File: github_oauth.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (97 lines) | stat: -rw-r--r-- 2,495 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# frozen_string_literal: true

module Import
  module GithubOauth
    extend ActiveSupport::Concern

    OAuthConfigMissingError = Class.new(StandardError)

    included do
      rescue_from OAuthConfigMissingError, with: :missing_oauth_config
    end

    private

    def provider_auth
      return if session[access_token_key].present?

      go_to_provider_for_permissions unless ci_cd_only?
    end

    def ci_cd_only?
      %w[1 true].include?(params[:ci_cd_only])
    end

    def go_to_provider_for_permissions
      redirect_to authorize_url
    end

    def oauth_client
      raise OAuthConfigMissingError unless oauth_config

      oauth_client_from_config
    end

    def oauth_client_from_config
      @oauth_client_from_config ||= ::OAuth2::Client.new(
        oauth_config.app_id,
        oauth_config.app_secret,
        oauth_options.merge(ssl: { verify: oauth_config['verify_ssl'] })
      )
    end

    def oauth_config
      @oauth_config ||= Gitlab::Auth::OAuth::Provider.config_for('github')
    end

    def oauth_options
      return unless oauth_config

      oauth_config.dig('args', 'client_options').to_h.deep_symbolize_keys
    end

    def authorize_url
      state = SecureRandom.base64(64)
      session[auth_state_key] = state
      session[:auth_on_failure_path] = "#{new_project_path}#import_project"
      oauth_client.auth_code.authorize_url(
        redirect_uri: callback_import_url,
        # read:org only required for collaborator import, which is optional,
        # but at the time of this OAuth request we do not know which optional
        # configuration the user will select because the options are only shown
        # after authenticating
        scope: 'repo, read:org',
        state: state
      )
    end

    def get_token(code)
      oauth_client.auth_code.get_token(code).token
    end

    def missing_oauth_config
      session[access_token_key] = nil

      message = _('Missing OAuth configuration for GitHub.')

      respond_to do |format|
        format.json do
          render json: { errors: message }, status: :unauthorized
        end

        format.any do
          redirect_to new_import_url,
            alert: message
        end
      end
    end

    def callback_import_url
      public_send("users_import_#{provider_name}_callback_url", extra_import_params.merge({ namespace_id: params[:namespace_id] })) # rubocop:disable GitlabSecurity/PublicSend
    end

    def extra_import_params
      {}
    end
  end
end