Remove the Amazon SES ingress

It's unusable and not ready to ship in Rails 6.0. We'll rewrite it for 6.1.
This commit is contained in:
George Claghorn 2019-04-14 12:15:54 -04:00 committed by GitHub
parent 00b0c84a9b
commit f480cfabcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 30 additions and 149 deletions

View File

@ -1,6 +1,6 @@
# Action Mailbox
Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Exim, Postfix, and Qmail ingresses.
Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Exim, Postfix, and Qmail ingresses.
The inbound emails are turned into `InboundEmail` records using Active Record and feature lifecycle tracking, storage of the original email on cloud storage via Active Storage, and responsible data handling with on-by-default incineration.

View File

@ -7,10 +7,6 @@ module ActionMailbox
before_action :ensure_configured
def self.prepare
# Override in concrete controllers to run code on load.
end
private
def ensure_configured
unless ActionMailbox.ingress == ingress_name

View File

@ -1,54 +0,0 @@
# frozen_string_literal: true
module ActionMailbox
# Ingests inbound emails from Amazon's Simple Email Service (SES).
#
# Requires the full RFC 822 message in the +content+ parameter. Authenticates requests by validating their signatures.
#
# Returns:
#
# - <tt>204 No Content</tt> if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox
# - <tt>401 Unauthorized</tt> if the request's signature could not be validated
# - <tt>404 Not Found</tt> if Action Mailbox is not configured to accept inbound emails from SES
# - <tt>422 Unprocessable Entity</tt> if the request is missing the required +content+ parameter
# - <tt>500 Server Error</tt> if one of the Active Record database, the Active Storage service, or
# the Active Job backend is misconfigured or unavailable
#
# == Usage
#
# 1. Install the {aws-sdk-sns}[https://rubygems.org/gems/aws-sdk-sns] gem:
#
# # Gemfile
# gem "aws-sdk-sns", ">= 1.9.0", require: false
#
# 2. Tell Action Mailbox to accept emails from SES:
#
# # config/environments/production.rb
# config.action_mailbox.ingress = :amazon
#
# 3. {Configure SES}[https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-notifications.html]
# to deliver emails to your application via POST requests to +/rails/action_mailbox/amazon/inbound_emails+.
# If your application lived at <tt>https://example.com</tt>, you would specify the fully-qualified URL
# <tt>https://example.com/rails/action_mailbox/amazon/inbound_emails</tt>.
class Ingresses::Amazon::InboundEmailsController < BaseController
before_action :authenticate
cattr_accessor :verifier
def self.prepare
self.verifier ||= begin
require "aws-sdk-sns"
Aws::SNS::MessageVerifier.new
end
end
def create
ActionMailbox::InboundEmail.create_and_extract_message_id! params.require(:content)
end
private
def authenticate
head :unauthorized unless verifier.authentic?(request.body)
end
end
end

View File

@ -2,7 +2,6 @@
Rails.application.routes.draw do
scope "/rails/action_mailbox", module: "action_mailbox/ingresses" do
post "/amazon/inbound_emails" => "amazon/inbound_emails#create", as: :rails_amazon_inbound_emails
post "/mandrill/inbound_emails" => "mandrill/inbound_emails#create", as: :rails_mandrill_inbound_emails
post "/postmark/inbound_emails" => "postmark/inbound_emails#create", as: :rails_postmark_inbound_emails
post "/relay/inbound_emails" => "relay/inbound_emails#create", as: :rails_relay_inbound_emails

View File

@ -26,16 +26,7 @@ module ActionMailbox
ActionMailbox.incinerate = app.config.action_mailbox.incinerate.nil? ? true : app.config.action_mailbox.incinerate
ActionMailbox.incinerate_after = app.config.action_mailbox.incinerate_after || 30.days
ActionMailbox.queues = app.config.action_mailbox.queues || {}
end
end
initializer "action_mailbox.ingress" do |app|
config.to_prepare do
if ActionMailbox.ingress = app.config.action_mailbox.ingress.presence
if ingress_controller_class = "ActionMailbox::Ingresses::#{ActionMailbox.ingress.to_s.classify}::InboundEmailsController".safe_constantize
ingress_controller_class.prepare
end
end
ActionMailbox.ingress = app.config.action_mailbox.ingress
end
end
end

View File

