Mercurial > p > roundup > code
annotate roundup/xmlrpc.py @ 3937:3c3077582c16
Add security checks and tests for xmlrpc interface.
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Sat, 03 Nov 2007 00:50:38 +0000 |
| parents | c31da624ae3b |
| children | 85cbaa50eba1 |
| rev | line source |
|---|---|
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
1 # |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
2 # Copyright (C) 2007 Stefan Seefeld |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
3 # All rights reserved. |
| 3839 | 4 # For license terms see the file COPYING.txt. |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
5 # |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
6 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
7 import base64 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
8 import roundup.instance |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
9 from roundup import hyperdb |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
10 from roundup.cgi.exceptions import * |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
11 from roundup.admin import UsageError |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
12 from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
13 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
14 class RoundupRequestHandler(SimpleXMLRPCRequestHandler): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
15 """A SimpleXMLRPCRequestHandler with support for basic |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
16 HTTP Authentication.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
17 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
18 def do_POST(self): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
19 """Extract username and password from authorization header.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
20 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
21 # Try to extract username and password from HTTP Authentication. |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
22 self.username = None |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
23 self.password = None |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
24 authorization = self.headers.get('authorization', ' ') |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
25 scheme, challenge = authorization.split(' ', 1) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
26 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
27 if scheme.lower() == 'basic': |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
28 decoded = base64.decodestring(challenge) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
29 self.username, self.password = decoded.split(':') |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
30 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
31 SimpleXMLRPCRequestHandler.do_POST(self) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
32 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
33 def _dispatch(self, method, params): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
34 """Inject username and password into function arguments.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
35 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
36 # Add username and password to function arguments |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
37 params = [self.username, self.password] + list(params) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
38 return self.server._dispatch(method, params) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
39 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
40 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
41 class RoundupRequest: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
42 """Little helper class to handle common per-request tasks such |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
43 as authentication and login.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
44 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
45 def __init__(self, tracker, username, password): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
46 """Open the database for the given tracker, using the given |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
47 username and password.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
48 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
49 self.tracker = tracker |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
50 self.db = self.tracker.open('admin') |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
51 try: |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
52 self.userid = self.db.user.lookup(username) |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
53 except KeyError: # No such user |
|
3841
c31da624ae3b
fix RoundupRequest:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3840
diff
changeset
|
54 self.db.close() |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
55 raise Unauthorised, 'Invalid user' |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
56 stored = self.db.user.get(self.userid, 'password') |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
57 if stored != password: |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
58 # Wrong password |
|
3841
c31da624ae3b
fix RoundupRequest:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3840
diff
changeset
|
59 self.db.close() |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
60 raise Unauthorised, 'Invalid user' |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
61 self.db.setCurrentUser(username) |
|
3840
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
62 |
| 3839 | 63 def close(self): |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
64 """Close the database, after committing any changes, if needed.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
65 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
66 if getattr(self, 'db'): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
67 try: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
68 if self.db.transactions: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
69 self.db.commit() |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
70 finally: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
71 self.db.close() |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
72 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
73 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
74 def get_class(self, classname): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
75 """Return the class for the given classname.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
76 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
77 try: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
78 return self.db.getclass(classname) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
79 except KeyError: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
80 raise UsageError, 'no such class "%s"'%classname |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
81 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
82 def props_from_args(self, cl, args): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
83 """Construct a list of properties from the given arguments, |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
84 and return them after validation.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
85 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
86 props = {} |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
87 for arg in args: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
88 if arg.find('=') == -1: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
89 raise UsageError, 'argument "%s" not propname=value'%arg |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
90 l = arg.split('=') |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
91 if len(l) < 2: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
92 raise UsageError, 'argument "%s" not propname=value'%arg |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
93 key, value = l[0], '='.join(l[1:]) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
94 if value: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
95 try: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
96 props[key] = hyperdb.rawToHyperdb(self.db, cl, None, |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
97 key, value) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
98 except hyperdb.HyperdbValueError, message: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
99 raise UsageError, message |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
100 else: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
101 props[key] = None |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
102 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
103 return props |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
104 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
105 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
106 #The server object |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
107 class RoundupServer: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
108 """The RoundupServer provides the interface accessible through |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
109 the Python XMLRPC mapping. All methods take an additional username |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
110 and password argument so each request can be authenticated.""" |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
111 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
112 def __init__(self, tracker, verbose = False): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
113 self.tracker = roundup.instance.open(tracker) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
114 self.verbose = verbose |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
115 |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
116 def list(self, username, password, classname, propname=None): |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
117 r = RoundupRequest(self.tracker, username, password) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
118 cl = r.get_class(classname) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
119 if not propname: |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
120 propname = cl.labelprop() |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
121 def has_perm(itemid): |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
122 return True |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
123 r.db.security.hasPermission('View', r.userid, classname, |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
124 itemid=itemid, property=propname) |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
125 result = [cl.get(id, propname) for id in cl.list() |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
126 if has_perm(id)] |
| 3839 | 127 r.close() |
| 128 return result | |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
129 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
130 def display(self, username, password, designator, *properties): |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
131 r = RoundupRequest(self.tracker, username, password) |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
132 classname, itemid = hyperdb.splitDesignator(designator) |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
133 |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
134 if not r.db.security.hasPermission('View', r.userid, classname, |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
135 itemid=itemid): |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
136 raise Unauthorised('Permission to view %s denied'%designator) |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
137 |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
138 cl = r.get_class(classname) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
139 props = properties and list(properties) or cl.properties.keys() |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
140 props.sort() |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
141 result = [(property, cl.get(itemid, property)) for property in props] |
| 3839 | 142 r.close() |
| 143 return dict(result) | |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
144 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
145 def create(self, username, password, classname, *args): |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
146 r = RoundupRequest(self.tracker, username, password) |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
147 |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
148 if not r.db.security.hasPermission('Create', r.userid, classname): |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
149 raise Unauthorised('Permission to create %s denied'%classname) |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
150 |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
151 cl = r.get_class(classname) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
152 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
153 # convert types |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
154 props = r.props_from_args(cl, args) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
155 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
156 # check for the key property |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
157 key = cl.getkey() |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
158 if key and not props.has_key(key): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
159 raise UsageError, 'you must provide the "%s" property.'%key |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
160 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
161 # do the actual create |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
162 try: |
|
3840
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
163 try: |
|
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
164 result = cl.create(**props) |
|
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
165 except (TypeError, IndexError, ValueError), message: |
|
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
166 raise UsageError, message |
| 3839 | 167 finally: |
| 168 r.close() | |
| 169 return result | |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
170 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
171 def set(self, username, password, designator, *args): |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
172 r = RoundupRequest(self.tracker, username, password) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
173 classname, itemid = hyperdb.splitDesignator(designator) |
|
3937
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
174 |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
175 if not r.db.security.hasPermission('Edit', r.userid, classname, |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
176 itemid=itemid): |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
177 raise Unauthorised('Permission to edit %s denied'%designator) |
|
3c3077582c16
Add security checks and tests for xmlrpc interface.
Richard Jones <richard@users.sourceforge.net>
parents:
3841
diff
changeset
|
178 |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
179 cl = r.get_class(classname) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
180 |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
181 # convert types |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
182 props = r.props_from_args(cl, args) |
|
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
183 try: |
|
3840
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
184 try: |
|
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
185 cl.set(itemid, **props) |
|
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
186 except (TypeError, IndexError, ValueError), message: |
|
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
187 raise UsageError, message |
| 3839 | 188 finally: |
| 189 r.close() | |
|
3828
ba6ba8d6bcc1
Initial checkin for new xmlrpc frontend.
Stefan Seefeld <stefan@seefeld.name>
parents:
diff
changeset
|
190 |
|
3840
9596a516d78c
fix compatibility with Python2.3:
Alexander Smishlajev <a1s@users.sourceforge.net>
parents:
3839
diff
changeset
|
191 # vim: set et sts=4 sw=4 : |
