summaryrefslogtreecommitdiff
path: root/app/controllers/concerns/import/github_oauth.rb
blob: d53022aabf28a4b0c08e0b34bae78cdc6180e3c6 (plain)
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
98
99
100
# 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').deep_symbolize_keys
    end

    def authorize_url
      state = SecureRandom.base64(64)
      session[auth_state_key] = state
      if Feature.enabled?(:remove_legacy_github_client)
        oauth_client.auth_code.authorize_url(
          redirect_uri: callback_import_url,
          scope: 'repo, user, user:email',
          state: state
        )
      else
        client.authorize_url(callback_import_url, state)
      end
    end

    def get_token(code)
      if Feature.enabled?(:remove_legacy_github_client)
        oauth_client.auth_code.get_token(code).token
      else
        client.get_token(code)
      end
    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