@ -5,6 +5,6 @@ copy_file "#{__dir__}/mailbox/templates/application_mailbox.rb", "app/mailboxes/
environment <<~end_of_config, env: "production"
# Prepare the ingress controller used to receive mail
# config.action_mailbox.ingress = :amazon
# config.action_mailbox.ingress = :postfix
end_of_config

View File

@ -1,22 +0,0 @@
# frozen_string_literal: true
require "test_helper"
ActionMailbox::Ingresses::Amazon::InboundEmailsController.verifier =
Module.new { def self.authentic?(message); true; end }
class ActionMailbox::Ingresses::Amazon::InboundEmailsControllerTest < ActionDispatch::IntegrationTest
setup { ActionMailbox.ingress = :amazon }
test "receiving an inbound email from Amazon" do
assert_difference -> { ActionMailbox::InboundEmail.count }, +1 do
post rails_amazon_inbound_emails_url, params: { content: file_fixture("../files/welcome.eml").read }, as: :json
end
assert_response :no_content
inbound_email = ActionMailbox::InboundEmail.last
assert_equal file_fixture("../files/welcome.eml").read, inbound_email.raw_email.download
assert_equal "0CB459E0-0336-41DA-BC88-E6E28C697DDB@37signals.com", inbound_email.message_id
end
end

View File

@ -1,9 +1,4 @@
Rails.application.configure do
# Prepare the ingress controller used to receive mail
# config.action_mailbox.ingress = :amazon
# Verifies that versions and hashed value of the package contents in the project's package.json
config.webpacker.check_yarn_integrity = false
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
@ -96,4 +91,10 @@ Rails.application.configure do
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Prepare the ingress controller used to receive mail
# config.action_mailbox.ingress = :postfix
# Verifies that versions and hashed value of the package contents in the project's package.json
config.webpacker.check_yarn_integrity = false
end

View File

