diff options
author | mortyccp <mortyccp@gmail.com> | 2018-12-01 20:41:24 +0300 |
---|---|---|
committer | mortyccp <mortyccp@gmail.com> | 2019-01-03 15:28:02 +0300 |
commit | d1fea99deb2b46467c456db17570710d60dd477b (patch) | |
tree | f4bc98f1f10c31186d7e7980b6d9afc3480cfdc1 /lib | |
parent | 32fbc12cc532f15392a4c4fa08b6229b06fe5bf0 (diff) |
Allow basic authentication on go get middleware
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/auth.rb | 24 | ||||
-rw-r--r-- | lib/gitlab/middleware/go.rb | 27 |
2 files changed, 34 insertions, 17 deletions
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 7aa02009aa0..a60f8cea27c 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -169,18 +169,6 @@ module Gitlab AccessTokenValidationService.new(token).include_any_scope?(scopes) end - def abilities_for_scopes(scopes) - abilities_by_scope = { - api: full_authentication_abilities, - read_registry: [:read_container_image], - read_repository: [:download_code] - } - - scopes.flat_map do |scope| - abilities_by_scope.fetch(scope.to_sym, []) - end.uniq - end - # rubocop: disable CodeReuse/ActiveRecord def deploy_token_check(login, password) return unless password.present? @@ -246,6 +234,18 @@ module Gitlab public + def abilities_for_scopes(scopes) + abilities_by_scope = { + api: full_authentication_abilities, + read_registry: [:read_container_image], + read_repository: [:download_code] + } + + scopes.flat_map do |scope| + abilities_by_scope.fetch(scope.to_sym, []) + end.uniq + end + def build_authentication_abilities [ :read_project, diff --git a/lib/gitlab/middleware/go.rb b/lib/gitlab/middleware/go.rb index d1a87c3b3bb..692e3ab187e 100644 --- a/lib/gitlab/middleware/go.rb +++ b/lib/gitlab/middleware/go.rb @@ -6,6 +6,7 @@ module Gitlab module Middleware class Go include ActionView::Helpers::TagHelper + include ActionController::HttpAuthentication::Basic PROJECT_PATH_REGEX = %r{\A(#{Gitlab::PathRegex.full_namespace_route_regex}/#{Gitlab::PathRegex.project_route_regex})/}.freeze @@ -14,7 +15,7 @@ module Gitlab end def call(env) - request = Rack::Request.new(env) + request = ActionDispatch::Request.new(env) render_go_doc(request) || @app.call(env) end @@ -110,22 +111,38 @@ module Gitlab def project_for_paths(paths, request) project = Project.where_full_path_in(paths).first - return unless Ability.allowed?(current_user(request), :read_project, project) + return unless Ability.allowed?(current_user(request, project), :read_project, project) project end - def current_user(request) + def current_user(request, project) + current_user_from_access_token_and_warden?(request) || current_user_from_basic_authentication?(request, project) + end + + def current_user_from_access_token_and_warden?(request) authenticator = Gitlab::Auth::RequestAuthenticator.new(request) user = authenticator.find_user_from_access_token || authenticator.find_user_from_warden - return unless user&.can?(:access_api) - # Right now, the `api` scope is the only one that should be able to determine private project existence. return unless authenticator.valid_access_token?(scopes: [:api]) user end + + def current_user_from_basic_authentication?(request, project) + return unless has_basic_credentials?(request) + login, password = user_name_and_password(request) + auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip) + return unless auth_result.success? + return unless auth_result.actor&.can?(:access_api) + if auth_result.type == :personal_access_token + apiScopeAbilities = Gitlab::Auth.abilities_for_scopes([:api]) + return unless auth_result.authentication_abilities.sort == apiScopeAbilities.sort + end + + auth_result.actor + end end end end |