Commit 8d441c81 authored by Alain Takoudjou's avatar Alain Takoudjou

NXD: access token should be valid for project and namespace

when doing git clone https://gitlab-ci-token:RUNNER_TOKEN@GITLAB_URL/NAMESPACE/PROJECT.git
user is always gitlab-ci-token and cannot be used to identify the project, runner token
is not unique per project.

If two projects in the namespace has the same token and the wrong project is returned by
`build_access_token_check` method, gitlab will simply return 404.

`build_access_token_check` now take namespace_id as parameter so that we can ensure that
we authenticate on the right project.
parent 611cf13b
......@@ -23,7 +23,9 @@ class JwtController < ApplicationController
@authentication_result = Gitlab::Auth::Result.new(nil, nil, :none, Gitlab::Auth.read_authentication_abilities)
authenticate_with_http_basic do |login, password|
@authentication_result = Gitlab::Auth.find_for_git_client(login, password, project: nil, ip: request.ip)
@authentication_result = Gitlab::Auth.find_for_git_client(
login, password, project: nil, ip: request.ip,
namespace_id: params[:namespace_id])
render_unauthorized unless @authentication_result.success? &&
(@authentication_result.actor.nil? || @authentication_result.actor.is_a?(User))
......
......@@ -125,7 +125,8 @@ class Projects::GitHttpClientController < Projects::ApplicationController
def handle_basic_authentication(login, password)
@authentication_result = Gitlab::Auth.find_for_git_client(
login, password, project: project, ip: request.ip)
login, password, project: project, ip: request.ip,
namespace_id: params[:namespace_id])
return false unless @authentication_result.success?
......
......@@ -7,7 +7,7 @@ module Gitlab
OPTIONAL_SCOPES = SCOPES - DEFAULT_SCOPES
class << self
def find_for_git_client(login, password, project:, ip:)
def find_for_git_client(login, password, project:, ip:, namespace_id:)
raise "Must provide an IP for rate limiting" if ip.nil?
# `user_with_password_for_git` should be the last check
......@@ -15,7 +15,7 @@ module Gitlab
# is enabled.
result =
service_request_check(login, password, project) ||
build_access_token_check(login, password) ||
build_access_token_check(login, password, namespace_id: namespace_id) ||
lfs_token_check(login, password) ||
oauth_access_token_check(login, password) ||
personal_access_token_check(login, password) ||
......@@ -151,14 +151,18 @@ module Gitlab
end
end
def build_access_token_check(login, password)
def build_access_token_check(login, password, namespace_id:)
return unless login == 'gitlab-ci-token'
return unless password
# XXX-nxd: we also accept runners_token if enabled on projects
project = Project.with_builds_enabled.find_by(runners_token: password)
if project
Gitlab::Auth::Result.new(nil, project, :ci, build_authentication_abilities)
namespace = Namespace.find_by_path_or_name(namespace_id)
if namespace
# find for project in the given namespace
project = Project.with_builds_enabled.find_by(runners_token: password, namespace_id: namespace.id)
if project
Gitlab::Auth::Result.new(nil, project, :ci, build_authentication_abilities)
end
else
build = ::Ci::Build.running.find_by_token(password)
return unless build
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment