Mercurial > p > roundup > code
annotate share/roundup/templates/devel/schema.py @ 5879:94a7669677ae
add permissions to control user of rest and xmlrpc API interfaces.
issue2551058: Add new permissions: 'Rest Access' and 'Xmlrpc Access'
to allow per-user access control to rest and xmlrpc interfaces using
roles.
Updated all schemas to add these new perms to all authenticated roles.
Error conditions in handle_xmlrpc were not working right in manual
testing. I tried to make it a little better, but I don't actually
understand how the fault xmlrpc object is supposed to be used. So I
may have messed something up. I'll try to ping the people who wrote
the xmlrpc code to have them review.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Fri, 27 Sep 2019 23:29:59 -0400 |
| parents | 602d544e3a93 |
| children | c087ad45bf4d |
| rev | line source |
|---|---|
| 4434 | 1 |
| 2 # | |
| 3 # TRACKER SCHEMA | |
| 4 # | |
| 5 | |
| 6 # Class automatically gets these properties: | |
| 7 # creation = Date() | |
| 8 # activity = Date() | |
| 9 # creator = Link('user') | |
| 10 # actor = Link('user') | |
| 11 | |
| 12 | |
| 13 # This is the repository class, then you can see/edit repositories in pages like | |
| 14 # "http://tracker/url/vcs_repo1" | |
| 15 vcs_repo = Class(db, "vcs_repo", | |
| 16 name=String(), | |
| 17 host=String(), | |
| 18 path=String(), | |
| 19 webview_url=String()) | |
| 20 vcs_repo.setkey('name') | |
| 21 | |
| 22 # Stores revision data, lets you see/edit revisions in pages like | |
| 23 # "http://tracker/url/vcs_rev1". The vcs_rev.item.html template is currently | |
| 24 # broken, but this works fine without it. | |
| 25 vcs_rev = Class(db, "vcs_rev", | |
| 26 repository=Link('vcs_repo'), | |
| 27 revision=String()) | |
| 28 | |
| 29 | |
| 30 | |
| 31 # Component | |
| 32 component = Class(db, 'component', | |
| 33 name=String(), | |
| 34 description=String(), | |
| 35 order=Number(), | |
| 36 assign_to=Link('user')) | |
| 37 component.setkey('name') | |
| 38 | |
| 39 # Version | |
| 40 version = Class(db, 'version', | |
| 41 name=String(), | |
| 42 description=String(), | |
| 43 order=Number()) | |
| 44 version.setkey('name') | |
| 45 | |
| 46 # Severity | |
| 47 severity = Class(db, 'severity', | |
| 48 name=String(), | |
| 49 description=String(), | |
| 50 order=Number()) | |
| 51 severity.setkey('name') | |
| 52 | |
| 53 # Priority | |
| 54 priority = Class(db, 'priority', | |
| 55 name=String(), | |
| 56 description=String(), | |
| 57 order=Number()) | |
| 58 priority.setkey('name') | |
| 59 | |
| 60 # Status | |
| 61 status = Class(db, "status", | |
| 62 name=String(), | |
| 63 description=String(), | |
| 64 order=Number()) | |
| 65 status.setkey("name") | |
| 66 | |
| 67 # Resolution | |
| 68 resolution = Class(db, "resolution", | |
| 69 name=String(), | |
| 70 description=String(), | |
| 71 order=Number()) | |
| 72 resolution.setkey('name') | |
| 73 | |
| 74 # Keyword | |
| 75 keyword = Class(db, "keyword", | |
| 76 name=String(), | |
| 77 description=String()) | |
| 78 keyword.setkey("name") | |
| 79 | |
| 80 | |
| 81 # User-defined saved searches | |
| 82 query = Class(db, "query", | |
| 83 klass=String(), | |
| 84 name=String(), | |
| 85 url=String(), | |
| 86 private_for=Link('user')) | |
| 87 | |
| 88 # add any additional database schema configuration here | |
| 89 | |
| 90 user = Class(db, "user", | |
| 91 username=String(), | |
| 92 password=Password(), | |
| 93 address=String(), | |
| 94 realname=String(), | |
| 95 phone=String(), | |
| 96 organisation=String(), | |
| 97 alternate_addresses=String(), | |
| 98 queries=Multilink('query'), | |
| 99 roles=String(), # comma-separated string of Role names | |
| 100 timezone=String(), | |
| 101 vcs_name=String()) | |
| 102 | |
| 103 user.setkey("username") | |
| 104 | |
| 105 # Permissions for revision creation and repository viewing. | |
| 106 for role in ('User',): | |
| 107 db.security.addPermissionToRole(role, 'Create', 'vcs_rev') | |
| 108 db.security.addPermissionToRole(role, 'View', 'vcs_repo') | |
| 109 | |
| 110 # FileClass automatically gets this property in addition to the Class ones: | |
| 111 # content = String() [saved to disk in <tracker home>/db/files/] | |
| 112 # type = String() [MIME type of the content, default 'text/plain'] | |
| 113 msg = FileClass(db, "msg", | |
| 114 author=Link("user", do_journal='no'), | |
| 115 recipients=Multilink("user", do_journal='no'), | |
| 116 date=Date(), | |
| 117 summary=String(), | |
| 118 files=Multilink("file"), | |
| 119 messageid=String(), | |
| 120 inreplyto=String(), | |
| 121 revision=Link("vcs_rev")) | |
| 122 | |
| 123 # File | |
| 124 file = FileClass(db, "file", | |
| 125 name=String(), | |
| 126 description=String(indexme='yes')) | |
| 127 | |
| 128 # Patch | |
|
5136
602d544e3a93
fixing some mismatched patches/patch references that I borked in a prior checkin. Patch support was not and still is not working. But at least this tracker runs without errors with demo.py -t devel, just missing features.
John Rouillard <rouilj@ieee.org>
parents:
5134
diff
changeset
|
129 patches = FileClass(db, "patches", |
| 4434 | 130 name=String(), |
| 131 description=String(indexme='yes'), | |
| 132 repository=String(), | |
| 133 revision=String()) | |
| 134 | |
| 135 # Bug Type | |
| 136 bug_type = Class(db, 'bug_type', | |
| 137 name=String(), | |
| 138 description=String(), | |
| 139 order=Number()) | |
| 140 bug_type.setkey('name') | |
| 141 | |
| 142 # IssueClass automatically gets these properties in addition to the Class ones: | |
| 143 # title = String() | |
| 144 # messages = Multilink("msg") | |
| 145 # files = Multilink("file") | |
| 146 # patches = Multilink("patches") | |
| 147 # nosy = Multilink("user") | |
| 148 # superseder = Multilink("issue") | |
| 149 bug = IssueClass(db, "bug", | |
| 150 type=Link('bug_type'), | |
| 151 components=Multilink('component'), | |
| 152 versions=Multilink('version'), | |
| 153 severity=Link('severity'), | |
| 154 priority=Link('priority'), | |
| 155 dependencies=Multilink('bug'), | |
| 156 assignee=Link('user'), | |
| 157 status=Link('status'), | |
| 158 resolution=Link('resolution'), | |
| 159 superseder=Link('bug'), | |
|
5049
29bd12331b86
issue2550601: add multilink to patches to the bug issue. The doc string above the definition already included the code.
John Rouillard <rouilj@ieee.org>
parents:
4902
diff
changeset
|
160 keywords=Multilink('keyword'), |
|
29bd12331b86
issue2550601: add multilink to patches to the bug issue. The doc string above the definition already included the code.
John Rouillard <rouilj@ieee.org>
parents:
4902
diff
changeset
|
161 patches=Multilink('patches')) |
| 4434 | 162 |
| 163 # Task Type | |
| 164 task_type = Class(db, 'task_type', | |
| 165 name=String(), | |
| 166 description=String(), | |
| 167 order=Number()) | |
| 168 task_type.setkey('name') | |
| 169 | |
| 170 # IssueClass automatically gets these properties in addition to the Class ones: | |
| 171 # title = String() | |
| 172 # messages = Multilink("msg") | |
| 173 # files = Multilink("file") | |
| 174 # nosy = Multilink("user") | |
| 175 # superseder = Multilink("issue") | |
| 176 task = IssueClass(db, "task", | |
| 177 type=Link('task_type'), | |
| 178 components=Multilink('component'), | |
| 179 priority=Link('priority'), | |
| 180 dependencies=Multilink('task'), | |
| 181 assignee=Multilink('user'), | |
| 182 status=Link('status'), | |
| 183 resolution=Link('resolution'), | |
| 184 solves=Link('bug')) | |
| 185 | |
| 186 milestone = IssueClass(db, "milestone", | |
| 187 bugs=Multilink("bug"), | |
| 188 tasks=Multilink("task"), | |
| 189 status=Link("status"), | |
| 190 release_date=String()) | |
| 191 | |
| 192 # | |
| 193 # TRACKER SECURITY SETTINGS | |
| 194 # | |
| 195 # See the configuration and customisation document for information | |
| 196 # about security setup. | |
| 197 | |
| 198 db.security.addRole(name='Developer', description='A developer') | |
| 199 db.security.addRole(name='Coordinator', description='A coordinator') | |
| 200 | |
| 201 # | |
| 202 # REGULAR USERS | |
| 203 # | |
| 204 # Give the regular users access to the web and email interface | |
| 205 for r in 'User', 'Developer', 'Coordinator': | |
| 206 db.security.addPermissionToRole(r, 'Web Access') | |
| 207 db.security.addPermissionToRole(r, 'Email Access') | |
|
5879
94a7669677ae
add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents:
5136
diff
changeset
|
208 db.security.addPermissionToRole(r, 'Rest Access') |
|
94a7669677ae
add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents:
5136
diff
changeset
|
209 db.security.addPermissionToRole(r, 'Xmlrpc Access') |
|
94a7669677ae
add permissions to control user of rest and xmlrpc API interfaces.
John Rouillard <rouilj@ieee.org>
parents:
5136
diff
changeset
|
210 |
| 4434 | 211 ########################## |
| 212 # User permissions | |
| 213 ########################## | |
| 214 | |
| 215 for cl in ('severity', 'component', | |
| 216 'version', 'priority', 'status', 'resolution', | |
| 217 'bug_type', 'bug', 'task_type', 'task', 'milestone', | |
| 218 'keyword', 'file', 'msg'): | |
| 219 db.security.addPermissionToRole('User', 'View', cl) | |
| 220 db.security.addPermissionToRole('Anonymous', 'View', cl) | |
|
4457
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
221 |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
222 for cl in ('severity', 'component', |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
223 'version', 'priority', 'status', 'resolution', |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
224 'bug_type', 'bug', 'file', 'msg'): |
| 4434 | 225 db.security.addPermissionToRole('User', 'Create', cl) |
| 226 | |
| 227 | |
| 228 def may_edit_file(db, userid, itemid): | |
| 229 return userid == db.file.get(itemid, "creator") | |
| 230 | |
| 231 p = db.security.addPermission(name='Edit', klass='file', check=may_edit_file, | |
| 232 description="User is allowed to remove their own files") | |
| 233 db.security.addPermissionToRole('User', p) | |
| 234 | |
| 235 p = db.security.addPermission(name='Create', klass='bug', | |
| 236 properties=('title', 'bug_type', | |
| 237 'components', 'versions', | |
| 238 'severity', | |
| 239 'messages', 'files', 'nosy'), | |
| 240 description='User can report and discuss bugs') | |
| 241 db.security.addPermissionToRole('User', p) | |
| 242 | |
| 243 p = db.security.addPermission(name='Edit', klass='bug', | |
| 244 properties=('title', 'bug_type', | |
| 245 'components', 'versions', | |
| 246 'severity', | |
| 247 'messages', 'files', 'nosy'), | |
| 248 description='User can report and discuss bugs') | |
| 249 db.security.addPermissionToRole('User', p) | |
| 250 | |
| 251 p = db.security.addPermission(name='Create', klass='task', | |
| 252 properties=('title', 'task_type', | |
| 253 'components', | |
| 254 'messages', 'files', 'nosy'), | |
| 255 description='Developer can create and discuss tasks') | |
| 256 db.security.addPermissionToRole('Developer', p) | |
| 257 | |
| 258 p = db.security.addPermission(name='Edit', klass='task', | |
| 259 properties=('title', 'task_type', | |
| 260 'components', | |
| 261 'messages', 'files', 'nosy'), | |
| 262 description='Developer can create and discuss tasks') | |
| 263 db.security.addPermissionToRole('Developer', p) | |
| 264 | |
| 265 p = db.security.addPermission(name='Create', klass='milestone', | |
| 266 description='Coordinator can create and discuss milestones') | |
| 267 db.security.addPermissionToRole('Coordinator', p) | |
| 268 | |
| 269 p = db.security.addPermission(name='Edit', klass='milestone', | |
| 270 description='Coordinator can create and discuss milestones') | |
| 271 db.security.addPermissionToRole('Coordinator', p) | |
| 272 | |
| 273 | |
| 274 ########################## | |
| 275 # Developer permissions | |
| 276 ########################## | |
| 277 for cl in ('bug_type', 'severity', 'component', | |
| 278 'version', 'priority', 'status', 'resolution', | |
| 279 'bug', 'file', 'msg', 'keyword'): | |
| 280 db.security.addPermissionToRole('Developer', 'View', cl) | |
| 281 | |
| 282 for cl in ('bug', 'file', 'msg', 'keyword'): | |
| 283 db.security.addPermissionToRole('Developer', 'Edit', cl) | |
| 284 db.security.addPermissionToRole('Developer', 'Create', cl) | |
| 285 | |
| 286 | |
| 287 ########################## | |
| 288 # Coordinator permissions | |
| 289 ########################## | |
| 290 for cl in ('bug_type', 'task_type', 'severity', 'component', | |
| 291 'version', 'priority', 'status', 'resolution', 'bug', 'task', 'file', 'msg'): | |
| 292 db.security.addPermissionToRole('Coordinator', 'View', cl) | |
| 293 db.security.addPermissionToRole('Coordinator', 'Edit', cl) | |
| 294 db.security.addPermissionToRole('Coordinator', 'Create', cl) | |
| 295 | |
| 296 # May users view other user information? Comment these lines out | |
| 297 # if you don't want them to | |
|
4902
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
298 p = db.security.addPermission(name='View', klass='user', |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
299 properties=('id', 'organisation', 'phone', 'realname', 'timezone', |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
300 'vcs_name', 'username')) |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
301 db.security.addPermissionToRole('User', p) |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
302 db.security.addPermissionToRole('Developer', p) |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
303 |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
304 # Coordinator may also edit users, so they may see everything: |
| 4434 | 305 db.security.addPermissionToRole('Coordinator', 'View', 'user') |
| 306 | |
| 307 # Allow Coordinator to edit any user, including their roles. | |
| 308 db.security.addPermissionToRole('Coordinator', 'Edit', 'user') | |
| 309 db.security.addPermissionToRole('Coordinator', 'Web Roles') | |
| 310 | |
| 311 # Users should be able to edit their own details -- this permission is | |
| 312 # limited to only the situation where the Viewed or Edited item is their own. | |
| 313 def own_record(db, userid, itemid): | |
| 314 '''Determine whether the userid matches the item being accessed.''' | |
| 315 return userid == itemid | |
| 316 p = db.security.addPermission(name='View', klass='user', check=own_record, | |
| 317 description="User is allowed to view their own user details") | |
| 318 for r in 'User', 'Developer', 'Coordinator': | |
| 319 db.security.addPermissionToRole(r, p) | |
| 320 p = db.security.addPermission(name='Edit', klass='user', check=own_record, | |
| 321 description="User is allowed to edit their own user details", | |
| 322 properties=('username', 'password', | |
| 323 'address', 'realname', | |
|
4676
d3f8d0be588c
Issue2550783 - change spelling of organization to organisation so that
rouilj
parents:
4457
diff
changeset
|
324 'phone', 'organisation', |
| 4434 | 325 'alternate_addresses', |
| 326 'queries', | |
| 327 'timezone')) # Note: 'roles' excluded - users should not be able to edit their own roles. | |
| 328 for r in 'User', 'Developer': | |
| 329 db.security.addPermissionToRole(r, p) | |
| 330 | |
| 331 # Users should be able to edit and view their own queries. They should also | |
| 332 # be able to view any marked as not private. They should not be able to | |
| 333 # edit others' queries, even if they're not private | |
| 334 def view_query(db, userid, itemid): | |
| 335 private_for = db.query.get(itemid, 'private_for') | |
| 336 if not private_for: return True | |
| 337 return userid == private_for | |
| 338 def edit_query(db, userid, itemid): | |
| 339 return userid == db.query.get(itemid, 'creator') | |
| 340 p = db.security.addPermission(name='View', klass='query', check=view_query, | |
| 341 description="User is allowed to view their own and public queries") | |
|
4437
261c9f913ff7
- Add explicit "Search" permissions, see Security Fix below.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents:
4434
diff
changeset
|
342 p = db.security.addPermission(name='Search', klass='query') |
|
261c9f913ff7
- Add explicit "Search" permissions, see Security Fix below.
Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
parents:
4434
diff
changeset
|
343 db.security.addPermissionToRole('User', p) |
| 4434 | 344 for r in 'User', 'Developer', 'Coordinator': |
| 345 db.security.addPermissionToRole(r, p) | |
| 346 p = db.security.addPermission(name='Edit', klass='query', check=edit_query, | |
| 347 description="User is allowed to edit their queries") | |
| 348 for r in 'User', 'Developer', 'Coordinator': | |
| 349 db.security.addPermissionToRole(r, p) | |
| 350 p = db.security.addPermission(name='Create', klass='query', | |
| 351 description="User is allowed to create queries") | |
| 352 for r in 'User', 'Developer', 'Coordinator': | |
| 353 db.security.addPermissionToRole(r, p) | |
| 354 | |
| 355 | |
| 356 # | |
| 357 # ANONYMOUS USER PERMISSIONS | |
| 358 # | |
| 359 # Let anonymous users access the web interface. Note that almost all | |
| 360 # trackers will need this Permission. The only situation where it's not | |
| 361 # required is in a tracker that uses an HTTP Basic Authenticated front-end. | |
| 362 db.security.addPermissionToRole('Anonymous', 'Web Access') | |
| 363 | |
| 364 # Let anonymous users access the email interface (note that this implies | |
| 365 # that they will be registered automatically, hence they will need the | |
| 366 # "Create" user Permission below) | |
| 367 # This is disabled by default to stop spam from auto-registering users on | |
| 368 # public trackers. | |
| 369 #db.security.addPermissionToRole('Anonymous', 'Email Access') | |
| 370 | |
| 371 # Assign the appropriate permissions to the anonymous user's Anonymous | |
| 372 # Role. Choices here are: | |
| 373 # - Allow anonymous users to register | |
| 374 db.security.addPermissionToRole('Anonymous', 'Create', 'user') | |
| 375 | |
| 376 # Allow anonymous users access to view issues (and the related, linked | |
| 377 # information). | |
| 378 | |
|
4454
cc402f5ad93e
Anonymous can only see bugs, but neither tasks nor milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4437
diff
changeset
|
379 for cl in 'bug', 'severity', 'status', 'resolution', 'msg', 'file': |
| 4434 | 380 db.security.addPermissionToRole('Anonymous', 'View', cl) |
| 381 | |
|
5113
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
382 # Allow the anonymous user to use the "Show Unassigned" search. |
|
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
383 # It acts like "Show Open" if this permission is not available. |
|
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
384 # If you are running a tracker that does not allow read access for |
|
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
385 # anonymous, you should remove this entry as it can be used to perform |
|
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
386 # a username guessing attack against a roundup install. |
|
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
387 p = db.security.addPermission(name='Search', klass='user') |
|
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
388 db.security.addPermissionToRole ('Anonymous', p) |
|
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
389 |
| 4434 | 390 # [OPTIONAL] |
| 391 # Allow anonymous users access to create or edit "issue" items (and the | |
| 392 # related file and message items) | |
| 393 #for cl in 'issue', 'file', 'msg': | |
| 394 # db.security.addPermissionToRole('Anonymous', 'Create', cl) | |
| 395 # db.security.addPermissionToRole('Anonymous', 'Edit', cl) | |
| 396 | |
| 397 | |
| 398 # vim: set filetype=python sts=4 sw=4 et si : | |
| 399 |
