def _dispose(self, mlist, msg, msgdata): # List isn't doing bounce processing? if not mlist.process_bounces: return False # Try VERP detection first, since it's quick and easy context = BounceContext.normal addresses = StandardVERP().get_verp(mlist, msg) if len(addresses) > 0: # Scan the message to see if it contained permanent or temporary # failures. We'll ignore temporary failures, but even if there # are no permanent failures, we'll assume VERP bounces are # permanent. temporary, permanent = all_failures(msg) if len(temporary) > 0: # This was a temporary failure, so just ignore it. return False else: # See if this was a probe message. addresses = ProbeVERP().get_verp(mlist, msg) if len(addresses) > 0: context = BounceContext.probe else: # That didn't give us anything useful, so try the old fashion # bounce matching modules. Since Mailman currently doesn't # score temporary failures, if we get no permanent failures, # we're done, but we do need to check for temporary failures # to know if the bounce was recognized. temporary, addresses = all_failures(msg) if len(addresses) == 0 and len(temporary) > 0: # This is a recognized temp fail so ignore it. return False # If that still didn't return us any useful addresses, then send it on # or discard it. The addresses will come back from flufl.bounce as # bytes/8-bit strings, but we must store them as unicodes in the # database. Assume utf-8 encoding, but be cautious. if len(addresses) > 0: for address in addresses: if isinstance(address, bytes): try: address = address.decode('utf-8') except UnicodeError: log.exception('Ignoring non-UTF-8 encoded ' 'address: {}'.format(address)) continue self._processor.register(mlist, address, msg, context) else: log.info('Bounce message w/no discernable addresses: %s', msg.get('message-id', 'n/a')) maybe_forward(mlist, msg) # Dequeue this message. return False
def test_get_addresses(self): # Be able to extract the probed address from the pending database # based on the token in a probe bounce. token = send_probe(self._member, self._msg) # Simulate a bounce of the message in the virgin queue. message = get_queue_messages('virgin')[0].msg bounce = mfs("""\ To: {0} From: [email protected] """.format(message['From'])) addresses = ProbeVERP().get_verp(self._mlist, bounce) self.assertEqual(addresses, set(['*****@*****.**'])) # The pendable is no longer in the database. self.assertEqual(getUtility(IPendings).confirm(token), None)