Mercurial > p > roundup > code
comparison roundup/xmlrpc.py @ 3973:85cbaa50eba1
xml-rpc security checks and tests across all backends [SF#1907211]
also add some leap year tests
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Fri, 07 Mar 2008 01:11:55 +0000 |
| parents | 3c3077582c16 |
| children | f7f3068b32a1 |
comparison
equal
deleted
inserted
replaced
| 3972:eee76dd4a09f | 3973:85cbaa50eba1 |
|---|---|
| 61 self.db.setCurrentUser(username) | 61 self.db.setCurrentUser(username) |
| 62 | 62 |
| 63 def close(self): | 63 def close(self): |
| 64 """Close the database, after committing any changes, if needed.""" | 64 """Close the database, after committing any changes, if needed.""" |
| 65 | 65 |
| 66 if getattr(self, 'db'): | 66 try: |
| 67 try: | 67 self.db.commit() |
| 68 if self.db.transactions: | 68 finally: |
| 69 self.db.commit() | 69 self.db.close() |
| 70 finally: | |
| 71 self.db.close() | |
| 72 | |
| 73 | 70 |
| 74 def get_class(self, classname): | 71 def get_class(self, classname): |
| 75 """Return the class for the given classname.""" | 72 """Return the class for the given classname.""" |
| 76 | 73 |
| 77 try: | 74 try: |
| 92 raise UsageError, 'argument "%s" not propname=value'%arg | 89 raise UsageError, 'argument "%s" not propname=value'%arg |
| 93 key, value = l[0], '='.join(l[1:]) | 90 key, value = l[0], '='.join(l[1:]) |
| 94 if value: | 91 if value: |
| 95 try: | 92 try: |
| 96 props[key] = hyperdb.rawToHyperdb(self.db, cl, None, | 93 props[key] = hyperdb.rawToHyperdb(self.db, cl, None, |
| 97 key, value) | 94 key, value) |
| 98 except hyperdb.HyperdbValueError, message: | 95 except hyperdb.HyperdbValueError, message: |
| 99 raise UsageError, message | 96 raise UsageError, message |
| 100 else: | 97 else: |
| 101 props[key] = None | 98 props[key] = None |
| 102 | 99 |
| 113 self.tracker = roundup.instance.open(tracker) | 110 self.tracker = roundup.instance.open(tracker) |
| 114 self.verbose = verbose | 111 self.verbose = verbose |
| 115 | 112 |
| 116 def list(self, username, password, classname, propname=None): | 113 def list(self, username, password, classname, propname=None): |
| 117 r = RoundupRequest(self.tracker, username, password) | 114 r = RoundupRequest(self.tracker, username, password) |
| 118 cl = r.get_class(classname) | 115 try: |
| 119 if not propname: | 116 cl = r.get_class(classname) |
| 120 propname = cl.labelprop() | 117 if not propname: |
| 121 def has_perm(itemid): | 118 propname = cl.labelprop() |
| 122 return True | 119 result = [cl.get(itemid, propname) |
| 123 r.db.security.hasPermission('View', r.userid, classname, | 120 for itemid in cl.list() |
| 124 itemid=itemid, property=propname) | 121 if r.db.security.hasPermission('View', r.userid, |
| 125 result = [cl.get(id, propname) for id in cl.list() | 122 classname, propname, itemid) |
| 126 if has_perm(id)] | 123 ] |
| 127 r.close() | 124 finally: |
| 125 r.close() | |
| 128 return result | 126 return result |
| 129 | 127 |
| 130 def display(self, username, password, designator, *properties): | 128 def display(self, username, password, designator, *properties): |
| 131 r = RoundupRequest(self.tracker, username, password) | 129 r = RoundupRequest(self.tracker, username, password) |
| 132 classname, itemid = hyperdb.splitDesignator(designator) | 130 try: |
| 133 | 131 classname, itemid = hyperdb.splitDesignator(designator) |
| 134 if not r.db.security.hasPermission('View', r.userid, classname, | 132 cl = r.get_class(classname) |
| 135 itemid=itemid): | 133 props = properties and list(properties) or cl.properties.keys() |
| 136 raise Unauthorised('Permission to view %s denied'%designator) | 134 props.sort() |
| 137 | 135 for p in props: |
| 138 cl = r.get_class(classname) | 136 if not r.db.security.hasPermission('View', r.userid, |
| 139 props = properties and list(properties) or cl.properties.keys() | 137 classname, p, itemid): |
| 140 props.sort() | 138 raise Unauthorised('Permission to view %s of %s denied'% |
| 141 result = [(property, cl.get(itemid, property)) for property in props] | 139 (p, designator)) |
| 142 r.close() | 140 result = [(prop, cl.get(itemid, prop)) for prop in props] |
| 141 finally: | |
| 142 r.close() | |
| 143 return dict(result) | 143 return dict(result) |
| 144 | 144 |
| 145 def create(self, username, password, classname, *args): | 145 def create(self, username, password, classname, *args): |
| 146 r = RoundupRequest(self.tracker, username, password) | 146 r = RoundupRequest(self.tracker, username, password) |
| 147 try: | |
| 148 if not r.db.security.hasPermission('Create', r.userid, classname): | |
| 149 raise Unauthorised('Permission to create %s denied'%classname) | |
| 147 | 150 |
| 148 if not r.db.security.hasPermission('Create', r.userid, classname): | 151 cl = r.get_class(classname) |
| 149 raise Unauthorised('Permission to create %s denied'%classname) | |
| 150 | 152 |
| 151 cl = r.get_class(classname) | 153 # convert types |
| 154 props = r.props_from_args(cl, args) | |
| 152 | 155 |
| 153 # convert types | 156 # check for the key property |
| 154 props = r.props_from_args(cl, args) | 157 key = cl.getkey() |
| 158 if key and not props.has_key(key): | |
| 159 raise UsageError, 'you must provide the "%s" property.'%key | |
| 155 | 160 |
| 156 # check for the key property | 161 # do the actual create |
| 157 key = cl.getkey() | |
| 158 if key and not props.has_key(key): | |
| 159 raise UsageError, 'you must provide the "%s" property.'%key | |
| 160 | |
| 161 # do the actual create | |
| 162 try: | |
| 163 try: | 162 try: |
| 164 result = cl.create(**props) | 163 result = cl.create(**props) |
| 165 except (TypeError, IndexError, ValueError), message: | 164 except (TypeError, IndexError, ValueError), message: |
| 166 raise UsageError, message | 165 raise UsageError, message |
| 167 finally: | 166 finally: |
| 168 r.close() | 167 r.close() |
| 169 return result | 168 return result |
| 170 | 169 |
| 171 def set(self, username, password, designator, *args): | 170 def set(self, username, password, designator, *args): |
| 172 r = RoundupRequest(self.tracker, username, password) | 171 r = RoundupRequest(self.tracker, username, password) |
| 173 classname, itemid = hyperdb.splitDesignator(designator) | |
| 174 | |
| 175 if not r.db.security.hasPermission('Edit', r.userid, classname, | |
| 176 itemid=itemid): | |
| 177 raise Unauthorised('Permission to edit %s denied'%designator) | |
| 178 | |
| 179 cl = r.get_class(classname) | |
| 180 | |
| 181 # convert types | |
| 182 props = r.props_from_args(cl, args) | |
| 183 try: | 172 try: |
| 173 classname, itemid = hyperdb.splitDesignator(designator) | |
| 174 cl = r.get_class(classname) | |
| 175 props = r.props_from_args(cl, args) # convert types | |
| 176 for p in props.iterkeys (): | |
| 177 if not r.db.security.hasPermission('Edit', r.userid, | |
| 178 classname, p, itemid): | |
| 179 raise Unauthorised('Permission to edit %s of %s denied'% | |
| 180 (p, designator)) | |
| 184 try: | 181 try: |
| 185 cl.set(itemid, **props) | 182 return cl.set(itemid, **props) |
| 186 except (TypeError, IndexError, ValueError), message: | 183 except (TypeError, IndexError, ValueError), message: |
| 187 raise UsageError, message | 184 raise UsageError, message |
| 188 finally: | 185 finally: |
| 189 r.close() | 186 r.close() |
| 190 | 187 |
