summaryrefslogtreecommitdiff
path: root/app/controllers/oauth/authorizations_controller.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/oauth/authorizations_controller.rb')
-rw-r--r--app/controllers/oauth/authorizations_controller.rb51
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.