summaryrefslogtreecommitdiff
path: root/app/models/project_services/emails_on_push_service.rb
blob: cdb69684d16b9a6e1eb26b4caad480704c1b8ed3 (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
# frozen_string_literal: true

class EmailsOnPushService < Service
  include NotificationBranchSelection

  RECIPIENTS_LIMIT = 750

  boolean_accessor :send_from_committer_email
  boolean_accessor :disable_diffs
  prop_accessor :recipients, :branches_to_be_notified
  validates :recipients, presence: true, if: :validate_recipients?
  validate :number_of_recipients_within_limit, if: :validate_recipients?

  def self.valid_recipients(recipients)
    recipients.split.select do |recipient|
      recipient.include?('@')
    end.uniq(&:downcase)
  end

  def title
    s_('EmailsOnPushService|Emails on push')
  end

  def description
    s_('EmailsOnPushService|Email the commits and diff of each push to a list of recipients.')
  end

  def self.to_param
    'emails_on_push'
  end

  def self.supported_events
    %w(push tag_push)
  end

  def initialize_properties
    super

    self.branches_to_be_notified = 'all' if branches_to_be_notified.nil?
  end

  def execute(push_data)
    return unless supported_events.include?(push_data[:object_kind])
    return if project.emails_disabled?
    return unless notify_for_ref?(push_data)

    EmailsOnPushWorker.perform_async(
      project_id,
      recipients,
      push_data,
      send_from_committer_email: send_from_committer_email?,
      disable_diffs:             disable_diffs?
    )
  end

  def notify_for_ref?(push_data)
    return true if push_data[:object_kind] == 'tag_push'
    return true if push_data.dig(:object_attributes, :tag)

    notify_for_branch?(push_data)
  end

  def send_from_committer_email?
    Gitlab::Utils.to_boolean(self.send_from_committer_email)
  end

  def disable_diffs?
    Gitlab::Utils.to_boolean(self.disable_diffs)
  end

  def fields
    domains = Notify.allowed_email_domains.map { |domain| "user@#{domain}" }.join(", ")
    [
      { type: 'checkbox', name: 'send_from_committer_email', title: s_("EmailsOnPushService|Send from committer"),
        help: s_("EmailsOnPushService|Send notifications from the committer's email address if the domain matches the domain used by your GitLab instance (such as %{domains}).") % { domains: domains } },
      { type: 'checkbox', name: 'disable_diffs', title: s_("EmailsOnPushService|Disable code diffs"),
        help: s_("EmailsOnPushService|Don't include possibly sensitive code diffs in notification body.") },
      { type: 'select', name: 'branches_to_be_notified', choices: branch_choices },
      {
        type: 'textarea',
        name: 'recipients',
        placeholder: s_('EmailsOnPushService|tanuki@example.com gitlab@example.com'),
        help: s_('EmailsOnPushService|Emails separated by whitespace.')
      }
    ]
  end

  private

  def number_of_recipients_within_limit
    return if recipients.blank?

    if self.class.valid_recipients(recipients).size > RECIPIENTS_LIMIT
      errors.add(:recipients, s_("EmailsOnPushService|can't exceed %{recipients_limit}") % { recipients_limit: RECIPIENTS_LIMIT })
    end
  end
end