Skip to content

Commit 5a94c97

Browse files
authored
Merge pull request #461 from berkeley-cdss/cycomachead/158-is-there-anything-in-the-staging-environment-that-prevents-emails-from-being-sent-out-what-is-the/1
Redirect Staging Emails
2 parents 4511e26 + 056129e commit 5a94c97

3 files changed

Lines changed: 82 additions & 2 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
# ActionMailer interceptor used in the staging environment to ensure we never
4+
# email real people. Every outgoing message is redirected to a single safe
5+
# staging mailbox, and the original recipient(s) are preserved in the subject
6+
# line so the rendered email can still be inspected.
7+
#
8+
# Registered in config/environments/staging.rb via:
9+
# config.action_mailer.interceptors = %w[StagingEmailInterceptor]
10+
class StagingEmailInterceptor
11+
# Address that all staging mail is redirected to. Can be overridden with the
12+
# STAGING_EMAIL_OVERRIDE env var if a different staging inbox is desired.
13+
DEFAULT_OVERRIDE = 'flextensions@berkeley.edu'
14+
15+
def self.delivering_email(message)
16+
original_recipients = Array(message.to).join(', ')
17+
message.subject = "[STAGING -> #{original_recipients}] #{message.subject}"
18+
19+
message.to = ENV.fetch('STAGING_EMAIL_OVERRIDE', DEFAULT_OVERRIDE)
20+
message.cc = nil
21+
message.bcc = nil
22+
end
23+
end

config/environments/staging.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
# Show full error reports, OK because staging is behind a VPN
1111
config.consider_all_requests_local = true
1212

13-
# TODO: Configure ActionMailer to re-write emails to send to staging addresses
14-
# config.action_mailer.perform_deliveries = false
13+
# Ensure staging never emails real people: redirect every outgoing message to
14+
# a single safe staging mailbox, preserving the original recipient(s) in the
15+
# subject line. See StagingEmailInterceptor.
16+
config.action_mailer.interceptors = %w[StagingEmailInterceptor]
1517
end
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# spec/mailers/staging_email_interceptor_spec.rb
2+
require 'rails_helper'
3+
4+
RSpec.describe StagingEmailInterceptor do
5+
def build_message(to:, subject:, cc: nil, bcc: nil)
6+
Mail.new do
7+
to to
8+
cc cc if cc
9+
bcc bcc if bcc
10+
from 'flextensions@berkeley.edu'
11+
subject subject
12+
body 'Hello'
13+
end
14+
end
15+
16+
it 'redirects the recipient to the default staging mailbox' do
17+
message = build_message(to: 'student@example.com', subject: 'Your extension')
18+
described_class.delivering_email(message)
19+
20+
expect(message.to).to eq([ described_class::DEFAULT_OVERRIDE ])
21+
end
22+
23+
it 'honors STAGING_EMAIL_OVERRIDE when set' do
24+
message = build_message(to: 'student@example.com', subject: 'Your extension')
25+
26+
allow(ENV).to receive(:fetch).and_call_original
27+
allow(ENV).to receive(:fetch)
28+
.with('STAGING_EMAIL_OVERRIDE', described_class::DEFAULT_OVERRIDE)
29+
.and_return('someone@example.com')
30+
31+
described_class.delivering_email(message)
32+
33+
expect(message.to).to eq([ 'someone@example.com' ])
34+
end
35+
36+
it 'preserves the original recipient(s) in the subject line' do
37+
message = build_message(to: %w[a@example.com b@example.com], subject: 'Your extension')
38+
described_class.delivering_email(message)
39+
40+
expect(message.subject).to eq('[STAGING -> a@example.com, b@example.com] Your extension')
41+
end
42+
43+
it 'strips cc and bcc so no real person is reached' do
44+
message = build_message(
45+
to: 'student@example.com',
46+
subject: 'Your extension',
47+
cc: 'ta@example.com',
48+
bcc: 'instructor@example.com'
49+
)
50+
described_class.delivering_email(message)
51+
52+
expect(message.cc).to be_nil
53+
expect(message.bcc).to be_nil
54+
end
55+
end

0 commit comments

Comments
 (0)