# frozen_string_literal: true module Mailgun class WebhooksController < ApplicationController respond_to :json skip_before_action :authenticate_user! skip_before_action :verify_authenticity_token before_action :ensure_feature_enabled! before_action :authenticate_signature! feature_category :team_planning WEBHOOK_PROCESSORS = [ Gitlab::Mailgun::WebhookProcessors::FailureLogger, Gitlab::Mailgun::WebhookProcessors::MemberInvites ].freeze def process_webhook WEBHOOK_PROCESSORS.each do |processor_class| processor_class.new(params['event-data']).execute end 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 render_406 # failure to stop retries per https://documentation.mailgun.com/en/latest/user_manual.html#webhooks head :not_acceptable end end end