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

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

class SlackIntegration < ApplicationRecord
  include EachBatch

  ALL_FEATURES = %i[commands notifications].freeze

  SCOPE_COMMANDS = 'commands'
  SCOPE_CHAT_WRITE = 'chat:write'
  SCOPE_CHAT_WRITE_PUBLIC = 'chat:write.public'

  # These scopes are requested when installing the app, additional scopes
  # will need reauthorization.
  # https://api.slack.com/authentication/oauth-v2#asking
  SCOPES = [SCOPE_COMMANDS, SCOPE_CHAT_WRITE, SCOPE_CHAT_WRITE_PUBLIC].freeze

  belongs_to :integration

  attr_encrypted :bot_access_token,
    mode: :per_attribute_iv,
    key: Settings.attr_encrypted_db_key_base_32,
    algorithm: 'aes-256-gcm',
    encode: false,
    encode_iv: false

  has_many :slack_integrations_scopes,
    class_name: '::Integrations::SlackWorkspace::IntegrationApiScope'

  has_many :slack_api_scopes,
    class_name: '::Integrations::SlackWorkspace::ApiScope',
    through: :slack_integrations_scopes

  scope :with_bot, -> { where.not(bot_user_id: nil) }
  scope :by_team, ->(team_id) { where(team_id: team_id) }

  validates :team_id, presence: true
  validates :team_name, presence: true
  validates :alias, presence: true,
    uniqueness: { scope: :team_id, message: 'This alias has already been taken' },
    length: 2..4096
  validates :user_id, presence: true
  validates :integration, presence: true

  after_commit :update_active_status_of_integration, on: [:create, :destroy]

  def update_active_status_of_integration
    integration.update_active_status
  end

  def feature_available?(feature_name)
    case feature_name
    when :commands
      # The slash commands feature requires 'commands' scope.
      # All records will support this scope, as this was the original feature.
      true
    when :notifications
      scoped_to?(SCOPE_CHAT_WRITE, SCOPE_CHAT_WRITE_PUBLIC)
    else
      false
    end
  end

  def upgrade_needed?
    !all_features_supported?
  end

  def all_features_supported?
    ALL_FEATURES.all? { |feature| feature_available?(feature) } # rubocop: disable Gitlab/FeatureAvailableUsage
  end

  def authorized_scope_names=(names)
    names = Array.wrap(names).flat_map { |name| name.split(',') }.map(&:strip)

    scopes = ::Integrations::SlackWorkspace::ApiScope.find_or_initialize_by_names(names)
    self.slack_api_scopes = scopes
  end

  def authorized_scope_names
    slack_api_scopes.pluck(:name)
  end

  private

  def scoped_to?(*names)
    return false if names.empty?

    names.to_set <= all_scopes
  end

  def all_scopes
    @all_scopes = authorized_scope_names.to_set
  end
end