65 lines
1.9 KiB
Ruby
65 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Members
|
|
module Mailgun
|
|
class PermanentFailuresController < ApplicationController
|
|
respond_to :json
|
|
|
|
skip_before_action :authenticate_user!
|
|
skip_before_action :verify_authenticity_token
|
|
|
|
before_action :ensure_feature_enabled!
|
|
before_action :authenticate_signature!
|
|
before_action :validate_invite_email!
|
|
|
|
feature_category :authentication_and_authorization
|
|
|
|
def create
|
|
webhook_processor.execute
|
|
|
|
head :ok
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_feature_enabled!
|
|
render_406 unless Gitlab::CurrentSettings.mailgun_events_enabled?
|
|
end
|
|
|
|
def authenticate_signature!
|
|
access_denied! unless valid_signature?
|
|
end
|
|
|
|
def valid_signature?
|
|
return false if Gitlab::CurrentSettings.mailgun_signing_key.blank?
|
|
|
|
# per this guide: https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
|
|
digest = OpenSSL::Digest.new('SHA256')
|
|
data = [params.dig(:signature, :timestamp), params.dig(:signature, :token)].join
|
|
|
|
hmac_digest = OpenSSL::HMAC.hexdigest(digest, Gitlab::CurrentSettings.mailgun_signing_key, data)
|
|
|
|
ActiveSupport::SecurityUtils.secure_compare(params.dig(:signature, :signature), hmac_digest)
|
|
end
|
|
|
|
def validate_invite_email!
|
|
# permanent_failures webhook does not provide a way to filter failures, so we'll get them all on this endpoint
|
|
# and we only care about our invite_emails
|
|
render_406 unless payload[:tags]&.include?(::Members::Mailgun::INVITE_EMAIL_TAG)
|
|
end
|
|
|
|
def webhook_processor
|
|
::Members::Mailgun::ProcessWebhookService.new(payload)
|
|
end
|
|
|
|
def payload
|
|
@payload ||= params.permit!['event-data']
|
|
end
|
|
|
|
def render_406
|
|
# failure to stop retries per https://documentation.mailgun.com/en/latest/user_manual.html#webhooks
|
|
head :not_acceptable
|
|
end
|
|
end
|
|
end
|
|
end
|