diff options
author | George Claghorn <george.claghorn@gmail.com> | 2018-11-05 14:21:27 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-05 14:21:27 -0500 |
commit | 152a442b1902050265ddcef56f5506b3bfbb12e4 (patch) | |
tree | bd365d76299e978a6e974a64f5ff3d47f0614514 /app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb | |
parent | c474daefb18e9bab96f6f0bb0bb30dfc00058cb3 (diff) | |
parent | ac7fd0e56886eb134554789e014d2736b95d7042 (diff) | |
download | rails-152a442b1902050265ddcef56f5506b3bfbb12e4.tar.gz rails-152a442b1902050265ddcef56f5506b3bfbb12e4.tar.bz2 rails-152a442b1902050265ddcef56f5506b3bfbb12e4.zip |
Merge pull request #1 from basecamp/ingresses
Accept inbound emails from a variety of ingresses
Diffstat (limited to 'app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb')
-rw-r--r-- | app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb | 58 |
1 files changed, 58 insertions, 0 deletions
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..e878192603 --- /dev/null +++ b/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb @@ -0,0 +1,58 @@ +class ActionMailbox::Ingresses::Mailgun::InboundEmailsController < ActionMailbox::BaseController + before_action :authenticate + + def create + ActionMailbox::InboundEmail.create_and_extract_message_id! params.require("body-mime") + end + + private + def authenticate + head :unauthorized unless authenticated? + end + + def authenticated? + if key.present? + Authenticator.new( + key: key, + timestamp: params.require(:timestamp), + token: params.require(:token), + signature: params.require(:signature) + ).authenticated? + else + raise ArgumentError, <<~MESSAGE.squish + Missing required Mailgun API key. Set action_mailbox.mailgun_api_key in your application's + encrypted credentials or provide the MAILGUN_INGRESS_API_KEY environment variable. + MESSAGE + end + end + + def key + Rails.application.credentials.dig(:action_mailbox, :mailgun_api_key) || ENV["MAILGUN_INGRESS_API_KEY"] + end + + class Authenticator + attr_reader :key, :timestamp, :token, :signature + + def initialize(key:, timestamp:, token:, signature:) + @key, @timestamp, @token, @signature = key, Integer(timestamp), token, signature + end + + def authenticated? + signed? && recent? + end + + private + def signed? + ActiveSupport::SecurityUtils.secure_compare signature, expected_signature + end + + # Allow for 2 minutes of drift between Mailgun time and local server time. + def recent? + Time.at(timestamp) >= 2.minutes.ago + end + + def expected_signature + OpenSSL::HMAC.hexdigest OpenSSL::Digest::SHA256.new, key, "#{timestamp}#{token}" + end + end +end |