Welcome to mirror list, hosted at ThFree Co, Russian Federation.

slack_application_install_service.rb « projects « services « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 812b8b0a0823ff39e70d55d31060cebb96a6e702 (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
# frozen_string_literal: true

module Projects
  class SlackApplicationInstallService < BaseService
    include Gitlab::Routing

    # Endpoint to initiate the OAuth flow, redirects to Slack's authorization screen
    # https://api.slack.com/authentication/oauth-v2#asking
    SLACK_AUTHORIZE_URL = 'https://slack.com/oauth/v2/authorize'

    # Endpoint to exchange the temporary authorization code for an access token
    # https://api.slack.com/authentication/oauth-v2#exchanging
    SLACK_EXCHANGE_TOKEN_URL = 'https://slack.com/api/oauth.v2.access'

    def execute
      slack_data = exchange_slack_token

      return error("Slack: #{slack_data['error']}") unless slack_data['ok']

      integration = project.gitlab_slack_application_integration \
        || project.create_gitlab_slack_application_integration!

      installation = integration.slack_integration || integration.build_slack_integration

      installation.update!(
        bot_user_id: slack_data['bot_user_id'],
        bot_access_token: slack_data['access_token'],
        team_id: slack_data.dig('team', 'id'),
        team_name: slack_data.dig('team', 'name'),
        alias: project.full_path,
        user_id: slack_data.dig('authed_user', 'id'),
        authorized_scope_names: slack_data['scope']
      )

      update_legacy_installations!(installation)

      success
    end

    private

    def exchange_slack_token
      query = {
        client_id: Gitlab::CurrentSettings.slack_app_id,
        client_secret: Gitlab::CurrentSettings.slack_app_secret,
        code: params[:code],
        # NOTE: Needs to match the `redirect_uri` passed to the authorization endpoint,
        # otherwise we get a `bad_redirect_uri` error.
        redirect_uri: slack_auth_project_settings_slack_url(project)
      }

      Gitlab::HTTP.get(SLACK_EXCHANGE_TOKEN_URL, query: query).to_hash
    end

    # Update any legacy SlackIntegration records for the Slack Workspace. Legacy SlackIntegration records
    # are any created before our Slack App was upgraded to use Granular Bot Permissions and issue a
    # bot_access_token. Any SlackIntegration records for the Slack Workspace will already have the same
    # bot_access_token.
    def update_legacy_installations!(installation)
      updatable_attributes = installation.attributes.slice(
        'user_id',
        'bot_user_id',
        'encrypted_bot_access_token',
        'encrypted_bot_access_token_iv',
        'updated_at'
      )

      SlackIntegration.by_team(installation.team_id).id_not_in(installation.id).each_batch do |batch|
        batch_ids = batch.pluck(:id) # rubocop: disable CodeReuse/ActiveRecord
        batch.update_all(updatable_attributes)

        ::Integrations::SlackWorkspace::IntegrationApiScope.update_scopes(batch_ids, installation.slack_api_scopes)
      end
    end
  end
end