1010
1111from django .conf import settings
1212from django .core .mail import get_connection , EmailMessage
13- from django .test import TestCase
13+ from django .test import TestCase , override_settings
1414
1515
1616class FakeSMTPServer (smtpd .SMTPServer , threading .Thread ):
@@ -73,6 +73,8 @@ def stop(self):
7373 self .join ()
7474
7575
76+ @override_settings (BANDIT_EMAIL = 'bandit@example.com' )
77+ @override_settings (ADMINS = (('Admin' , 'admin@example.com' ),))
7678class BaseBackendTestCase (TestCase ):
7779 """
7880 Test email interception in the HijackBackend.
@@ -83,17 +85,11 @@ def setUpClass(cls):
8385 cls .server = FakeSMTPServer (('127.0.0.1' , 0 ), None )
8486 settings .EMAIL_HOST = "127.0.0.1"
8587 settings .EMAIL_PORT = cls .server .socket .getsockname ()[1 ]
86- cls ._original_admins = settings .ADMINS
87- cls ._original_bandit = getattr (settings , 'BANDIT_EMAIL' , '' )
88- settings .BANDIT_EMAIL = 'bandit@example.com'
89- settings .ADMINS = (('Admin' , 'admin@example.com' ), )
9088 cls .server .start ()
9189
9290 @classmethod
9391 def tearDownClass (cls ):
9492 cls .server .stop ()
95- settings .BANDIT_EMAIL = cls ._original_bandit
96- settings .ADMINS = cls ._original_admins
9793
9894 def setUp (self ):
9995 super (BaseBackendTestCase , self ).setUp ()
@@ -118,35 +114,51 @@ class HijackBackendTestCase(BaseBackendTestCase):
118114 def get_connection (self ):
119115 return get_connection ('bandit.backends.smtp.HijackSMTPBackend' )
120116
121- def test_basic_hijack (self ):
122- """Emails should be redirected to send to BANDIT_EMAIL."""
123- emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' ])]
117+ def assert_emails_are_hijacked (self , emails ):
124118 num_sent = self .get_connection ().send_messages (emails )
125119 self .assertEqual (len (emails ), num_sent )
126120 messages = self .get_mailbox_content ()
127121 self .assertEqual (len (messages ), num_sent )
128- message = messages [0 ]
129- self .assertEqual (message .get_all ('to' ), ['bandit@example.com' , ])
122+ if isinstance (settings .BANDIT_EMAIL , list ):
123+ self .assertEqual (messages [0 ].get_all ('to' )[0 ].replace ('\n ' , '' ), ', ' .join (settings .BANDIT_EMAIL ))
124+ else :
125+ self .assertEqual (messages [0 ].get_all ('to' ), ['bandit@example.com' , ])
130126
131- def test_send_to_admins (self ):
132- """Admin emails should not be hijacked."""
133- emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['admin@example.com' ])]
134- num_sent = self .get_connection ().send_messages (emails )
135- self .assertEqual (len (emails ), num_sent )
136- messages = self .get_mailbox_content ()
137- self .assertEqual (len (messages ), num_sent )
138- message = messages [0 ]
139- self .assertEqual (message .get_all ('to' ), ['admin@example.com' , ])
127+ def test_basic_hijack (self ):
128+ """Emails should be redirected to send to BANDIT_EMAIL."""
129+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' ])]
130+ self .assert_emails_are_hijacked (emails )
131+
132+ @override_settings (BANDIT_EMAIL = ['bandit@example.com' , 'accomplice@example.com' , 'Hijacker <hijacker@example.com>' ])
133+ def test_send_to_multiple_bandits (self ):
134+ """Emails should be redirected to all bandit emails."""
135+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' ])]
136+ self .assert_emails_are_hijacked (emails )
137+
138+ def test_hijack_cc (self ):
139+ """Emails with unapproved recipient in CC should be redirected to send to BANDIT_EMAIL."""
140+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , to = ['admin@example.com' ], cc = ['to@example.com' ])]
141+ self .assert_emails_are_hijacked (emails )
142+
143+ def test_hijack_bcc (self ):
144+ """Emails with unapproved recipient in BCC should be redirected to send to BANDIT_EMAIL."""
145+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , to = ['admin@example.com' ], bcc = ['to@example.com' ])]
146+ self .assert_emails_are_hijacked (emails )
140147
141148 def test_send_to_mixed (self ):
142149 """Emails with mixed recipients will be hijacked."""
143150 emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' , 'admin@example.com' ])]
151+ self .assert_emails_are_hijacked (emails )
152+
153+ def test_send_to_admins (self ):
154+ """Admin emails should not be hijacked."""
155+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['admin@example.com' ])]
144156 num_sent = self .get_connection ().send_messages (emails )
145157 self .assertEqual (len (emails ), num_sent )
146158 messages = self .get_mailbox_content ()
147159 self .assertEqual (len (messages ), num_sent )
148160 message = messages [0 ]
149- self .assertEqual (message .get_all ('to' ), ['bandit @example.com' , ])
161+ self .assertEqual (message .get_all ('to' ), ['admin @example.com' , ])
150162
151163 def test_send_multiple (self ):
152164 """Emails with mixed recipients will be hijacked."""
@@ -162,10 +174,11 @@ def test_send_multiple(self):
162174 self .assertEqual (message .get_all ('to' ), ['admin@example.com' , ])
163175
164176 def test_whitelist_domain (self ):
177+ """Emails send to whitelisted domains should not be hijacked"""
165178 addresses = ['foo@whitelisted.test.com' ,
166179 '<bar@whitelisted.test.com>' ,
167180 'Foo Bar <baz@whitelisted.test.com>' ]
168- emails = [EmailMessage ( 'Subject' , 'Content' , 'from@example.com' , addresses )]
181+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , addresses )]
169182 num_sent = self .get_connection ().send_messages (emails )
170183 self .assertEqual (len (emails ), num_sent )
171184 messages = self .get_mailbox_content ()
@@ -177,14 +190,38 @@ class LogOnlyBackendTestCase(BaseBackendTestCase):
177190 def get_connection (self ):
178191 return get_connection ('bandit.backends.smtp.LogOnlySMTPBackend' )
179192
180- def test_basic_hijack (self ):
181- """Emails should only be logged."""
182- emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' ])]
193+ def assert_emails_are_only_logged (self , emails ):
183194 num_sent = self .get_connection ().send_messages (emails )
184195 self .assertEqual (len (emails ), num_sent )
185196 messages = self .get_mailbox_content ()
186197 self .assertEqual (len (messages ), 0 )
187198
199+ def test_basic_hijack (self ):
200+ """Emails should only be logged."""
201+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' ])]
202+ self .assert_emails_are_only_logged (emails )
203+
204+ @override_settings (BANDIT_EMAIL = ['bandit@example.com' , 'accomplice@example.com' , 'Hijacker <hijacker@example.com>' ])
205+ def test_send_to_multiple_bandits (self ):
206+ """Even with multiple bandit emails the email are only logged."""
207+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' ])]
208+ self .assert_emails_are_only_logged (emails )
209+
210+ def test_hijack_cc (self ):
211+ """Emails with unapproved recipient in CC should only be logged."""
212+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , to = ['admin@example.com' ], cc = ['to@example.com' ])]
213+ self .assert_emails_are_only_logged (emails )
214+
215+ def test_hijack_bcc (self ):
216+ """Emails with unapproved recipient in BCC should only be logged."""
217+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , to = ['admin@example.com' ], bcc = ['to@example.com' ])]
218+ self .assert_emails_are_only_logged (emails )
219+
220+ def test_send_to_mixed (self ):
221+ """Emails with mixed recipients will only be logged."""
222+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' , 'admin@example.com' ])]
223+ self .assert_emails_are_only_logged (emails )
224+
188225 def test_send_to_admins (self ):
189226 """Admin emails should still be sent."""
190227 emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['admin@example.com' ])]
@@ -195,14 +232,6 @@ def test_send_to_admins(self):
195232 message = messages [0 ]
196233 self .assertEqual (message .get_all ('to' ), ['admin@example.com' , ])
197234
198- def test_send_to_mixed (self ):
199- """Emails with mixed recipients will only be logged."""
200- emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' , 'admin@example.com' ])]
201- num_sent = self .get_connection ().send_messages (emails )
202- self .assertEqual (len (emails ), num_sent )
203- messages = self .get_mailbox_content ()
204- self .assertEqual (len (messages ), 0 )
205-
206235 def test_send_multiple (self ):
207236 """Only the email to the admin should be sent (the other should be logged)."""
208237 emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , ['to@example.com' ]),
@@ -213,3 +242,15 @@ def test_send_multiple(self):
213242 self .assertEqual (len (messages ), 1 )
214243 message = messages [0 ]
215244 self .assertEqual (message .get_all ('to' ), ['admin@example.com' , ])
245+
246+ def test_whitelist_domain (self ):
247+ """Emails send to whitelisted domains are still sent"""
248+ addresses = ['foo@whitelisted.test.com' ,
249+ '<bar@whitelisted.test.com>' ,
250+ 'Foo Bar <baz@whitelisted.test.com>' ]
251+ emails = [EmailMessage ('Subject' , 'Content' , 'from@example.com' , addresses )]
252+ num_sent = self .get_connection ().send_messages (emails )
253+ self .assertEqual (len (emails ), num_sent )
254+ messages = self .get_mailbox_content ()
255+ self .assertEqual (len (messages ), num_sent )
256+ self .assertEqual (messages [0 ].get_all ('to' )[0 ].replace ('\n ' , '' ), ', ' .join (addresses ))
0 commit comments