|
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)
|
|
|
218 db.security.addPermissionToRole('User', 'Create', cl)
|
|
|
219
|
|
|
220
|
|
|
221 def may_edit_file(db, userid, itemid):
|
|
|
222 return userid == db.file.get(itemid, "creator")
|
|
|
223
|
|
|
224 p = db.security.addPermission(name='Edit', klass='file', check=may_edit_file,
|
|
|
225 description="User is allowed to remove their own files")
|
|
|
226 db.security.addPermissionToRole('User', p)
|
|
|
227
|
|
|
228 p = db.security.addPermission(name='Create', klass='bug',
|
|
|
229 properties=('title', 'bug_type',
|
|
|
230 'components', 'versions',
|
|
|
231 'severity',
|
|
|
232 'messages', 'files', 'nosy'),
|
|
|
233 description='User can report and discuss bugs')
|
|
|
234 db.security.addPermissionToRole('User', p)
|
|
|
235
|
|
|
236 p = db.security.addPermission(name='Edit', klass='bug',
|
|
|
237 properties=('title', 'bug_type',
|
|
|
238 'components', 'versions',
|
|
|
239 'severity',
|
|
|
240 'messages', 'files', 'nosy'),
|
|
|
241 description='User can report and discuss bugs')
|
|
|
242 db.security.addPermissionToRole('User', p)
|
|
|
243
|
|
|
244 p = db.security.addPermission(name='Create', klass='task',
|
|
|
245 properties=('title', 'task_type',
|
|
|
246 'components',
|
|
|
247 'messages', 'files', 'nosy'),
|
|
|
248 description='Developer can create and discuss tasks')
|
|
|
249 db.security.addPermissionToRole('Developer', p)
|
|
|
250
|
|
|
251 p = db.security.addPermission(name='Edit', 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='Create', klass='milestone',
|
|
|
259 description='Coordinator can create and discuss milestones')
|
|
|
260 db.security.addPermissionToRole('Coordinator', p)
|
|
|
261
|
|
|
262 p = db.security.addPermission(name='Edit', klass='milestone',
|
|
|
263 description='Coordinator can create and discuss milestones')
|
|
|
264 db.security.addPermissionToRole('Coordinator', p)
|
|
|
265
|
|
|
266
|
|
|
267 ##########################
|
|
|
268 # Developer permissions
|
|
|
269 ##########################
|
|
|
270 for cl in ('bug_type', 'severity', 'component',
|
|
|
271 'version', 'priority', 'status', 'resolution',
|
|
|
272 'bug', 'file', 'msg', 'keyword'):
|
|
|
273 db.security.addPermissionToRole('Developer', 'View', cl)
|
|
|
274
|
|
|
275 for cl in ('bug', 'file', 'msg', 'keyword'):
|
|
|
276 db.security.addPermissionToRole('Developer', 'Edit', cl)
|
|
|
277 db.security.addPermissionToRole('Developer', 'Create', cl)
|
|
|
278
|
|
|
279
|
|
|
280 ##########################
|
|
|
281 # Coordinator permissions
|
|
|
282 ##########################
|
|
|
283 for cl in ('bug_type', 'task_type', 'severity', 'component',
|
|
|
284 'version', 'priority', 'status', 'resolution', 'bug', 'task', 'file', 'msg'):
|
|
|
285 db.security.addPermissionToRole('Coordinator', 'View', cl)
|
|
|
286 db.security.addPermissionToRole('Coordinator', 'Edit', cl)
|
|
|
287 db.security.addPermissionToRole('Coordinator', 'Create', cl)
|
|
|
288
|
|
|
289 # May users view other user information? Comment these lines out
|
|
|
290 # if you don't want them to
|
|
|
291 db.security.addPermissionToRole('User', 'View', 'user')
|
|
|
292 db.security.addPermissionToRole('Developer', 'View', 'user')
|
|
|
293 db.security.addPermissionToRole('Coordinator', 'View', 'user')
|
|
|
294
|
|
|
295 # Allow Coordinator to edit any user, including their roles.
|
|
|
296 db.security.addPermissionToRole('Coordinator', 'Edit', 'user')
|
|
|
297 db.security.addPermissionToRole('Coordinator', 'Web Roles')
|
|
|
298
|
|
|
299 # Users should be able to edit their own details -- this permission is
|
|
|
300 # limited to only the situation where the Viewed or Edited item is their own.
|
|
|
301 def own_record(db, userid, itemid):
|
|
|
302 '''Determine whether the userid matches the item being accessed.'''
|
|
|
303 return userid == itemid
|
|
|
304 p = db.security.addPermission(name='View', klass='user', check=own_record,
|
|
|
305 description="User is allowed to view their own user details")
|
|
|
306 for r in 'User', 'Developer', 'Coordinator':
|
|
|
307 db.security.addPermissionToRole(r, p)
|
|
|
308 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
|
|
|
309 description="User is allowed to edit their own user details",
|
|
|
310 properties=('username', 'password',
|
|
|
311 'address', 'realname',
|
|
|
312 'phone', 'organization',
|
|
|
313 'alternate_addresses',
|
|
|
314 'queries',
|
|
|
315 'timezone')) # Note: 'roles' excluded - users should not be able to edit their own roles.
|
|
|
316 for r in 'User', 'Developer':
|
|
|
317 db.security.addPermissionToRole(r, p)
|
|
|
318
|
|
|
319 # Users should be able to edit and view their own queries. They should also
|
|
|
320 # be able to view any marked as not private. They should not be able to
|
|
|
321 # edit others' queries, even if they're not private
|
|
|
322 def view_query(db, userid, itemid):
|
|
|
323 private_for = db.query.get(itemid, 'private_for')
|
|
|
324 if not private_for: return True
|
|
|
325 return userid == private_for
|
|
|
326 def edit_query(db, userid, itemid):
|
|
|
327 return userid == db.query.get(itemid, 'creator')
|
|
|
328 p = db.security.addPermission(name='View', klass='query', check=view_query,
|
|
|
329 description="User is allowed to view their own and public queries")
|
|
|
330 for r in 'User', 'Developer', 'Coordinator':
|
|
|
331 db.security.addPermissionToRole(r, p)
|
|
|
332 p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
|
|
|
333 description="User is allowed to edit their queries")
|
|
|
334 for r in 'User', 'Developer', 'Coordinator':
|
|
|
335 db.security.addPermissionToRole(r, p)
|
|
|
336 p = db.security.addPermission(name='Create', klass='query',
|
|
|
337 description="User is allowed to create queries")
|
|
|
338 for r in 'User', 'Developer', 'Coordinator':
|
|
|
339 db.security.addPermissionToRole(r, p)
|
|
|
340
|
|
|
341
|
|
|
342 #
|
|
|
343 # ANONYMOUS USER PERMISSIONS
|
|
|
344 #
|
|
|
345 # Let anonymous users access the web interface. Note that almost all
|
|
|
346 # trackers will need this Permission. The only situation where it's not
|
|
|
347 # required is in a tracker that uses an HTTP Basic Authenticated front-end.
|
|
|
348 db.security.addPermissionToRole('Anonymous', 'Web Access')
|
|
|
349
|
|
|
350 # Let anonymous users access the email interface (note that this implies
|
|
|
351 # that they will be registered automatically, hence they will need the
|
|
|
352 # "Create" user Permission below)
|
|
|
353 # This is disabled by default to stop spam from auto-registering users on
|
|
|
354 # public trackers.
|
|
|
355 #db.security.addPermissionToRole('Anonymous', 'Email Access')
|
|
|
356
|
|
|
357 # Assign the appropriate permissions to the anonymous user's Anonymous
|
|
|
358 # Role. Choices here are:
|
|
|
359 # - Allow anonymous users to register
|
|
|
360 db.security.addPermissionToRole('Anonymous', 'Create', 'user')
|
|
|
361
|
|
|
362 # Allow anonymous users access to view issues (and the related, linked
|
|
|
363 # information).
|
|
|
364
|
|
|
365 for cl in 'bug', 'task', 'milestone', 'severity', 'status', 'resolution', 'msg', 'file':
|
|
|
366 db.security.addPermissionToRole('Anonymous', 'View', cl)
|
|
|
367
|
|
|
368 # [OPTIONAL]
|
|
|
369 # Allow anonymous users access to create or edit "issue" items (and the
|
|
|
370 # related file and message items)
|
|
|
371 #for cl in 'issue', 'file', 'msg':
|
|
|
372 # db.security.addPermissionToRole('Anonymous', 'Create', cl)
|
|
|
373 # db.security.addPermissionToRole('Anonymous', 'Edit', cl)
|
|
|
374
|
|
|
375
|
|
|
376 # vim: set filetype=python sts=4 sw=4 et si :
|
|
|
377
|