Mercurial > p > roundup > code
view roundup/xmlrpc.py @ 3854:f4e8dc583256
Restored subject parser regexp to the string it was before the...
...implementation of customization of it, i.e., the version from
CVS revision 1.184 of mailgw.py.
This makes 'testFollowupTitleMatchMultiRe' work again.
| author | Erik Forsberg <forsberg@users.sourceforge.net> |
|---|---|
| date | Sat, 12 May 2007 16:14:54 +0000 |
| parents | c31da624ae3b |
| children | 3c3077582c16 |
line wrap: on
line source
# # Copyright (C) 2007 Stefan Seefeld # All rights reserved. # For license terms see the file COPYING.txt. # import base64 import roundup.instance from roundup import hyperdb from roundup.cgi.exceptions import * from roundup.admin import UsageError from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler class RoundupRequestHandler(SimpleXMLRPCRequestHandler): """A SimpleXMLRPCRequestHandler with support for basic HTTP Authentication.""" def do_POST(self): """Extract username and password from authorization header.""" # Try to extract username and password from HTTP Authentication. self.username = None self.password = None authorization = self.headers.get('authorization', ' ') scheme, challenge = authorization.split(' ', 1) if scheme.lower() == 'basic': decoded = base64.decodestring(challenge) self.username, self.password = decoded.split(':') SimpleXMLRPCRequestHandler.do_POST(self) def _dispatch(self, method, params): """Inject username and password into function arguments.""" # Add username and password to function arguments params = [self.username, self.password] + list(params) return self.server._dispatch(method, params) class RoundupRequest: """Little helper class to handle common per-request tasks such as authentication and login.""" def __init__(self, tracker, username, password): """Open the database for the given tracker, using the given username and password.""" self.tracker = tracker self.db = self.tracker.open('admin') try: userid = self.db.user.lookup(username) except KeyError: # No such user self.db.close() raise Unauthorised, 'Invalid user.' stored = self.db.user.get(userid, 'password') if stored != password: # Wrong password self.db.close() raise Unauthorised, 'Invalid user.' self.db.setCurrentUser(username) def close(self): """Close the database, after committing any changes, if needed.""" if getattr(self, 'db'): try: if self.db.transactions: self.db.commit() finally: self.db.close() def get_class(self, classname): """Return the class for the given classname.""" try: return self.db.getclass(classname) except KeyError: raise UsageError, 'no such class "%s"'%classname def props_from_args(self, cl, args): """Construct a list of properties from the given arguments, and return them after validation.""" props = {} for arg in args: if arg.find('=') == -1: raise UsageError, 'argument "%s" not propname=value'%arg l = arg.split('=') if len(l) < 2: raise UsageError, 'argument "%s" not propname=value'%arg key, value = l[0], '='.join(l[1:]) if value: try: props[key] = hyperdb.rawToHyperdb(self.db, cl, None, key, value) except hyperdb.HyperdbValueError, message: raise UsageError, message else: props[key] = None return props #The server object class RoundupServer: """The RoundupServer provides the interface accessible through the Python XMLRPC mapping. All methods take an additional username and password argument so each request can be authenticated.""" def __init__(self, tracker, verbose = False): self.tracker = roundup.instance.open(tracker) self.verbose = verbose def list(self, username, password, classname, propname = None): r = RoundupRequest(self.tracker, username, password) cl = r.get_class(classname) if not propname: propname = cl.labelprop() result = [cl.get(id, propname) for id in cl.list()] r.close() return result def display(self, username, password, designator, *properties): r = RoundupRequest(self.tracker, username, password) classname, nodeid = hyperdb.splitDesignator(designator) cl = r.get_class(classname) props = properties and list(properties) or cl.properties.keys() props.sort() result = [(property, cl.get(nodeid, property)) for property in props] r.close() return dict(result) def create(self, username, password, classname, *args): r = RoundupRequest(self.tracker, username, password) cl = r.get_class(classname) # convert types props = r.props_from_args(cl, args) # check for the key property key = cl.getkey() if key and not props.has_key(key): raise UsageError, 'you must provide the "%s" property.'%key # do the actual create try: try: result = cl.create(**props) except (TypeError, IndexError, ValueError), message: raise UsageError, message finally: r.close() return result def set(self, username, password, designator, *args): r = RoundupRequest(self.tracker, username, password) classname, itemid = hyperdb.splitDesignator(designator) cl = r.get_class(classname) # convert types props = r.props_from_args(cl, args) try: try: cl.set(itemid, **props) except (TypeError, IndexError, ValueError), message: raise UsageError, message finally: r.close() # vim: set et sts=4 sw=4 :
