Mercurial > p > roundup > code
annotate share/roundup/templates/devel/schema.py @ 4880:ca692423e401
Different approach to fix XSS in issue2550817
Encapsulate the error/ok message append method as add_ok_message and
add_error_message. The new approach escapes the messages when appending
-- at a point in the code where we still know where the message comes
from. Escaping is the default but can bei turned off. This also fixes
issue2550836 where certain messages may contain links.
Another advantage of the new fix is that users don't need to change
installed trackers and are secure by default.
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Mon, 31 Mar 2014 18:19:23 +0200 |
| parents | d3f8d0be588c |
| children | a403c29ffaf9 |
| 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 | |
| 129 patch = FileClass(db, "patch", | |
| 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'), | |
| 160 keywords=Multilink('keyword')) | |
| 161 | |
| 162 # Task Type | |
| 163 task_type = Class(db, 'task_type', | |
| 164 name=String(), | |
| 165 description=String(), | |
| 166 order=Number()) | |
| 167 task_type.setkey('name') | |
| 168 | |
| 169 # IssueClass automatically gets these properties in addition to the Class ones: | |
| 170 # title = String() | |
| 171 # messages = Multilink("msg") | |
| 172 # files = Multilink("file") | |
| 173 # nosy = Multilink("user") | |
| 174 # superseder = Multilink("issue") | |
| 175 task = IssueClass(db, "task", | |
| 176 type=Link('task_type'), | |
| 177 components=Multilink('component'), | |
| 178 priority=Link('priority'), | |
| 179 dependencies=Multilink('task'), | |
| 180 assignee=Multilink('user'), | |
| 181 status=Link('status'), | |
| 182 resolution=Link('resolution'), | |
| 183 solves=Link('bug')) | |
| 184 | |
| 185 milestone = IssueClass(db, "milestone", | |
| 186 bugs=Multilink("bug"), | |
| 187 tasks=Multilink("task"), | |
| 188 status=Link("status"), | |
| 189 release_date=String()) | |
| 190 | |
| 191 # | |
| 192 # TRACKER SECURITY SETTINGS | |
| 193 # | |
| 194 # See the configuration and customisation document for information | |
| 195 # about security setup. | |
| 196 | |
| 197 db.security.addRole(name='Developer', description='A developer') | |
| 198 db.security.addRole(name='Coordinator', description='A coordinator') | |
| 199 | |
| 200 # | |
| 201 # REGULAR USERS | |
| 202 # | |
| 203 # Give the regular users access to the web and email interface | |
| 204 for r in 'User', 'Developer', 'Coordinator': | |
| 205 db.security.addPermissionToRole(r, 'Web Access') | |
| 206 db.security.addPermissionToRole(r, 'Email Access') | |
| 207 | |
| 208 ########################## | |
| 209 # User permissions | |
| 210 ########################## | |
| 211 | |
| 212 for cl in ('severity', 'component', | |
| 213 'version', 'priority', 'status', 'resolution', | |
| 214 'bug_type', 'bug', 'task_type', 'task', 'milestone', | |
| 215 'keyword', 'file', 'msg'): | |
| 216 db.security.addPermissionToRole('User', 'View', cl) | |
| 217 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
|
218 |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
219 for cl in ('severity', 'component', |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
220 'version', 'priority', 'status', 'resolution', |
|
89dd446af2a8
Don't allow users to create tasks and milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4454
diff
changeset
|
221 'bug_type', 'bug', 'file', 'msg'): |
| 4434 | 222 db.security.addPermissionToRole('User', 'Create', cl) |
| 223 | |
| 224 | |
| 225 def may_edit_file(db, userid, itemid): | |
| 226 return userid == db.file.get(itemid, "creator") | |
| 227 | |
| 228 p = db.security.addPermission(name='Edit', klass='file', check=may_edit_file, | |
| 229 description="User is allowed to remove their own files") | |
| 230 db.security.addPermissionToRole('User', p) | |
| 231 | |
| 232 p = db.security.addPermission(name='Create', klass='bug', | |
| 233 properties=('title', 'bug_type', | |
| 234 'components', 'versions', | |
| 235 'severity', | |
| 236 'messages', 'files', 'nosy'), | |
| 237 description='User can report and discuss bugs') | |
| 238 db.security.addPermissionToRole('User', p) | |
| 239 | |
| 240 p = db.security.addPermission(name='Edit', klass='bug', | |
| 241 properties=('title', 'bug_type', | |
| 242 'components', 'versions', | |
| 243 'severity', | |
| 244 'messages', 'files', 'nosy'), | |
| 245 description='User can report and discuss bugs') | |
| 246 db.security.addPermissionToRole('User', p) | |
| 247 | |
| 248 p = db.security.addPermission(name='Create', klass='task', | |
| 249 properties=('title', 'task_type', | |
| 250 'components', | |
| 251 'messages', 'files', 'nosy'), | |
| 252 description='Developer can create and discuss tasks') | |
| 253 db.security.addPermissionToRole('Developer', p) | |
| 254 | |
| 255 p = db.security.addPermission(name='Edit', klass='task', | |
| 256 properties=('title', 'task_type', | |
| 257 'components', | |
| 258 'messages', 'files', 'nosy'), | |
| 259 description='Developer can create and discuss tasks') | |
| 260 db.security.addPermissionToRole('Developer', p) | |
| 261 | |
| 262 p = db.security.addPermission(name='Create', klass='milestone', | |
| 263 description='Coordinator can create and discuss milestones') | |
| 264 db.security.addPermissionToRole('Coordinator', p) | |
| 265 | |
| 266 p = db.security.addPermission(name='Edit', klass='milestone', | |
| 267 description='Coordinator can create and discuss milestones') | |
| 268 db.security.addPermissionToRole('Coordinator', p) | |
| 269 | |
| 270 | |
| 271 ########################## | |
| 272 # Developer permissions | |
| 273 ########################## | |
| 274 for cl in ('bug_type', 'severity', 'component', | |
| 275 'version', 'priority', 'status', 'resolution', | |
| 276 'bug', 'file', 'msg', 'keyword'): | |
| 277 db.security.addPermissionToRole('Developer', 'View', cl) | |
| 278 | |
| 279 for cl in ('bug', 'file', 'msg', 'keyword'): | |
| 280 db.security.addPermissionToRole('Developer', 'Edit', cl) | |
| 281 db.security.addPermissionToRole('Developer', 'Create', cl) | |
| 282 | |
| 283 | |
| 284 ########################## | |
| 285 # Coordinator permissions | |
| 286 ########################## | |
| 287 for cl in ('bug_type', 'task_type', 'severity', 'component', | |
| 288 'version', 'priority', 'status', 'resolution', 'bug', 'task', 'file', 'msg'): | |
| 289 db.security.addPermissionToRole('Coordinator', 'View', cl) | |
| 290 db.security.addPermissionToRole('Coordinator', 'Edit', cl) | |
| 291 db.security.addPermissionToRole('Coordinator', 'Create', cl) | |
| 292 | |
| 293 # May users view other user information? Comment these lines out | |
| 294 # if you don't want them to | |
| 295 db.security.addPermissionToRole('User', 'View', 'user') | |
| 296 db.security.addPermissionToRole('Developer', 'View', 'user') | |
| 297 db.security.addPermissionToRole('Coordinator', 'View', 'user') | |
| 298 | |
| 299 # Allow Coordinator to edit any user, including their roles. | |
| 300 db.security.addPermissionToRole('Coordinator', 'Edit', 'user') | |
| 301 db.security.addPermissionToRole('Coordinator', 'Web Roles') | |
| 302 | |
| 303 # Users should be able to edit their own details -- this permission is | |
| 304 # limited to only the situation where the Viewed or Edited item is their own. | |
| 305 def own_record(db, userid, itemid): | |
| 306 '''Determine whether the userid matches the item being accessed.''' | |
| 307 return userid == itemid | |
| 308 p = db.security.addPermission(name='View', klass='user', check=own_record, | |
| 309 description="User is allowed to view their own user details") | |
| 310 for r in 'User', 'Developer', 'Coordinator': | |
| 311 db.security.addPermissionToRole(r, p) | |
| 312 p = db.security.addPermission(name='Edit', klass='user', check=own_record, | |
| 313 description="User is allowed to edit their own user details", | |
| 314 properties=('username', 'password', | |
| 315 'address', 'realname', | |
|
4676
d3f8d0be588c
Issue2550783 - change spelling of organization to organisation so that
rouilj
parents:
4457
diff
changeset
|
316 'phone', 'organisation', |
| 4434 | 317 'alternate_addresses', |
| 318 'queries', | |
| 319 'timezone')) # Note: 'roles' excluded - users should not be able to edit their own roles. | |
| 320 for r in 'User', 'Developer': | |
| 321 db.security.addPermissionToRole(r, p) | |
| 322 | |
| 323 # Users should be able to edit and view their own queries. They should also | |
| 324 # be able to view any marked as not private. They should not be able to | |
| 325 # edit others' queries, even if they're not private | |
| 326 def view_query(db, userid, itemid): | |
| 327 private_for = db.query.get(itemid, 'private_for') | |
| 328 if not private_for: return True | |
| 329 return userid == private_for | |
| 330 def edit_query(db, userid, itemid): | |
| 331 return userid == db.query.get(itemid, 'creator') | |
| 332 p = db.security.addPermission(name='View', klass='query', check=view_query, | |
| 333 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
|
334 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
|
335 db.security.addPermissionToRole('User', p) |
| 4434 | 336 for r in 'User', 'Developer', 'Coordinator': |
| 337 db.security.addPermissionToRole(r, p) | |
| 338 p = db.security.addPermission(name='Edit', klass='query', check=edit_query, | |
| 339 description="User is allowed to edit their queries") | |
| 340 for r in 'User', 'Developer', 'Coordinator': | |
| 341 db.security.addPermissionToRole(r, p) | |
| 342 p = db.security.addPermission(name='Create', klass='query', | |
| 343 description="User is allowed to create queries") | |
| 344 for r in 'User', 'Developer', 'Coordinator': | |
| 345 db.security.addPermissionToRole(r, p) | |
| 346 | |
| 347 | |
| 348 # | |
| 349 # ANONYMOUS USER PERMISSIONS | |
| 350 # | |
| 351 # Let anonymous users access the web interface. Note that almost all | |
| 352 # trackers will need this Permission. The only situation where it's not | |
| 353 # required is in a tracker that uses an HTTP Basic Authenticated front-end. | |
| 354 db.security.addPermissionToRole('Anonymous', 'Web Access') | |
| 355 | |
| 356 # Let anonymous users access the email interface (note that this implies | |
| 357 # that they will be registered automatically, hence they will need the | |
| 358 # "Create" user Permission below) | |
| 359 # This is disabled by default to stop spam from auto-registering users on | |
| 360 # public trackers. | |
| 361 #db.security.addPermissionToRole('Anonymous', 'Email Access') | |
| 362 | |
| 363 # Assign the appropriate permissions to the anonymous user's Anonymous | |
| 364 # Role. Choices here are: | |
| 365 # - Allow anonymous users to register | |
| 366 db.security.addPermissionToRole('Anonymous', 'Create', 'user') | |
| 367 | |
| 368 # Allow anonymous users access to view issues (and the related, linked | |
| 369 # information). | |
| 370 | |
|
4454
cc402f5ad93e
Anonymous can only see bugs, but neither tasks nor milestones.
Stefan Seefeld <stefan@seefeld.name>
parents:
4437
diff
changeset
|
371 for cl in 'bug', 'severity', 'status', 'resolution', 'msg', 'file': |
| 4434 | 372 db.security.addPermissionToRole('Anonymous', 'View', cl) |
| 373 | |
| 374 # [OPTIONAL] | |
| 375 # Allow anonymous users access to create or edit "issue" items (and the | |
| 376 # related file and message items) | |
| 377 #for cl in 'issue', 'file', 'msg': | |
| 378 # db.security.addPermissionToRole('Anonymous', 'Create', cl) | |
| 379 # db.security.addPermissionToRole('Anonymous', 'Edit', cl) | |
| 380 | |
| 381 | |
| 382 # vim: set filetype=python sts=4 sw=4 et si : | |
| 383 |
