Commit 46084b38 authored by Dmitry Gruzd's avatar Dmitry Gruzd

Merge branch '333562-setup-gitlab-mailgun-endpoint-for-syncing-bounced-invite-emails' into 'master'

Add mailgun application settings for receiving email send failures

See merge request gitlab-org/gitlab!64249
parents f9782c3d c454e131
......@@ -343,6 +343,8 @@ module ApplicationSettingsHelper
:commit_email_hostname,
:protected_ci_variables,
:local_markdown_version,
:mailgun_signing_key,
:mailgun_events_enabled,
:snowplow_collector_hostname,
:snowplow_cookie_domain,
:snowplow_enabled,
......
......@@ -172,6 +172,11 @@ class ApplicationSetting < ApplicationRecord
addressable_url: { enforce_sanitization: true },
if: :gitpod_enabled
validates :mailgun_signing_key,
presence: true,
length: { maximum: 255 },
if: :mailgun_events_enabled
validates :snowplow_collector_hostname,
presence: true,
hostname: true,
......@@ -552,6 +557,7 @@ class ApplicationSetting < ApplicationRecord
attr_encrypted :secret_detection_token_revocation_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :cloud_license_auth_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :external_pipeline_validation_service_token, encryption_options_base_32_aes_256_gcm
attr_encrypted :mailgun_signing_key, encryption_options_base_32_aes_256_gcm.merge(encode: false)
validates :disable_feed_token,
inclusion: { in: [true, false], message: _('must be a boolean value') }
......
......@@ -104,6 +104,8 @@ module ApplicationSettingImplementation
issues_create_limit: 300,
local_markdown_version: 0,
login_recaptcha_protection_enabled: false,
mailgun_signing_key: nil,
mailgun_events_enabled: false,
max_artifacts_size: Settings.artifacts['max_size'],
max_attachment_size: Settings.gitlab['max_attachment_size'],
max_import_size: 0,
......
- return unless Feature.enabled?(:mailgun_events_receiver)
- expanded = integration_expanded?('mailgun_')
%section.settings.as-mailgun.no-animate#js-mailgun-settings{ class: ('expanded' if expanded) }
.settings-header
%h4
= _('Mailgun')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Configure the %{link} integration.').html_safe % { link: link_to(_('Mailgun events'), 'https://documentation.mailgun.com/en/latest/user_manual.html#webhooks', target: '_blank') }
.settings-content
= form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-mailgun-settings'), html: { class: 'fieldset-form', id: 'mailgun-settings' } do |f|
= form_errors(@application_setting) if expanded
%fieldset
.form-group
.form-check
= f.check_box :mailgun_events_enabled, class: 'form-check-input'
= f.label :mailgun_events_enabled, _('Enable Mailgun event receiver'), class: 'form-check-label'
.form-group
= f.label :mailgun_signing_key, _('Mailgun HTTP webhook signing key'), class: 'label-light'
= f.text_field :mailgun_signing_key, class: 'form-control gl-form-input'
= f.submit _('Save changes'), class: 'gl-button btn btn-confirm'
......@@ -107,6 +107,7 @@
= render_if_exists 'admin/application_settings/maintenance_mode_settings_form'
= render 'admin/application_settings/gitpod'
= render 'admin/application_settings/kroki'
= render 'admin/application_settings/mailgun'
= render 'admin/application_settings/plantuml'
= render 'admin/application_settings/sourcegraph'
= render_if_exists 'admin/application_settings/slack'
......
......@@ -151,6 +151,7 @@ module Gitlab
elasticsearch_password
search
jwt
mailgun_signing_key
otp_attempt
sentry_dsn
trace
......
---
name: mailgun_events_receiver
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64249
rollout_issue_url:
milestone: '14.1'
type: development
group: group::expansion
default_enabled: false
# frozen_string_literal: true
class AddMailgunSettingsToApplicationSetting < ActiveRecord::Migration[6.1]
def change
add_column :application_settings, :encrypted_mailgun_signing_key, :binary
add_column :application_settings, :encrypted_mailgun_signing_key_iv, :binary
add_column :application_settings, :mailgun_events_enabled, :boolean, default: false, null: false
end
end
8d73f4b4b716176afe5a9b0ee3a4ef28bbbc2fe944a18fb66afa8cf8f763e8ac
\ No newline at end of file
......@@ -9522,6 +9522,9 @@ CREATE TABLE application_settings (
diff_max_lines integer DEFAULT 50000 NOT NULL,
diff_max_files integer DEFAULT 1000 NOT NULL,
valid_runner_registrars character varying[] DEFAULT '{project,group}'::character varying[],
encrypted_mailgun_signing_key bytea,
encrypted_mailgun_signing_key_iv bytea,
mailgun_events_enabled boolean DEFAULT false NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
......@@ -328,6 +328,8 @@ listed in the descriptions of the relevant settings.
| `issues_create_limit` | integer | no | Max number of issue creation requests per minute per user. Disabled by default.|
| `keep_latest_artifact` | boolean | no | Prevent the deletion of the artifacts from the most recent successful jobs, regardless of the expiry time. Enabled by default. |
| `local_markdown_version` | integer | no | Increase this value when any cached Markdown should be invalidated. |
| `mailgun_signing_key` | string | no | The Mailgun HTTP webhook signing key for receiving events from webhook |
| `mailgun_events_enabled` | boolean | no | Enable Mailgun event receiver. |
| `maintenance_mode_message` | string | no | **(PREMIUM)** Message displayed when instance is in maintenance mode. |
| `maintenance_mode` | boolean | no | **(PREMIUM)** When instance is in maintenance mode, non-administrative users can sign in with read-only access and make read-only API requests. |
| `max_artifacts_size` | integer | no | Maximum artifacts size in MB. |
......
......@@ -160,6 +160,10 @@ module API
optional :usage_ping_enabled, type: Boolean, desc: 'Every week GitLab will report license usage back to GitLab, Inc.'
optional :local_markdown_version, type: Integer, desc: 'Local markdown version, increase this value when any cached markdown should be invalidated'
optional :allow_local_requests_from_hooks_and_services, type: Boolean, desc: 'Deprecated: Use :allow_local_requests_from_web_hooks_and_services instead. Allow requests to the local network from hooks and services.' # support legacy names, can be removed in v5
optional :mailgun_events_enabled, type: Grape::API::Boolean, desc: 'Enable Mailgun event receiver'
given mailgun_events_enabled: ->(val) { val } do
requires :mailgun_signing_key, type: String, desc: 'The Mailgun HTTP webhook signing key for receiving events from webhook'
end
optional :snowplow_enabled, type: Grape::API::Boolean, desc: 'Enable Snowplow tracking'
given snowplow_enabled: ->(val) { val } do
requires :snowplow_collector_hostname, type: String, desc: 'The Snowplow collector hostname'
......
......@@ -8208,6 +8208,9 @@ msgstr ""
msgid "Configure storage path settings."
msgstr ""
msgid "Configure the %{link} integration."
msgstr ""
msgid "Configure the way a user creates a new account."
msgstr ""
......@@ -11938,6 +11941,9 @@ msgstr ""
msgid "Enable Kroki"
msgstr ""
msgid "Enable Mailgun event receiver"
msgstr ""
msgid "Enable PlantUML"
msgstr ""
......@@ -19718,6 +19724,15 @@ msgstr ""
msgid "Made this issue confidential."
msgstr ""
msgid "Mailgun"
msgstr ""
msgid "Mailgun HTTP webhook signing key"
msgstr ""
msgid "Mailgun events"
msgstr ""
msgid "Maintenance mode"
msgstr ""
......
......@@ -269,7 +269,10 @@ RSpec.describe 'Admin updates settings' do
end
context 'Integrations page' do
let(:mailgun_events_receiver_enabled) { true }
before do
stub_feature_flags(mailgun_events_receiver: mailgun_events_receiver_enabled)
visit general_admin_application_settings_path
end
......@@ -282,6 +285,28 @@ RSpec.describe 'Admin updates settings' do
expect(page).to have_content "Application settings saved successfully"
expect(current_settings.hide_third_party_offers).to be true
end
context 'when mailgun_events_receiver feature flag is enabled' do
it 'enabling Mailgun events', :aggregate_failures do
page.within('.as-mailgun') do
check 'Enable Mailgun event receiver'
fill_in 'Mailgun HTTP webhook signing key', with: 'MAILGUN_SIGNING_KEY'
click_button 'Save changes'
end
expect(page).to have_content 'Application settings saved successfully'
expect(current_settings.mailgun_events_enabled).to be true
expect(current_settings.mailgun_signing_key).to eq 'MAILGUN_SIGNING_KEY'
end
end
context 'when mailgun_events_receiver feature flag is disabled' do
let(:mailgun_events_receiver_enabled) { false }
it 'does not have mailgun' do
expect(page).not_to have_selector('.as-mailgun')
end
end
end
context 'when Service Templates are enabled' do
......
......@@ -258,6 +258,19 @@ RSpec.describe ApplicationSetting do
it { is_expected.to allow_value(nil).for(:snowplow_collector_hostname) }
end
context 'when mailgun_events_enabled is enabled' do
before do
setting.mailgun_events_enabled = true
end
it { is_expected.to validate_presence_of(:mailgun_signing_key) }
it { is_expected.to validate_length_of(:mailgun_signing_key).is_at_most(255) }
end
context 'when mailgun_events_enabled is not enabled' do
it { is_expected.not_to validate_presence_of(:mailgun_signing_key) }
end
context "when user accepted let's encrypt terms of service" do
before do
expect do
......
......@@ -127,6 +127,8 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
spam_check_endpoint_enabled: true,
spam_check_endpoint_url: 'grpc://example.com/spam_check',
spam_check_api_key: 'SPAM_CHECK_API_KEY',
mailgun_events_enabled: true,
mailgun_signing_key: 'MAILGUN_SIGNING_KEY',
disabled_oauth_sign_in_sources: 'unknown',
import_sources: 'github,bitbucket',
wiki_page_max_content_bytes: 12345,
......@@ -175,6 +177,8 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
expect(json_response['spam_check_endpoint_enabled']).to be_truthy
expect(json_response['spam_check_endpoint_url']).to eq('grpc://example.com/spam_check')
expect(json_response['spam_check_api_key']).to eq('SPAM_CHECK_API_KEY')
expect(json_response['mailgun_events_enabled']).to be(true)
expect(json_response['mailgun_signing_key']).to eq('MAILGUN_SIGNING_KEY')
expect(json_response['disabled_oauth_sign_in_sources']).to eq([])
expect(json_response['import_sources']).to match_array(%w(github bitbucket))
expect(json_response['wiki_page_max_content_bytes']).to eq(12345)
......@@ -493,6 +497,15 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
end
end
context "missing mailgun_signing_key value when mailgun_events_enabled is true" do
it "returns a blank parameter error message" do
put api("/application/settings", admin), params: { mailgun_events_enabled: true }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('mailgun_signing_key is missing')
end
end
context "personal access token prefix settings" do
context "handles validation errors" do
it "fails to update the settings with too long prefix" do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment