def dispose(mlist, msg, msgdata, why): if mlist.filter_action is FilterAction.reject: # Bounce the message to the original author. raise RejectMessage(why) elif mlist.filter_action is FilterAction.forward: # Forward it on to the list moderators. text = _("""\ The attached message matched the $mlist.display_name mailing list's content filtering rules and was prevented from being forwarded on to the list membership. You are receiving the only remaining copy of the discarded message. """) subject = _('Content filter message notification') notice = OwnerNotification(mlist, subject, roster=mlist.moderators) notice.set_type('multipart/mixed') notice.attach(MIMEText(text)) notice.attach(MIMEMessage(msg)) notice.send(mlist) # Let this fall through so the original message gets discarded. elif mlist.filter_action is FilterAction.preserve: if as_boolean(config.mailman.filtered_messages_are_preservable): # This is just like discarding the message except that a copy is # placed in the 'bad' queue should the site administrator want to # inspect the message. filebase = config.switchboards['bad'].enqueue(msg, msgdata) log.info('{} preserved in file base {}'.format( msg.get('message-id', 'n/a'), filebase)) else: log.error('{} invalid FilterAction: {}. Treating as discard'.format( mlist.fqdn_listname, mlist.filter_action.name)) # Most cases also discard the message raise DiscardMessage(why)
def _process(self, mlist, msg, msgdata): """See `TerminalChainBase`.""" # Start by decorating the message with a header that contains a list # of all the rules that matched. These metadata could be None or an # empty list. rule_hits = msgdata.get('rule_hits') if rule_hits: msg['X-Mailman-Rule-Hits'] = SEMISPACE.join(rule_hits) rule_misses = msgdata.get('rule_misses') if rule_misses: msg['X-Mailman-Rule-Misses'] = SEMISPACE.join(rule_misses) reasons = msgdata.get('moderation_reasons') if reasons is None: error = None else: error = RejectMessage(_(""" Your message to the {list_name} mailing-list was rejected for the following reasons: {reasons} The original message as received by Mailman is attached. """).format( list_name=mlist.display_name, # noqa reasons=NEWLINE.join(reasons) # noqa )) bounce_message(mlist, msg, error) log.info('REJECT: %s', msg.get('message-id', 'n/a')) notify(RejectEvent(mlist, msg, msgdata, self))
def process(self, mlist, msg, msgdata): """See `IHandler`.""" # Short circuit if we've already calculated the recipients list, # regardless of whether the list is empty or not. if 'recipients' in msgdata: return # Should the original sender should be included in the recipients list? include_sender = True member = mlist.members.get_member(msg.sender) if member and not member.receive_own_postings: include_sender = False # Support for urgent messages, which bypasses digests and disabled # delivery and forces an immediate delivery to all members Right Now. # We are specifically /not/ allowing the site admins password to work # here because we want to discourage the practice of sending the site # admin password through email in the clear. (see also Approve.py) # # XXX This is broken. missing = object() password = msg.get('urgent', missing) if password is not missing: if mlist.Authenticate((config.AuthListModerator, config.AuthListAdmin), password): recipients = mlist.getMemberCPAddresses( mlist.getRegularMemberKeys() + mlist.getDigestMemberKeys()) msgdata['recipients'] = recipients return else: # Bad Urgent: password, so reject it instead of passing it on. # I think it's better that the sender know they screwed up # than to deliver it normally. text = _("""\ Your urgent message to the $mlist.display_name mailing list was not authorized for delivery. The original message as received by Mailman is attached. """) raise RejectMessage(wrap(text)) # Calculate the regular recipients of the message recipients = set(member.address.email for member in mlist.regular_members.members if member.delivery_status == DeliveryStatus.enabled) # Remove the sender if they don't want to receive their own posts if not include_sender and member.address.email in recipients: recipients.remove(member.address.email) # Handle topic classifications # XXX: Disabled for now until we fix it properly # # do_topic_filters(mlist, msg, msgdata, recipients) # # Bookkeeping msgdata['recipients'] = recipients
def _process(self, mlist, msg, msgdata): """See `TerminalChainBase`.""" # Start by decorating the message with a header that contains a list # of all the rules that matched. These metadata could be None or an # empty list. rule_hits = msgdata.get('rule_hits') if rule_hits: msg['X-Mailman-Rule-Hits'] = SEMISPACE.join(rule_hits) rule_misses = msgdata.get('rule_misses') if rule_misses: msg['X-Mailman-Rule-Misses'] = SEMISPACE.join(rule_misses) reasons = msgdata.get('moderation_reasons') if reasons is None: error = None else: template = getUtility(ITemplateLoader).get( 'list:user:notice:rejected', mlist) error = RejectMessage(template, reasons, dict(listname=mlist.display_name)) bounce_message(mlist, msg, error) log.info('REJECT: %s', msg.get('message-id', 'n/a')) notify(RejectEvent(mlist, msg, msgdata, self))
def process(self, mlist, msg, msgdata): raise RejectMessage(self.message)
def process(self, mlist, msg, msgdata): raise RejectMessage('by test handler')