Mercurial > p > roundup > code
annotate share/roundup/templates/devel/schema.py @ 5548:fea11d05110e
Avoid errors from selecting "no selection" on multilink (issue2550722).
As discussed in issue 2550722 there are various cases where selecting
"no selection" on a multilink can result in inappropriate errors from
Roundup:
* If selecting "no selection" produces a null edit (a value was set in
the multilink in an edit with an error, then removed again, along
with all other changes, in the next form submission), so the page is
rendered from the form contents including the "-<id>" value for "no
selection" for the multilink.
* If creating an item with a nonempty value for a multilink has an
error, and the resubmission changes that multilink to "no selection"
(and this in turn has subcases, according to whether the creation
then succeeds or fails on the resubmission, which need fixes in
different places in the Roundup code).
All of these cases have in common that it is expected and OK to have a
"-<id>" value for a submission for a multilink when <id> is not set in
that multilink in the database (because the original attempt to set
<id> in that multilink had an error), so the hyperdb.py logic to give
an error in that case is thus removed. In the subcase of the second
case where the resubmission with "no selection" has an error, the
templating code tries to produce a menu entry for the "-<id>"
multilink value, which also results in an error, hence the
templating.py change to ignore such values in the list for a
multilink.
| author | Joseph Myers <jsm@polyomino.org.uk> |
|---|---|
| date | Thu, 27 Sep 2018 11:33:01 +0000 |
| parents | 602d544e3a93 |
| children | 94a7669677ae |
| 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') | |
| 208 | |
| 209 ########################## | |
| 210 # User permissions | |
| 211 ########################## | |
| 212 | |
| 213 for cl in ('severity', 'component', | |
| 214 'version', 'priority', 'status', 'resolution', | |
| 215 'bug_type', 'bug', 'task_type', 'task', 'milestone', | |
| 216 'keyword', 'file', 'msg'): | |
| 217 db.security.addPermissionToRole('User', 'View', cl) | |
| 218 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
|
219 |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
220 for cl in ('severity', 'component', |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
221 'version', 'priority', 'status', 'resolution', |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
222 'bug_type', 'bug', 'file', 'msg'): |
| 4434 | 223 db.security.addPermissionToRole('User', 'Create', cl) |
| 224 | |
| 225 | |
| 226 def may_edit_file(db, userid, itemid): | |
| 227 return userid == db.file.get(itemid, "creator") | |
| 228 | |
| 229 p = db.security.addPermission(name='Edit', klass='file', check=may_edit_file, | |
| 230 description="User is allowed to remove their own files") | |
| 231 db.security.addPermissionToRole('User', p) | |
| 232 | |
| 233 p = db.security.addPermission(name='Create', klass='bug', | |
| 234 properties=('title', 'bug_type', | |
| 235 'components', 'versions', | |
| 236 'severity', | |
| 237 'messages', 'files', 'nosy'), | |
| 238 description='User can report and discuss bugs') | |
| 239 db.security.addPermissionToRole('User', p) | |
| 240 | |
| 241 p = db.security.addPermission(name='Edit', klass='bug', | |
| 242 properties=('title', 'bug_type', | |
| 243 'components', 'versions', | |
| 244 'severity', | |
| 245 'messages', 'files', 'nosy'), | |
| 246 description='User can report and discuss bugs') | |
| 247 db.security.addPermissionToRole('User', p) | |
| 248 | |
| 249 p = db.security.addPermission(name='Create', klass='task', | |
| 250 properties=('title', 'task_type', | |
| 251 'components', | |
| 252 'messages', 'files', 'nosy'), | |
| 253 description='Developer can create and discuss tasks') | |
| 254 db.security.addPermissionToRole('Developer', p) | |
| 255 | |
| 256 p = db.security.addPermission(name='Edit', klass='task', | |
| 257 properties=('title', 'task_type', | |
| 258 'components', | |
| 259 'messages', 'files', 'nosy'), | |
| 260 description='Developer can create and discuss tasks') | |
| 261 db.security.addPermissionToRole('Developer', p) | |
| 262 | |
| 263 p = db.security.addPermission(name='Create', klass='milestone', | |
| 264 description='Coordinator can create and discuss milestones') | |
| 265 db.security.addPermissionToRole('Coordinator', p) | |
| 266 | |
| 267 p = db.security.addPermission(name='Edit', klass='milestone', | |
| 268 description='Coordinator can create and discuss milestones') | |
| 269 db.security.addPermissionToRole('Coordinator', p) | |
| 270 | |
| 271 | |
| 272 ########################## | |
| 273 # Developer permissions | |
| 274 ########################## | |
| 275 for cl in ('bug_type', 'severity', 'component', | |
| 276 'version', 'priority', 'status', 'resolution', | |
| 277 'bug', 'file', 'msg', 'keyword'): | |
| 278 db.security.addPermissionToRole('Developer', 'View', cl) | |
| 279 | |
| 280 for cl in ('bug', 'file', 'msg', 'keyword'): | |
| 281 db.security.addPermissionToRole('Developer', 'Edit', cl) | |
| 282 db.security.addPermissionToRole('Developer', 'Create', cl) | |
| 283 | |
| 284 | |
| 285 ########################## | |
| 286 # Coordinator permissions | |
| 287 ########################## | |
| 288 for cl in ('bug_type', 'task_type', 'severity', 'component', | |
| 289 'version', 'priority', 'status', 'resolution', 'bug', 'task', 'file', 'msg'): | |
| 290 db.security.addPermissionToRole('Coordinator', 'View', cl) | |
| 291 db.security.addPermissionToRole('Coordinator', 'Edit', cl) | |
| 292 db.security.addPermissionToRole('Coordinator', 'Create', cl) | |
| 293 | |
| 294 # May users view other user information? Comment these lines out | |
| 295 # if you don't want them to | |
|
4902
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
296 p = db.security.addPermission(name='View', klass='user', |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
297 properties=('id', 'organisation', 'phone', 'realname', 'timezone', |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
298 'vcs_name', 'username')) |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
299 db.security.addPermissionToRole('User', p) |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
300 db.security.addPermissionToRole('Developer', p) |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
301 |
|
a403c29ffaf9
Security fix default user permissions
Ralf Schlatterbeck <rsc@runtux.com>
parents:
4676
diff
changeset
|
302 # Coordinator may also edit users, so they may see everything: |
| 4434 | 303 db.security.addPermissionToRole('Coordinator', 'View', 'user') |
| 304 | |
| 305 # Allow Coordinator to edit any user, including their roles. | |
| 306 db.security.addPermissionToRole('Coordinator', 'Edit', 'user') | |
| 307 db.security.addPermissionToRole('Coordinator', 'Web Roles') | |
| 308 | |
| 309 # Users should be able to edit their own details -- this permission is | |
| 310 # limited to only the situation where the Viewed or Edited item is their own. | |
| 311 def own_record(db, userid, itemid): | |
| 312 '''Determine whether the userid matches the item being accessed.''' | |
| 313 return userid == itemid | |
| 314 p = db.security.addPermission(name='View', klass='user', check=own_record, | |
| 315 description="User is allowed to view their own user details") | |
| 316 for r in 'User', 'Developer', 'Coordinator': | |
| 317 db.security.addPermissionToRole(r, p) | |
| 318 p = db.security.addPermission(name='Edit', klass='user', check=own_record, | |
| 319 description="User is allowed to edit their own user details", | |
| 320 properties=('username', 'password', | |
| 321 'address', 'realname', | |
|
4676
d3f8d0be588c
Issue2550783 - change spelling of organization to organisation so that
rouilj
parents:
4457
diff
changeset
|
322 'phone', 'organisation', |
| 4434 | 323 'alternate_addresses', |
| 324 'queries', | |
| 325 'timezone')) # Note: 'roles' excluded - users should not be able to edit their own roles. | |
| 326 for r in 'User', 'Developer': | |
| 327 db.security.addPermissionToRole(r, p) | |
| 328 | |
| 329 # Users should be able to edit and view their own queries. They should also | |
| 330 # be able to view any marked as not private. They should not be able to | |
| 331 # edit others' queries, even if they're not private | |
| 332 def view_query(db, userid, itemid): | |
| 333 private_for = db.query.get(itemid, 'private_for') | |
| 334 if not private_for: return True | |
| 335 return userid == private_for | |
| 336 def edit_query(db, userid, itemid): | |
| 337 return userid == db.query.get(itemid, 'creator') | |
| 338 p = db.security.addPermission(name='View', klass='query', check=view_query, | |
| 339 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
|
340 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
|
341 db.security.addPermissionToRole('User', p) |
| 4434 | 342 for r in 'User', 'Developer', 'Coordinator': |
| 343 db.security.addPermissionToRole(r, p) | |
| 344 p = db.security.addPermission(name='Edit', klass='query', check=edit_query, | |
| 345 description="User is allowed to edit their queries") | |
| 346 for r in 'User', 'Developer', 'Coordinator': | |
| 347 db.security.addPermissionToRole(r, p) | |
| 348 p = db.security.addPermission(name='Create', klass='query', | |
| 349 description="User is allowed to create queries") | |
| 350 for r in 'User', 'Developer', 'Coordinator': | |
| 351 db.security.addPermissionToRole(r, p) | |
| 352 | |
| 353 | |
| 354 # | |
| 355 # ANONYMOUS USER PERMISSIONS | |
| 356 # | |
| 357 # Let anonymous users access the web interface. Note that almost all | |
| 358 # trackers will need this Permission. The only situation where it's not | |
| 359 # required is in a tracker that uses an HTTP Basic Authenticated front-end. | |
| 360 db.security.addPermissionToRole('Anonymous', 'Web Access') | |
| 361 | |
| 362 # Let anonymous users access the email interface (note that this implies | |
| 363 # that they will be registered automatically, hence they will need the | |
| 364 # "Create" user Permission below) | |
| 365 # This is disabled by default to stop spam from auto-registering users on | |
| 366 # public trackers. | |
| 367 #db.security.addPermissionToRole('Anonymous', 'Email Access') | |
| 368 | |
| 369 # Assign the appropriate permissions to the anonymous user's Anonymous | |
| 370 # Role. Choices here are: | |
| 371 # - Allow anonymous users to register | |
| 372 db.security.addPermissionToRole('Anonymous', 'Create', 'user') | |
| 373 | |
| 374 # Allow anonymous users access to view issues (and the related, linked | |
| 375 # information). | |
| 376 | |
|
4454
cc402f5ad93e
Anonymous can only see bugs, but neither tasks nor milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4437
diff
changeset
|
377 for cl in 'bug', 'severity', 'status', 'resolution', 'msg', 'file': |
| 4434 | 378 db.security.addPermissionToRole('Anonymous', 'View', cl) |
| 379 | |
|
5113
cf112b90fa8d
issue2550855: added search perms for anonymous to the user class.
John Rouillard <rouilj@ieee.org>
parents:
5049
diff
changeset
|
380 # 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
|
381 # 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
|
382 # 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
|
383 # 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
|
384 # 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
|
385 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
|
386 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
|
387 |
| 4434 | 388 # [OPTIONAL] |
| 389 # Allow anonymous users access to create or edit "issue" items (and the | |
| 390 # related file and message items) | |
| 391 #for cl in 'issue', 'file', 'msg': | |
| 392 # db.security.addPermissionToRole('Anonymous', 'Create', cl) | |
| 393 # db.security.addPermissionToRole('Anonymous', 'Edit', cl) | |
| 394 | |
| 395 | |
| 396 # vim: set filetype=python sts=4 sw=4 et si : | |
| 397 |
