2018-12-05 23:21:45 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-04-26 12:48:37 +05:30
|
|
|
class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
2020-01-01 13:55:28 +05:30
|
|
|
include InitializesCurrentUserMode
|
2022-04-04 11:22:00 +05:30
|
|
|
include Gitlab::Utils::StrongMemoize
|
2020-01-01 13:55:28 +05:30
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
before_action :verify_confirmed_email!, :verify_admin_allowed!
|
2020-05-30 21:06:31 +05:30
|
|
|
|
2015-09-11 14:41:01 +05:30
|
|
|
layout 'profile'
|
2015-04-26 12:48:37 +05:30
|
|
|
|
2018-12-13 13:39:08 +05:30
|
|
|
# Overridden from Doorkeeper::AuthorizationsController to
|
2017-08-17 22:00:37 +05:30
|
|
|
# include the call to session.delete
|
2015-04-26 12:48:37 +05:30
|
|
|
def new
|
|
|
|
if pre_auth.authorizable?
|
|
|
|
if skip_authorization? || matching_token?
|
|
|
|
auth = authorization.authorize
|
2021-06-02 17:11:27 +05:30
|
|
|
parsed_redirect_uri = URI.parse(auth.redirect_uri)
|
2016-06-02 11:05:42 +05:30
|
|
|
session.delete(:user_return_to)
|
2021-06-02 17:11:27 +05:30
|
|
|
render "doorkeeper/authorizations/redirect", locals: { redirect_uri: parsed_redirect_uri }, layout: false
|
2015-04-26 12:48:37 +05:30
|
|
|
else
|
2022-07-23 23:45:48 +05:30
|
|
|
redirect_uri = URI(authorization.authorize.redirect_uri)
|
|
|
|
allow_redirect_uri_form_action(redirect_uri.scheme)
|
|
|
|
|
2015-04-26 12:48:37 +05:30
|
|
|
render "doorkeeper/authorizations/new"
|
|
|
|
end
|
|
|
|
else
|
|
|
|
render "doorkeeper/authorizations/error"
|
|
|
|
end
|
|
|
|
end
|
2020-05-30 21:06:31 +05:30
|
|
|
|
2021-01-18 16:13:48 +05:30
|
|
|
private
|
|
|
|
|
2022-07-23 23:45:48 +05:30
|
|
|
# Chrome blocks redirections if the form-action CSP directive is present
|
|
|
|
# and the redirect location's scheme isn't allow-listed
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/form-action
|
|
|
|
# https://github.com/w3c/webappsec-csp/issues/8
|
|
|
|
def allow_redirect_uri_form_action(redirect_uri_scheme)
|
|
|
|
return unless content_security_policy?
|
|
|
|
|
|
|
|
form_action = request.content_security_policy.form_action
|
|
|
|
return unless form_action
|
|
|
|
|
|
|
|
form_action.push("#{redirect_uri_scheme}:")
|
|
|
|
request.content_security_policy.form_action(*form_action)
|
|
|
|
end
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
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!
|
|
|
|
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
|
|
|
|
|
2020-05-30 21:06:31 +05:30
|
|
|
def verify_confirmed_email!
|
|
|
|
return if current_user&.confirmed?
|
|
|
|
|
|
|
|
pre_auth.error = :unconfirmed_email
|
|
|
|
render "doorkeeper/authorizations/error"
|
|
|
|
end
|
2023-01-13 00:05:48 +05:30
|
|
|
|
|
|
|
def verify_admin_allowed!
|
|
|
|
render "doorkeeper/authorizations/forbidden" if disallow_connect?
|
|
|
|
end
|
|
|
|
|
|
|
|
def disallow_connect?
|
|
|
|
# we're disabling Cop/UserAdmin as OAuth tokens don't seem to respect admin mode
|
|
|
|
current_user&.admin? && Gitlab::CurrentSettings.disable_admin_oauth_scopes && dangerous_scopes? # rubocop:disable Cop/UserAdmin
|
|
|
|
end
|
|
|
|
|
|
|
|
def dangerous_scopes?
|
|
|
|
doorkeeper_application&.includes_scope?(*::Gitlab::Auth::API_SCOPE, *::Gitlab::Auth::READ_API_SCOPE,
|
|
|
|
*::Gitlab::Auth::ADMIN_SCOPES, *::Gitlab::Auth::REPOSITORY_SCOPES,
|
|
|
|
*::Gitlab::Auth::REGISTRY_SCOPES) && !doorkeeper_application&.trusted?
|
|
|
|
end
|
2015-04-26 12:48:37 +05:30
|
|
|
end
|