66 lines
1.9 KiB
Ruby
66 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
|