Skip to content

Commit f263530

Browse files
authored
Merge pull request rails#42634 from HackerIntro/actionmailbox-storage-service
Problem: ActionMailbox uses default ActiveStorage service
2 parents ef747e9 + 855e08d commit f263530

File tree

9 files changed

+84
-2
lines changed

9 files changed

+84
-2
lines changed

actionmailbox/CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
* Add ability to configure ActiveStorage service
2+
for storing email raw source.
3+
4+
```yml
5+
# config/storage.yml
6+
incoming_emails:
7+
service: Disk
8+
root: /secure/dir/for/emails/only
9+
```
10+
11+
```ruby
12+
config.action_mailbox.storage_service = :incoming_emails
13+
```
14+
15+
*Yurii Rashkovskii*
16+
117
* Add ability to incinerate an inbound message through the conductor interface.
218

319
*Santiago Bartesaghi*

actionmailbox/app/models/action_mailbox/inbound_email.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class InboundEmail < Record
2929

3030
include Incineratable, MessageId, Routable
3131

32-
has_one_attached :raw_email
32+
has_one_attached :raw_email, service: ActionMailbox.storage_service
3333
enum status: %i[ pending processing delivered failed bounced ]
3434

3535
def mail

actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ def generate_missing_message_id(message_checksum)
3535
end
3636

3737
def create_and_upload_raw_email!(source)
38-
ActiveStorage::Blob.create_and_upload! io: StringIO.new(source), filename: "message.eml", content_type: "message/rfc822"
38+
ActiveStorage::Blob.create_and_upload! io: StringIO.new(source), filename: "message.eml", content_type: "message/rfc822",
39+
service_name: ActionMailbox.storage_service
3940
end
4041
end
4142
end

actionmailbox/lib/action_mailbox.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ module ActionMailbox
1414
mattr_accessor :incinerate, default: true
1515
mattr_accessor :incinerate_after, default: 30.days
1616
mattr_accessor :queues, default: {}
17+
mattr_accessor :storage_service
1718
end

actionmailbox/lib/action_mailbox/engine.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ class Engine < Rails::Engine
2020
config.action_mailbox.queues = ActiveSupport::InheritableOptions.new \
2121
incineration: :action_mailbox_incineration, routing: :action_mailbox_routing
2222

23+
config.action_mailbox.storage_service = nil
24+
2325
initializer "action_mailbox.config" do
2426
config.after_initialize do |app|
2527
ActionMailbox.logger = app.config.action_mailbox.logger || Rails.logger
2628
ActionMailbox.incinerate = app.config.action_mailbox.incinerate.nil? ? true : app.config.action_mailbox.incinerate
2729
ActionMailbox.incinerate_after = app.config.action_mailbox.incinerate_after || 30.days
2830
ActionMailbox.queues = app.config.action_mailbox.queues || {}
2931
ActionMailbox.ingress = app.config.action_mailbox.ingress
32+
ActionMailbox.storage_service = app.config.action_mailbox.storage_service
3033
end
3134
end
3235
end

actionmailbox/test/dummy/config/storage.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ local:
66
service: Disk
77
root: <%= Rails.root.join("storage") %>
88

9+
test_email:
10+
service: Disk
11+
root: <%= Rails.root.join("tmp/storage_email") %>
12+
913
# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
1014
# amazon:
1115
# service: S3

actionmailbox/test/unit/inbound_email_test.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,41 @@ class InboundEmailTest < ActiveSupport::TestCase
4444
end
4545
end
4646
end
47+
48+
test "email gets saved to the configured storage service" do
49+
ActionMailbox.storage_service = :test_email
50+
51+
assert_equal(:test_email, ActionMailbox.storage_service)
52+
53+
email = create_inbound_email_from_fixture("welcome.eml")
54+
55+
storage_service = ActiveStorage::Blob.services.fetch(ActionMailbox.storage_service)
56+
raw = email.raw_email_blob
57+
58+
# Not present in the main storage
59+
assert_not(ActiveStorage::Blob.service.exist?(raw.key))
60+
# Present in the email storage
61+
assert(storage_service.exist?(raw.key))
62+
ensure
63+
ActionMailbox.storage_service = nil
64+
end
65+
66+
test "email gets saved to the default storage service, even if it gets changed" do
67+
default_service = ActiveStorage::Blob.service
68+
ActiveStorage::Blob.service = ActiveStorage::Blob.services.fetch(:test_email)
69+
70+
# Doesn't change ActionMailbox.storage_service
71+
assert_nil(ActionMailbox.storage_service)
72+
73+
email = create_inbound_email_from_fixture("welcome.eml")
74+
raw = email.raw_email_blob
75+
76+
# Not present in the (previously) default storage
77+
assert_not(default_service.exist?(raw.key))
78+
# Present in the current default storage (email)
79+
assert(ActiveStorage::Blob.service.exist?(raw.key))
80+
ensure
81+
ActiveStorage::Blob.service = default_service
82+
end
4783
end
4884
end

guides/source/configuring.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,8 @@ Defaults to `'signed cookie'`.
785785

786786
* `config.action_mailbox.queues.routing` accepts a symbol indicating the Active Job queue to use for routing jobs. When this option is `nil`, routing jobs are sent to the default Active Job queue (see `config.active_job.default_queue_name`).
787787

788+
* `config.action_mailbox.storage_service` accepts a symbol indicating the Active Storage service to use for uploading emails. When this option is `nil`, emails are uploaded to the default Active Storage service (see `config.active_storage.service`).
789+
788790
### Configuring Action Mailer
789791

790792
There are a number of settings available on `config.action_mailer`:

railties/test/application/configuration_test.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2946,6 +2946,25 @@ class MyLogger < ::Logger
29462946
assert_equal :another_queue, ActionMailbox.queues[:routing]
29472947
end
29482948

2949+
test "ActionMailbox.storage_service is nil by default (default service)" do
2950+
app "development"
2951+
assert_nil(ActionMailbox.storage_service)
2952+
end
2953+
2954+
test "ActionMailbox.storage_service can be configured" do
2955+
add_to_config <<-RUBY
2956+
config.active_storage.service_configurations = {
2957+
email: {
2958+
root: "#{Dir.tmpdir}/email",
2959+
service: "Disk"
2960+
}
2961+
}
2962+
config.action_mailbox.storage_service = :email
2963+
RUBY
2964+
app "development"
2965+
assert_equal(:email, ActionMailbox.storage_service)
2966+
end
2967+
29492968
test "ActionMailer::Base.delivery_job is ActionMailer::MailDeliveryJob by default" do
29502969
app "development"
29512970

0 commit comments

Comments
 (0)