On 7/1/2013 10:24 AM, Chris Nulk wrote: > Hello user, > > I am writing a custom handler to globally ban email address from sending > messages sent to Mailman. I know I can use Mark's add_banned.py script > to add an address to all lists. However, if I add an address to be > banned, as the administrator for all lists, I don't want a list admin to > remove a pest from their list(s). I banned an address for being a pest > to all lists (or a majority of them), therefore, the address stays banned.
Note that the ban_list only prevents the address from subscribing. If the address was already a member when banned, it can still post. > Before I put the custom handler in place and screw up my lists, I > thought I would post it here so others more knowledgeable can review it > and let me know if it will work, correct it, and/or improve it. > > #!/usr/bin/env python > # > > """This is a custom handler that will check all the sender addresses of > a message against a global ban list. If any of the sender addresses are > on the global ban list, the message will get logged and discarded. > """ > > import sys > > from Mailman import mm_cfg > from Mailman import Utils > from Mailman import Message > from Mailman import Errors > from Mailman.i18n import _ > from Mailman.Logging.Syslog import syslog > from Mailman.MailList import MailList You don't actually use MailList so there's no need to import it. Also Utils, Message, Errors and _ are used only by the discard code you copied. You could instead just >From Mailman.Handlers.Moderate import do_discard and use that if it wasn't important to have specific messages. OTOH, see below. > > def process(mlist, msg, msgdata): > # added because it was in Mailman/Handlers/Moderate.py > # I am guessing it has to due in part with an upstream > # pipeline handler marking the message approved and/or > # because the handler can be moved to different parts > # of the pipeline. > # But, I have been wrong before. > if msgdata.get('approved') or msgdata.get('fromusenet'): > return There are two things in the above. The test for 'approved' says if this message was pre-approved by inclusion of an Approved: <list_pw> header or pseudo-header, or if this message was held for moderation by a prior handler and approved by the moderator, then skip this handler. The test for 'fromusenet' says if this post arrived via the Mail<->Usenet gateway, then skip this handler. You probably don't want the " or msgdata.get('fromusenet')" part even if you are gating from usenet. > > # First, initialize the banlist > banlist = [] > > # Read in the global ban list of email addresses > # mm_cfg.GLOBALBANLIST_FILENAME is defined in mm_cfg and should > # be the full path to the file. > try: > with open(mm_cfg.GLOBALBANLIST_FILENAME) as f: > for addr in f: > banlist.append(addr.lower().strip()) > except IOError: > # cannot open the global ban list for whatever reason > # log it and continue with the next pipeline handler > syslog('error', 'An error occurred opening the global ban list') I would put something like except IOError, e: syslog('error', "Can't open %s: %s" % (mm_cfg.GLOBALBANLIST_FILENAME, e) ) > return > except: > # unspecified error > # log it and continue with the next pipeline handler > syslog('error', "ERROR: Unknown error: ", sys.exc_info()[0]) and here I would put syslog('error', 'ERROR: %s: %s' % (sys.exc_info()[0], sys.exc_info()[1]) ) > return > > # Go through possible senders. Check if any of them are > # on the global ban list > for sender in msg.get_senders(): > if sender.lower() in banlist: > break > else: > # None of the sender addresses were in the global ban > # list so return and continue with the next pipeline > # handler > return > > # A sender was found on the global ban list. Log it and > # discard the message notifying the list owner > if sender: How can this be False? > # Log banned sender to the vette log > syslog('vette', '%s is banned by the global ban list', sender) > # Perform message discard > do_discard_globalban(mlist, msg) You could just import do_discard from Mailman.Handlers.Moderate and use that, but you may want the custom messages. If so, you may also want do_discard_globalban(mlist, msg, sender) > else: > assert 0, 'Bad sender in GlobalBan.py' > > > # copied almost verbatim from Mailman/Handlers/Moderate.py > def do_discard_globalban(mlist, msg): > sender = msg.get_sender Actually, that should be sender = msg.get_sender() but as I indicate above it would be better to pass the bad sender in the call because msg.get_senders() returns a list of sender addresses and msg.get_sender() returns a single address which may not be the get_senders() address you found in your blacklist. > # forward auto-discards to list owners? > if mlist.forward_auto_discards: > lang = mlist.preferred_language > # is varhelp used anywhere? > varhelp = '%s/?VARHELP=privacy/sender/discard_these_nonmembers' % \ > mlist.GetScriptURL('admin', absolute=1) It is the URL to the web admin (Details for discard_these_nonmembers) page. Someone intended to include it in the auto-discard notice but either never did or at some point it was dropped without removing the above. It is currently superfluous. > nmsg = Message.UserNotification(mlist.GetOwnerEmail(), > mlist.GetBouncesEmail(), > _('Global Ban List Auto-discard > notification'), > lang=lang) > nmsg.set_type('multipart/mixed') > text = MIMEText(Utils.wrap(_("""\ > The sender of the attached message is on the Global Ban list. Therefore, > the message > has been automatically discarded.""")), > _charset=Utils.GetCharSet(lang)) > nmsg.attach(text) > nmsg.attach(MIMEMessage(msg)) > nmsg.send(mlist) > # Discard the message > raise Errors.DiscardMessage -- Mark Sapiro <m...@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan ------------------------------------------------------ Mailman-Users mailing list Mailman-Users@python.org http://mail.python.org/mailman/listinfo/mailman-users Mailman FAQ: http://wiki.list.org/x/AgA3 Security Policy: http://wiki.list.org/x/QIA9 Searchable Archives: http://www.mail-archive.com/mailman-users%40python.org/ Unsubscribe: http://mail.python.org/mailman/options/mailman-users/archive%40jab.org