From 6b7eac5c51cbef4acd1ab7f48884e7b614f71678 Mon Sep 17 00:00:00 2001 From: George Claghorn Date: Sat, 6 Oct 2018 22:02:08 -0400 Subject: Accept inbound emails from a variety of ingresses --- .../ingresses/mailgun/inbound_emails_controller.rb | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb (limited to 'app/controllers/action_mailbox/ingresses/mailgun') diff --git a/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb b/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb new file mode 100644 index 0000000000..4d194a3e00 --- /dev/null +++ b/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb @@ -0,0 +1,61 @@ +class ActionMailbox::Ingresses::Mailgun::InboundEmailsController < ActionMailbox::BaseController + before_action :ensure_authenticated + + def create + ActionMailbox::InboundEmail.create_and_extract_message_id! raw_email + head :ok + end + + private + def raw_email + StringIO.new params.require("body-mime") + end + + + def ensure_authenticated + head :unauthorized unless authenticated? + end + + def authenticated? + Authenticator.new(authentication_params).authenticated? + rescue ArgumentError + false + end + + def authentication_params + params.permit(:timestamp, :token, :signature).to_h.symbolize_keys + end + + + class Authenticator + cattr_accessor :key + + attr_reader :timestamp, :token, :signature + + def initialize(timestamp:, token:, signature:) + @timestamp, @token, @signature = timestamp, token, signature + end + + def authenticated? + signed? && recent? + end + + private + def signed? + ActiveSupport::SecurityUtils.secure_compare signature, expected_signature + end + + # Allow for 10 minutes of drift between Mailgun time and local server time. + def recent? + time >= 10.minutes.ago + end + + def expected_signature + OpenSSL::HMAC.hexdigest OpenSSL::Digest::SHA256.new, key, "#{timestamp}#{token}" + end + + def time + Time.at Integer(timestamp) + end + end +end -- cgit v1.2.3