@ -19,9 +19,9 @@ Introduction
------------
Action Mailbox routes incoming emails to controller-like mailboxes for
processing in Rails. It ships with ingresses for Amazon SES, Mailgun, Mandrill,
Postmark, and SendGrid. You can also handle inbound mails directly via the
built-in Exim, Postfix, and Qmail ingresses.
processing in Rails. It ships with ingresses for Mailgun, Mandrill, Postmark,
and SendGrid. You can also handle inbound mails directly via the built-in Exim,
Postfix, and Qmail ingresses.
The inbound emails are turned into `InboundEmail` records using Active Record
and feature lifecycle tracking, storage of the original email on cloud storage
@ -43,28 +43,6 @@ $ rails db:migrate
## Configuration
### Amazon SES
Install the [`aws-sdk-sns`](https://rubygems.org/gems/aws-sdk-sns) gem:
```ruby
# Gemfile
gem "aws-sdk-sns", ">= 1.9.0", require: false
```
Tell Action Mailbox to accept emails from SES:
```ruby
# config/environments/production.rb
config.action_mailbox.ingress = :amazon
```
[Configure SES](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-notifications.html)
to deliver emails to your application via POST requests to
`/rails/action_mailbox/amazon/inbound_emails`. If your application lived at
`https://example.com`, you would specify the fully-qualified URL
`https://example.com/rails/action_mailbox/amazon/inbound_emails`.
### Exim
Tell Action Mailbox to accept emails from an SMTP relay:

View File

@ -20,7 +20,6 @@ module ApplicationTests
assert_equal <<~MESSAGE, run_rake_routes
Prefix Verb URI Pattern Controller#Action
cart GET /cart(.:format) cart#show
rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create

View File

@ -62,7 +62,6 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
assert_equal <<~MESSAGE, run_routes_command([ "-g", "POST" ])
Prefix Verb URI Pattern Controller#Action
POST /cart(.:format) cart#create
rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create
@ -166,7 +165,6 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
assert_equal <<~MESSAGE, run_routes_command
Prefix Verb URI Pattern Controller#Action
rails_amazon_inbound_emails POST /rails/action_mailbox/amazon/inbound_emails(.:format) action_mailbox/ingresses/amazon/inbound_emails#create
rails_mandrill_inbound_emails POST /rails/action_mailbox/mandrill/inbound_emails(.:format) action_mailbox/ingresses/mandrill/inbound_emails#create
rails_postmark_inbound_emails POST /rails/action_mailbox/postmark/inbound_emails(.:format) action_mailbox/ingresses/postmark/inbound_emails#create
rails_relay_inbound_emails POST /rails/action_mailbox/relay/inbound_emails(.:format) action_mailbox/ingresses/relay/inbound_emails#create
@ -207,101 +205,96 @@ class Rails::Command::RoutesTest < ActiveSupport::TestCase
URI | /cart(.:format)
Controller#Action | cart#show
--[ Route 2 ]--------------
Prefix | rails_amazon_inbound_emails
Verb | POST
URI | /rails/action_mailbox/amazon/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/amazon/inbound_emails#create
--[ Route 3 ]--------------
Prefix | rails_mandrill_inbound_emails
Verb | POST
URI | /rails/action_mailbox/mandrill/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/mandrill/inbound_emails#create
--[ Route 4 ]--------------
--[ Route 3 ]--------------
Prefix | rails_postmark_inbound_emails
Verb | POST
URI | /rails/action_mailbox/postmark/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/postmark/inbound_emails#create
--[ Route 5 ]--------------
--[ Route 4 ]--------------
Prefix | rails_relay_inbound_emails
Verb | POST
URI | /rails/action_mailbox/relay/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/relay/inbound_emails#create
--[ Route 6 ]--------------
--[ Route 5 ]--------------
Prefix | rails_sendgrid_inbound_emails
Verb | POST
URI | /rails/action_mailbox/sendgrid/inbound_emails(.:format)
Controller#Action | action_mailbox/ingresses/sendgrid/inbound_emails#create
--[ Route 7 ]--------------
--[ Route 6 ]--------------
Prefix | rails_mailgun_inbound_emails
Verb | POST
URI | /rails/action_mailbox/mailgun/inbound_emails/mime(.:format)
Controller#Action | action_mailbox/ingresses/mailgun/inbound_emails#create
--[ Route 8 ]--------------
--[ Route 7 ]--------------
Prefix | rails_conductor_inbound_emails
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#index
--[ Route 9 ]--------------
--[ Route 8 ]--------------
Prefix |
Verb | POST
URI | /rails/conductor/action_mailbox/inbound_emails(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#create
--[ Route 10 ]-------------
--[ Route 9 ]--------------
Prefix | new_rails_conductor_inbound_email
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails/new(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#new
--[ Route 11 ]-------------
--[ Route 10 ]-------------
Prefix | edit_rails_conductor_inbound_email
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails/:id/edit(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#edit
--[ Route 12 ]-------------
--[ Route 11 ]-------------
Prefix | rails_conductor_inbound_email
Verb | GET
URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#show
--[ Route 13 ]-------------
--[ Route 12 ]-------------
Prefix |
Verb | PATCH
URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#update
--[ Route 14 ]-------------
--[ Route 13 ]-------------
Prefix |
Verb | PUT
URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#update
--[ Route 15 ]-------------
--[ Route 14 ]-------------
Prefix |
Verb | DELETE
URI | /rails/conductor/action_mailbox/inbound_emails/:id(.:format)
Controller#Action | rails/conductor/action_mailbox/inbound_emails#destroy
--[ Route 16 ]-------------
--[ Route 15 ]-------------
Prefix | rails_conductor_inbound_email_reroute
Verb | POST
URI | /rails/conductor/action_mailbox/:inbound_email_id/reroute(.:format)
Controller#Action | rails/conductor/action_mailbox/reroutes#create
--[ Route 17 ]-------------
--[ Route 16 ]-------------
Prefix | rails_service_blob
Verb | GET
URI | /rails/active_storage/blobs/:signed_id/*filename(.:format)
Controller#Action | active_storage/blobs#show
--[ Route 18 ]-------------
--[ Route 17 ]-------------
Prefix | rails_blob_representation
Verb | GET
URI | /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format)
Controller#Action | active_storage/representations#show
--[ Route 19 ]-------------
--[ Route 18 ]-------------
Prefix | rails_disk_service
Verb | GET
URI | /rails/active_storage/disk/:encoded_key/*filename(.:format)
Controller#Action | active_storage/disk#show
--[ Route 20 ]-------------
--[ Route 19 ]-------------
Prefix | update_rails_disk_service
Verb | PUT
URI | /rails/active_storage/disk/:encoded_token(.:format)
Controller#Action | active_storage/disk#update
--[ Route 21 ]-------------
--[ Route 20 ]-------------
Prefix | rails_direct_uploads
Verb | POST
URI | /rails/active_storage/direct_uploads(.:format)