def test_priority_site_over_list(self): # Test that the site-wide checks take precedence over the list-specific # checks. msg = mfs("""\ From: [email protected] To: [email protected] Subject: A message Message-ID: <ant> Foo: foo MIME-Version: 1.0 A message body. """) msgdata = {} header_matches = IHeaderMatchList(self._mlist) header_matches.append('Foo', 'foo', 'accept') # This event subscriber records the event that occurs when the message # is processed by the owner chain. events = [] with event_subscribers(events.append): process(self._mlist, msg, msgdata, start_chain='header-match') self.assertEqual(len(events), 1) event = events[0] # Site-wide wants to hold the message, the list wants to accept it. self.assertIsInstance(event, HoldEvent) self.assertEqual(event.chain, config.chains['hold'])
def test_no_action_defaults_to_site_wide_action(self): # If the list-specific header check matches, but there is no defined # action, the site-wide antispam action is used. msg = mfs("""\ From: [email protected] To: [email protected] Subject: A message Message-ID: <ant> Foo: foo MIME-Version: 1.0 A message body. """) header_matches = IHeaderMatchList(self._mlist) header_matches.append('Foo', 'foo') # This event subscriber records the event that occurs when the message # is processed by the owner chain, which holds its for approval. events = [] def record_holds(event): # noqa if not isinstance(event, HoldEvent): return events.append(event) with event_subscribers(record_holds): # Set the site-wide antispam action to hold the message. with configuration('antispam', header_checks=""" Spam: [*]{3,} """, jump_chain='hold'): # noqa process(self._mlist, msg, {}, start_chain='header-match') self.assertEqual(len(events), 1) event = events[0] self.assertIsInstance(event, HoldEvent) self.assertEqual(event.chain, config.chains['hold']) self.assertEqual(event.mlist, self._mlist) self.assertEqual(event.msg, msg) events = [] def record_discards(event): # noqa if not isinstance(event, DiscardEvent): return events.append(event) with event_subscribers(record_discards): # Set the site-wide default to discard the message. msg.replace_header('Message-Id', '<bee>') with configuration('antispam', header_checks=""" Spam: [*]{3,} """, jump_chain='discard'): # noqa process(self._mlist, msg, {}, start_chain='header-match') self.assertEqual(len(events), 1) event = events[0] self.assertIsInstance(event, DiscardEvent) self.assertEqual(event.chain, config.chains['discard']) self.assertEqual(event.mlist, self._mlist) self.assertEqual(event.msg, msg)
def _dispose(self, mlist, msg, msgdata): """See `IRunner`.""" if msgdata.get("envsender") is None: msgdata["envsender"] = mlist.no_reply_address # Ensure that the email addresses of the message's senders are known # to Mailman. This will be used in nonmember posting dispositions. user_manager = getUtility(IUserManager) with transaction(): for sender in msg.senders: with suppress(ExistingAddressError): user_manager.create_address(sender) # Process the message through the mailing list's start chain. start_chain = mlist.owner_chain if msgdata.get("to_owner", False) else mlist.posting_chain process(mlist, msg, msgdata, start_chain) # Do not keep this message queued. return False
def test_owner_pipeline(self): # Messages processed through the default owners chain end up in the # pipeline queue, and an event gets sent. # # This event subscriber records the event that occurs when the message # is processed by the owner chain. events = [] def catch_event(event): # noqa if isinstance(event, AcceptOwnerEvent): events.append(event) with event_subscribers(catch_event): process(self._mlist, self._msg, {}, 'default-owner-chain') self.assertEqual(len(events), 1) event = events[0] self.assertIsInstance(event, AcceptOwnerEvent) self.assertEqual(event.mlist, self._mlist) self.assertEqual(event.msg['message-id'], '<ant>') self.assertIsInstance(event.chain, BuiltInOwnerChain) items = get_queue_messages('pipeline', expected_count=1) message = items[0].msg self.assertEqual(message['message-id'], '<ant>')
def test_get_all_returns_non_string(self): # Test case where msg.get_all() returns header instance. msg = message_from_bytes( b"""\ From: [email protected] To: [email protected] Subject: Bad \x96 subject Message-ID: <ant> body """, Message) msgdata = {} header_matches = IHeaderMatchList(self._mlist) header_matches.append('Subject', 'Bad', 'hold') # This event subscriber records the event that occurs when the message # is processed by the owner chain. events = [] with event_subscribers(events.append): process(self._mlist, msg, msgdata, start_chain='header-match') self.assertEqual(len(events), 1) event = events[0] self.assertIsInstance(event, HoldEvent) self.assertEqual(event.chain, config.chains['hold'])
def test_rfc2047_encodedheader(self): # Test case where msg.get_all() returns raw rfc2047 encoded string. msg = message_from_bytes( b"""\ From: [email protected] To: [email protected] Subject: =?utf-8?b?SSBsaWtlIElrZQo=?= Message-ID: <ant> body """, Message) msgdata = {} header_matches = IHeaderMatchList(self._mlist) header_matches.append('Subject', 'I Like Ike', 'hold') # This event subscriber records the event that occurs when the message # is processed by the owner chain. events = [] with event_subscribers(events.append): process(self._mlist, msg, msgdata, start_chain='header-match') self.assertEqual(len(events), 1) event = events[0] self.assertIsInstance(event, HoldEvent) self.assertEqual(event.chain, config.chains['hold'])
def test_owner_pipeline(self): # Messages processed through the default owners chain end up in the # pipeline queue, and an event gets sent. # # This event subscriber records the event that occurs when the message # is processed by the owner chain. events = [] def catch_event(event): if isinstance(event, AcceptOwnerEvent): events.append(event) with event_subscribers(catch_event): process(self._mlist, self._msg, {}, 'default-owner-chain') self.assertEqual(len(events), 1) event = events[0] self.assertTrue(isinstance(event, AcceptOwnerEvent)) self.assertEqual(event.mlist, self._mlist) self.assertEqual(event.msg['message-id'], '<ant>') self.assertTrue(isinstance(event.chain, BuiltInOwnerChain)) messages = get_queue_messages('pipeline') self.assertEqual(len(messages), 1) message = messages[0].msg self.assertEqual(message['message-id'], '<ant>')