aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorGeorge Claghorn <george@basecamp.com>2018-10-17 00:12:03 -0400
committerGeorge Claghorn <george@basecamp.com>2018-10-17 00:12:03 -0400
commit3984460424b678d844009319598e2b41c350ca3c (patch)
tree96a5bd26ae3191dd6a2837d4c7e4bb1e8c55f9bc /app
parent6b7eac5c51cbef4acd1ab7f48884e7b614f71678 (diff)
downloadrails-3984460424b678d844009319598e2b41c350ca3c.tar.gz
rails-3984460424b678d844009319598e2b41c350ca3c.tar.bz2
rails-3984460424b678d844009319598e2b41c350ca3c.zip
Add Mandrill support
Diffstat (limited to 'app')
-rw-r--r--app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb59
1 files changed, 59 insertions, 0 deletions
diff --git a/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb b/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb
new file mode 100644
index 0000000000..825ec6eabd
--- /dev/null
+++ b/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb
@@ -0,0 +1,59 @@
+class ActionMailbox::Ingresses::Mandrill::InboundEmailsController < ActionMailbox::BaseController
+ before_action :ensure_authenticated
+
+ def create
+ raw_emails.each { |raw_email| ActionMailbox::InboundEmail.create_and_extract_message_id! raw_email }
+ head :ok
+ rescue JSON::ParserError => error
+ log.error error.message
+ head :unprocessable_entity
+ end
+
+ private
+ def raw_emails
+ events.lazy.
+ select { |event| event["event"] == "inbound" }.
+ collect { |event| event.dig("msg", "raw_msg") }.
+ collect { |message| StringIO.new message }
+ end
+
+ def events
+ JSON.parse params.require(:mandrill_events)
+ end
+
+
+ def ensure_authenticated
+ head :unauthorized unless authenticated?
+ end
+
+ def authenticated?
+ Authenticator.new(request).authenticated?
+ end
+
+ class Authenticator
+ cattr_accessor :key
+
+ attr_reader :request
+
+ def initialize(request)
+ @request = request
+ end
+
+ def authenticated?
+ ActiveSupport::SecurityUtils.secure_compare given_signature, expected_signature
+ end
+
+ private
+ def given_signature
+ request.headers["X-Mandrill-Signature"]
+ end
+
+ def expected_signature
+ Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, key, message)).strip
+ end
+
+ def message
+ [ request.original_url, request.POST.sort ].flatten.join
+ end
+ end
+end