diff options
Diffstat (limited to 'app/controllers/oauth')
-rw-r--r-- | app/controllers/oauth/authorizations_controller.rb | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb index ddf70c1892a..d1c409d071e 100644 --- a/app/controllers/oauth/authorizations_controller.rb +++ b/app/controllers/oauth/authorizations_controller.rb @@ -3,6 +3,7 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController include Gitlab::Experimentation::ControllerConcern include InitializesCurrentUserMode + include Gitlab::Utils::StrongMemoize before_action :verify_confirmed_email!, :verify_confidential_application! @@ -27,6 +28,56 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController private + def pre_auth_params + # Cannot be achieved with a before_action hook, due to the execution order. + downgrade_scopes! if action_name == 'new' + + super + end + + # limit scopes when signing in with GitLab + def downgrade_scopes! + return unless Feature.enabled?(:omniauth_login_minimal_scopes, current_user, + default_enabled: :yaml) + + auth_type = params.delete('gl_auth_type') + return unless auth_type == 'login' + + ensure_read_user_scope! + + params['scope'] = Gitlab::Auth::READ_USER_SCOPE.to_s if application_has_read_user_scope? + end + + # Configure the application to support read_user scope, if it already + # supports scopes with greater levels of privileges. + def ensure_read_user_scope! + return if application_has_read_user_scope? + return unless application_has_api_scope? + + add_read_user_scope! + end + + def add_read_user_scope! + return unless doorkeeper_application + + scopes = doorkeeper_application.scopes + scopes.add(Gitlab::Auth::READ_USER_SCOPE) + doorkeeper_application.scopes = scopes + doorkeeper_application.save! + end + + def doorkeeper_application + strong_memoize(:doorkeeper_application) { ::Doorkeeper::OAuth::Client.find(params['client_id'])&.application } + end + + def application_has_read_user_scope? + doorkeeper_application&.includes_scope?(Gitlab::Auth::READ_USER_SCOPE) + end + + def application_has_api_scope? + doorkeeper_application&.includes_scope?(*::Gitlab::Auth::API_SCOPES) + end + # Confidential apps require the client_secret to be sent with the request. # Doorkeeper allows implicit grant flow requests (response_type=token) to # work without client_secret regardless of the confidential setting. |