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

gitlab_slack_application.rb « integrations « models « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 66746117c00a3b994736335675e57008d008fa60 (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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# frozen_string_literal: true

module Integrations
  class GitlabSlackApplication < BaseSlackNotification
    attribute :alert_events, default: false
    attribute :commit_events, default: false
    attribute :confidential_issues_events, default: false
    attribute :confidential_note_events, default: false
    attribute :deployment_events, default: false
    attribute :issues_events, default: false
    attribute :job_events, default: false
    attribute :merge_requests_events, default: false
    attribute :note_events, default: false
    attribute :pipeline_events, default: false
    attribute :push_events, default: false
    attribute :tag_push_events, default: false
    attribute :vulnerability_events, default: false
    attribute :wiki_page_events, default: false

    has_one :slack_integration, foreign_key: :integration_id, inverse_of: :integration
    delegate :bot_access_token, :bot_user_id, to: :slack_integration, allow_nil: true

    include SlackMattermostFields

    def update_active_status
      update(active: !!slack_integration)
    end

    def self.title
      s_('Integrations|GitLab for Slack app')
    end

    def self.description
      s_('Integrations|Enable slash commands and notifications for a Slack workspace.')
    end

    def self.to_param
      'gitlab_slack_application'
    end

    override :show_active_box?
    def show_active_box?
      false
    end

    override :test
    def test(_data)
      failures = test_notification_channels

      { success: failures.blank?, result: failures }
    end

    # The form fields of this integration are editable only after the Slack App installation
    # flow has been completed, which causes the integration to become activated/enabled.
    override :editable?
    def editable?
      activated?
    end

    override :fields
    def fields
      return [] unless editable?

      super
    end

    override :sections
    def sections
      return [] unless editable?

      super.drop(1)
    end

    def self.webhook_help
      # no-op
    end

    override :configurable_events
    def configurable_events
      return [] unless editable?

      super
    end

    override :requires_webhook?
    def self.requires_webhook?
      false
    end

    def upgrade_needed?
      slack_integration.present? && slack_integration.upgrade_needed?
    end

    private

    override :notify
    def notify(message, opts)
      channels = Array(opts[:channel])
      return false if channels.empty?

      payload = {
        attachments: message.attachments,
        text: message.pretext,
        unfurl_links: false,
        unfurl_media: false
      }

      successes = channels.map do |channel|
        notify_slack_channel!(channel, payload)
      end

      successes.any?
    end

    def notify_slack_channel!(channel, payload)
      response = api_client.post(
        'chat.postMessage',
        payload.merge(channel: channel)
      )

      log_error('Slack API error when notifying', api_response: response.parsed_response) unless response['ok']

      response['ok']
    rescue *Gitlab::HTTP::HTTP_ERRORS => e
      Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e,
        {
          integration_id: id,
          slack_integration_id: slack_integration.id
        }
      )

      false
    end

    def api_client
      @slack_api ||= ::Slack::API.new(slack_integration)
    end

    def test_notification_channels
      return if unique_channels.empty?
      return s_('Integrations|GitLab for Slack app must be reinstalled to enable notifications') unless bot_access_token

      test_payload = {
        text: 'Test',
        user: bot_user_id
      }

      not_found_channels = unique_channels.first(10).select do |channel|
        test_payload[:channel] = channel

        response = ::Slack::API.new(slack_integration).post('chat.postEphemeral', test_payload)
        response['error'] == 'channel_not_found'
      end

      return if not_found_channels.empty?

      format(
        s_(
          'Integrations|Unable to post to %{channel_list}, ' \
          'please add the GitLab Slack app to any private Slack channels'
        ),
        channel_list: not_found_channels.to_sentence
      )
    end

    override :metrics_key_prefix
    def metrics_key_prefix
      'i_integrations_gitlab_for_slack_app'
    end
  end
end