From de7716bcd1f49504d055d46db938778a10bacb39 Mon Sep 17 00:00:00 2001 From: richard Date: Fri, 26 Mar 2004 00:44:11 +0000 Subject: [PATCH] add and use Reject exception (sf bug 700265) git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@2197 57a73879-2fb5-44c3-a270-3262357dd7e2 --- CHANGES.txt | 4 +++ doc/customizing.txt | 33 +++++++++++++++++++++++- roundup/cgi/actions.py | 3 +++ roundup/cgi/exceptions.py | 7 ++++++ roundup/exceptions.py | 19 ++++++++++++++ roundup/mailgw.py | 53 +++++++++++++++++++++++---------------- 6 files changed, 97 insertions(+), 22 deletions(-) create mode 100644 roundup/exceptions.py diff --git a/CHANGES.txt b/CHANGES.txt index ea80670..b00dbb9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,12 +7,16 @@ Feature: - added new auditor, emailauditor.py, that works around a bug in IE. See emailauditor.py for more info. - added dispatcher functionality - see upgrading.txt for more info +- added Reject exception which may be raised by auditors. This is trapped + by mailgw and may be used to veto creation of file attachments or + messages. (sf bug 700265) Fixed: - Boolean HTML templating was broken - Link HTML templating field() was broken - Fix reporting of test inclusion in postgresql test + 2004-03-24 0.7.0b1 Major new features: - added postgresql backend (originally from sf patch 761740, many changes diff --git a/doc/customizing.txt b/doc/customizing.txt index 27e73bb..084d334 100644 --- a/doc/customizing.txt +++ b/doc/customizing.txt @@ -2,7 +2,7 @@ Customising Roundup =================== -:Version: $Revision: 1.122 $ +:Version: $Revision: 1.123 $ .. This document borrows from the ZopeBook section on ZPT. The original is at: http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx @@ -586,6 +586,37 @@ to use one, copy it to the ``'detectors'`` of your tracker instance: db.issue.react('create', newissuecopy) +Auditor or Reactor? +------------------- + +Generally speaking, the following rules should be observed: + +**Auditors** + Are used for `vetoing creation of or changes to items`_. They might + also make automatic changes to item properties. +**Reactors** + Detect changes in the database and react accordingly. They should avoid + making changes to the database where possible, as this could create + detector loops. + +Vetoing creation of or changes to items +--------------------------------------- + +Auditors may raise the ``Reject`` exception to prevent the creation of +or changes to items in the database. The mail gateway, for example, will +not attach files or messages to issues when the creation of those files or +messages are prevented through the ``Reject`` exception. It'll also not create +users if that creation is ``Reject``'ed too. + +To use, simply add at the top of your auditor:: + + from roundup.exceptions import Reject + +And then when your rejection criteria have been detected, simply:: + + raise Reject + + Database Content ================ diff --git a/roundup/cgi/actions.py b/roundup/cgi/actions.py index 5fbbf22..42bd7ec 100755 --- a/roundup/cgi/actions.py +++ b/roundup/cgi/actions.py @@ -1,3 +1,5 @@ +#$Id: actions.py,v 1.15 2004-03-26 00:44:11 richard Exp $ + import re, cgi, StringIO, urllib, Cookie, time, random from roundup import hyperdb, token, date, password, rcsv @@ -837,3 +839,4 @@ class ExportCSVAction(Action): return '\n' +# vim: set filetype=python ts=4 sw=4 et si diff --git a/roundup/cgi/exceptions.py b/roundup/cgi/exceptions.py index 2929895..1d24fc1 100755 --- a/roundup/cgi/exceptions.py +++ b/roundup/cgi/exceptions.py @@ -1,3 +1,9 @@ +#$Id: exceptions.py,v 1.4 2004-03-26 00:44:11 richard Exp $ +'''Exceptions for use in Roundup's web interface. +''' + +__docformat__ = 'restructuredtext' + import cgi class HTTPException(Exception): @@ -51,3 +57,4 @@ class SeriousError(Exception): '''%cgi.escape(self.args[0]) +# vim: set filetype=python ts=4 sw=4 et si diff --git a/roundup/exceptions.py b/roundup/exceptions.py new file mode 100644 index 0000000..27cc1ef --- /dev/null +++ b/roundup/exceptions.py @@ -0,0 +1,19 @@ +#$Id: exceptions.py,v 1.1 2004-03-26 00:44:11 richard Exp $ +'''Exceptions for use across all Roundup components. +''' + +__docformat__ = 'restructuredtext' + +class Reject(Exception): + '''An auditor may raise this exception when the current create or set + operation should be stopped. + + It is up to the specific interface invoking the create or set to + handle this exception sanely. For example: + + - mailgw will trap and ignore Reject for file attachments and messages + - cgi will trap and present the exception in a nice format + ''' + pass + +# vim: set filetype=python ts=4 sw=4 et si diff --git a/roundup/mailgw.py b/roundup/mailgw.py index d676875..47d0831 100644 --- a/roundup/mailgw.py +++ b/roundup/mailgw.py @@ -72,7 +72,7 @@ are calling the create() method to create a new node). If an auditor raises an exception, the original message is bounced back to the sender with the explanatory message given in the exception. -$Id: mailgw.py,v 1.145 2004-03-25 22:52:12 richard Exp $ +$Id: mailgw.py,v 1.146 2004-03-26 00:44:11 richard Exp $ """ __docformat__ = 'restructuredtext' @@ -80,7 +80,7 @@ import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri import time, random, sys import traceback, MimeWriter, rfc822 -from roundup import hyperdb, date, password, rfc2822 +from roundup import hyperdb, date, password, rfc2822, exceptions from roundup.mailer import Mailer SENDMAILDEBUG = os.environ.get('SENDMAILDEBUG', '') @@ -805,8 +805,13 @@ not find a text/plain part to use. for (name, mime_type, data) in attachments: if not name: name = "unnamed" - files.append(self.db.file.create(type=mime_type, name=name, - content=data, **file_props)) + try: + fileid = self.db.file.create(type=mime_type, name=name, + content=data, **file_props) + except exceptions.Reject: + pass + else: + files.append(fileid) # attach the files to the issue if nodeid: # extend the existing files list @@ -821,20 +826,23 @@ not find a text/plain part to use. # create the message if there's a message body (content) # if (content and properties.has_key('messages')): - message_id = self.db.msg.create(author=author, - recipients=recipients, date=date.Date('.'), summary=summary, - content=content, files=files, messageid=messageid, - inreplyto=inreplyto, **msg_props) - - # attach the message to the node - if nodeid: - # add the message to the node's list - messages = cl.get(nodeid, 'messages') - messages.append(message_id) - props['messages'] = messages + try: + message_id = self.db.msg.create(author=author, + recipients=recipients, date=date.Date('.'), + summary=summary, content=content, files=files, + messageid=messageid, inreplyto=inreplyto, **msg_props) + except exceptions.Reject: + pass else: - # pre-load the messages list - props['messages'] = [message_id] + # attach the message to the node + if nodeid: + # add the message to the node's list + messages = cl.get(nodeid, 'messages') + messages.append(message_id) + props['messages'] = messages + else: + # pre-load the messages list + props['messages'] = [message_id] # # perform the node change / create @@ -948,10 +956,13 @@ def uidFromAddress(db, address, create=1, **user_props): trying = username + str(n) # create! - return db.user.create(username=trying, address=address, - realname=realname, roles=db.config.NEW_EMAIL_USER_ROLES, - password=password.Password(password.generatePassword()), - **user_props) + try: + return db.user.create(username=trying, address=address, + realname=realname, roles=db.config.NEW_EMAIL_USER_ROLES, + password=password.Password(password.generatePassword()), + **user_props) + except exceptions.Reject: + return 0 else: return 0 -- 2.30.2