Merge lp:~bac/launchpad/bug-588773 into lp:launchpad
- bug-588773
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Aaron Bentley |
Approved revision: | no longer in the source branch. |
Merged at revision: | 10966 |
Proposed branch: | lp:~bac/launchpad/bug-588773 |
Merge into: | lp:launchpad |
Diff against target: |
1369 lines (+286/-17) 3 files modified
lib/canonical/launchpad/security.py (+186/-11) lib/lp/registry/browser/tests/test_edit_permissions.py (+97/-0) lib/lp/registry/stories/product/xx-product-edit.txt (+3/-6) |
To merge this branch: | bzr merge lp:~bac/launchpad/bug-588773 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Aaron Bentley (community) | code | Approve | |
Review via email: mp+26968@code.launchpad.net |
Commit message
Allow registry admins to access +edit on persons and pillars.
Description of the change
= Summary =
We want registry experts (members of ~registry) to have more abilities
in order to perform CHR duties. Often things like person or pillar
editing has to be deferred to LP admins which is not an efficient use of
their nor the CHR's time.
== Proposed fix ==
Change the security settings for launchpad.Edit for pillars and persons
to include registry experts.
== Pre-implementation notes ==
Chats with Curtis.
== Implementation details ==
As above.
== Tests ==
bin/test -vvm lp.registry -t test_edit_
== Demo and Q/A ==
In our sample data, only mark is in the registry admin team, but he is
also a LP admin, so using that account to test proves nothing. A
non-admin (such as bac) needs to be added to the registry team.
Once that is done, simply demonstrate that the registry expert can edit
people, project, project groups, and distros.
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files:
lib/canonical
lib/lp/
== Pyflakes notices ==
lib/canonical/
1170: undefined name 'EditDistributi
== Pylint notices ==
lib/canonical/
1170: [E0602, AdminDistributi
Undefined variable 'EditDistributi
I'll sort this out.
Brad Crittenden (bac) wrote : | # |
Aaron Bentley (abentley) wrote : | # |
Looks good. As discussed on IRC, there are a few spots that could use an additional blank line.
Brad Crittenden (bac) wrote : | # |
Thanks Aaron. The file was a bit of a mess regarding blank lines between the class/docstring and the first line of code. I fixed them all.
Brad Crittenden (bac) wrote : | # |
Fixed a failing test:
Preview Diff
1 | === modified file 'lib/canonical/launchpad/security.py' |
2 | --- lib/canonical/launchpad/security.py 2010-06-07 12:01:14 +0000 |
3 | +++ lib/canonical/launchpad/security.py 2010-06-08 13:20:48 +0000 |
4 | @@ -132,6 +132,7 @@ |
5 | |
6 | |
7 | class AuthorizationBase: |
8 | + |
9 | implements(IAuthorization) |
10 | permission = None |
11 | usedfor = None |
12 | @@ -176,6 +177,7 @@ |
13 | By default, any logged-in user can see anything. More restrictive |
14 | rulesets are defined in other IAuthorization implementations. |
15 | """ |
16 | + |
17 | permission = 'launchpad.View' |
18 | usedfor = Interface |
19 | |
20 | @@ -186,6 +188,7 @@ |
21 | |
22 | class AnonymousAuthorization(AuthorizationBase): |
23 | """Allow any authenticated and unauthenticated user access.""" |
24 | + |
25 | permission = 'launchpad.View' |
26 | |
27 | def checkUnauthenticated(self): |
28 | @@ -198,6 +201,7 @@ |
29 | |
30 | |
31 | class AdminByAdminsTeam(AuthorizationBase): |
32 | + |
33 | permission = 'launchpad.Admin' |
34 | usedfor = Interface |
35 | |
36 | @@ -206,6 +210,7 @@ |
37 | |
38 | |
39 | class AdminByCommercialTeamOrAdmins(AuthorizationBase): |
40 | + |
41 | permission = 'launchpad.Commercial' |
42 | usedfor = Interface |
43 | |
44 | @@ -214,6 +219,7 @@ |
45 | |
46 | |
47 | class EditByRegistryExpertsOrAdmins(AuthorizationBase): |
48 | + |
49 | permission = 'launchpad.Edit' |
50 | usedfor = ILaunchpadRoot |
51 | |
52 | @@ -222,6 +228,7 @@ |
53 | |
54 | |
55 | class ReviewByRegistryExpertsOrAdmins(AuthorizationBase): |
56 | + |
57 | permission = 'launchpad.ProjectReview' |
58 | usedfor = None |
59 | |
60 | @@ -230,27 +237,33 @@ |
61 | |
62 | |
63 | class ReviewProduct(ReviewByRegistryExpertsOrAdmins): |
64 | + |
65 | usedfor = IProduct |
66 | |
67 | |
68 | class ReviewProductSet(ReviewByRegistryExpertsOrAdmins): |
69 | + |
70 | usedfor = IProductSet |
71 | |
72 | |
73 | class ReviewProject(ReviewByRegistryExpertsOrAdmins): |
74 | + |
75 | usedfor = IProjectGroup |
76 | |
77 | |
78 | class ReviewProjectGroupSet(ReviewByRegistryExpertsOrAdmins): |
79 | + |
80 | usedfor = IProjectGroupSet |
81 | |
82 | |
83 | class ModeratePerson(ReviewByRegistryExpertsOrAdmins): |
84 | + |
85 | permission = 'launchpad.Moderate' |
86 | usedfor = IPerson |
87 | |
88 | |
89 | class ViewPillar(AuthorizationBase): |
90 | + |
91 | usedfor = IPillar |
92 | permission = 'launchpad.View' |
93 | |
94 | @@ -268,6 +281,7 @@ |
95 | |
96 | |
97 | class EditAccountBySelfOrAdmin(AuthorizationBase): |
98 | + |
99 | permission = 'launchpad.Edit' |
100 | usedfor = IAccount |
101 | |
102 | @@ -282,10 +296,12 @@ |
103 | |
104 | |
105 | class ViewAccount(EditAccountBySelfOrAdmin): |
106 | + |
107 | permission = 'launchpad.View' |
108 | |
109 | |
110 | class SpecialAccount(EditAccountBySelfOrAdmin): |
111 | + |
112 | permission = 'launchpad.Special' |
113 | |
114 | def checkAuthenticated(self, user): |
115 | @@ -294,14 +310,16 @@ |
116 | |
117 | |
118 | class ModerateAccountByRegistryExpert(AuthorizationBase): |
119 | + |
120 | + permission = 'launchpad.Moderate' |
121 | usedfor = IAccount |
122 | - permission = 'launchpad.Moderate' |
123 | |
124 | def checkAuthenticated(self, user): |
125 | return user.in_admin or user.in_registry_experts |
126 | |
127 | |
128 | class EditOAuthAccessToken(AuthorizationBase): |
129 | + |
130 | permission = 'launchpad.Edit' |
131 | usedfor = IOAuthAccessToken |
132 | |
133 | @@ -310,11 +328,13 @@ |
134 | |
135 | |
136 | class EditOAuthRequestToken(EditOAuthAccessToken): |
137 | + |
138 | permission = 'launchpad.Edit' |
139 | usedfor = IOAuthRequestToken |
140 | |
141 | |
142 | class EditBugNominationStatus(AuthorizationBase): |
143 | + |
144 | permission = 'launchpad.Driver' |
145 | usedfor = IBugNomination |
146 | |
147 | @@ -323,6 +343,7 @@ |
148 | |
149 | |
150 | class EditByOwnersOrAdmins(AuthorizationBase): |
151 | + |
152 | permission = 'launchpad.Edit' |
153 | usedfor = IHasOwner |
154 | |
155 | @@ -330,15 +351,28 @@ |
156 | return user.isOwner(self.obj) or user.in_admin |
157 | |
158 | |
159 | -class EditProduct(EditByOwnersOrAdmins): |
160 | +class EditByOwnersRegistryExpertsOrAdmins(AuthorizationBase): |
161 | + |
162 | + permission = 'launchpad.Edit' |
163 | + |
164 | + def checkAuthenticated(self, user): |
165 | + return (user.isOwner(self.obj) or |
166 | + user.in_registry_experts or |
167 | + user.in_admin) |
168 | + |
169 | + |
170 | +class EditProduct(EditByOwnersRegistryExpertsOrAdmins): |
171 | + |
172 | usedfor = IProduct |
173 | |
174 | |
175 | class EditPackaging(EditByOwnersOrAdmins): |
176 | + |
177 | usedfor = IPackaging |
178 | |
179 | |
180 | class EditProductReleaseFile(AuthorizationBase): |
181 | + |
182 | permission = 'launchpad.Edit' |
183 | usedfor = IProductReleaseFile |
184 | |
185 | @@ -349,6 +383,7 @@ |
186 | |
187 | class AdminDistributionMirrorByDistroOwnerOrMirrorAdminsOrAdmins( |
188 | AuthorizationBase): |
189 | + |
190 | permission = 'launchpad.Admin' |
191 | usedfor = IDistributionMirror |
192 | |
193 | @@ -360,6 +395,7 @@ |
194 | |
195 | class EditDistributionMirrorByOwnerOrDistroOwnerOrMirrorAdminsOrAdmins( |
196 | AuthorizationBase): |
197 | + |
198 | permission = 'launchpad.Edit' |
199 | usedfor = IDistributionMirror |
200 | |
201 | @@ -371,11 +407,13 @@ |
202 | |
203 | class ViewDistributionMirror(AnonymousAuthorization): |
204 | """Anyone can view an IDistributionMirror.""" |
205 | + |
206 | usedfor = IDistributionMirror |
207 | |
208 | |
209 | class ViewMilestone(AnonymousAuthorization): |
210 | """Anyone can view an IMilestone.""" |
211 | + |
212 | usedfor = IMilestone |
213 | |
214 | |
215 | @@ -426,6 +464,7 @@ |
216 | |
217 | |
218 | class AdminSpecification(AuthorizationBase): |
219 | + |
220 | permission = 'launchpad.Admin' |
221 | usedfor = ISpecification |
222 | |
223 | @@ -437,6 +476,7 @@ |
224 | |
225 | |
226 | class DriverSpecification(AuthorizationBase): |
227 | + |
228 | permission = 'launchpad.Driver' |
229 | usedfor = ISpecification |
230 | |
231 | @@ -455,6 +495,7 @@ |
232 | """The sprint owner or driver can say what makes it onto the agenda for |
233 | the sprint. |
234 | """ |
235 | + |
236 | permission = 'launchpad.Driver' |
237 | usedfor = ISprintSpecification |
238 | |
239 | @@ -467,6 +508,7 @@ |
240 | """The sprint owner or driver can say what makes it onto the agenda for |
241 | the sprint. |
242 | """ |
243 | + |
244 | permission = 'launchpad.Driver' |
245 | usedfor = ISprint |
246 | |
247 | @@ -478,6 +520,7 @@ |
248 | |
249 | class Sprint(AuthorizationBase): |
250 | """An attendee, owner, or driver of a sprint.""" |
251 | + |
252 | permission = 'launchpad.View' |
253 | usedfor = ISprint |
254 | |
255 | @@ -492,6 +535,7 @@ |
256 | class EditSpecificationSubscription(AuthorizationBase): |
257 | """The subscriber, and people related to the spec or the target of the |
258 | spec can determine who is essential.""" |
259 | + |
260 | permission = 'launchpad.Edit' |
261 | usedfor = ISpecificationSubscription |
262 | |
263 | @@ -519,6 +563,7 @@ |
264 | |
265 | |
266 | class AdminProjectTranslations(AuthorizationBase): |
267 | + |
268 | permission = 'launchpad.TranslationsAdmin' |
269 | usedfor = IProjectGroup |
270 | |
271 | @@ -534,6 +579,7 @@ |
272 | |
273 | |
274 | class AdminProductTranslations(AuthorizationBase): |
275 | + |
276 | permission = 'launchpad.TranslationsAdmin' |
277 | usedfor = IProduct |
278 | |
279 | @@ -548,7 +594,13 @@ |
280 | user.in_admin) |
281 | |
282 | |
283 | +class EditProject(EditByOwnersRegistryExpertsOrAdmins): |
284 | + |
285 | + usedfor = IProjectGroup |
286 | + |
287 | + |
288 | class EditProjectMilestoneNever(AuthorizationBase): |
289 | + |
290 | permission = 'launchpad.Edit' |
291 | usedfor = IProjectGroupMilestone |
292 | |
293 | @@ -558,6 +610,7 @@ |
294 | |
295 | |
296 | class EditMilestoneByTargetOwnerOrAdmins(AuthorizationBase): |
297 | + |
298 | permission = 'launchpad.Edit' |
299 | usedfor = IMilestone |
300 | |
301 | @@ -575,6 +628,7 @@ |
302 | |
303 | |
304 | class AdminMilestoneByLaunchpadAdmins(AuthorizationBase): |
305 | + |
306 | permission = 'launchpad.Admin' |
307 | usedfor = IMilestone |
308 | |
309 | @@ -586,11 +640,13 @@ |
310 | |
311 | |
312 | class ModeratePersonSetByExpertsOrAdmins(ReviewByRegistryExpertsOrAdmins): |
313 | + |
314 | permission = 'launchpad.Moderate' |
315 | usedfor = IPersonSet |
316 | |
317 | |
318 | class EditTeamByTeamOwnerOrLaunchpadAdmins(AuthorizationBase): |
319 | + |
320 | permission = 'launchpad.Owner' |
321 | usedfor = ITeam |
322 | |
323 | @@ -601,6 +657,7 @@ |
324 | |
325 | |
326 | class EditTeamByTeamOwnerOrTeamAdminsOrAdmins(AuthorizationBase): |
327 | + |
328 | permission = 'launchpad.Edit' |
329 | usedfor = ITeam |
330 | |
331 | @@ -613,6 +670,7 @@ |
332 | |
333 | |
334 | class ModerateTeam(ReviewByRegistryExpertsOrAdmins): |
335 | + |
336 | permission = 'launchpad.Moderate' |
337 | usedfor = ITeam |
338 | |
339 | @@ -628,6 +686,7 @@ |
340 | |
341 | |
342 | class EditTeamMembershipByTeamOwnerOrTeamAdminsOrAdmins(AuthorizationBase): |
343 | + |
344 | permission = 'launchpad.Edit' |
345 | usedfor = ITeamMembership |
346 | |
347 | @@ -640,6 +699,7 @@ |
348 | # going to be used only on the webservice (which explicitly checks for |
349 | # launchpad.View) so that we don't leak memberships of private teams. |
350 | class ViewTeamMembership(AuthorizationBase): |
351 | + |
352 | permission = 'launchpad.View' |
353 | usedfor = ITeamMembership |
354 | |
355 | @@ -660,19 +720,23 @@ |
356 | return False |
357 | |
358 | |
359 | -class EditPersonBySelfOrAdmins(AuthorizationBase): |
360 | +class EditPersonBySelfRegistryExpertsOrAdmins(AuthorizationBase): |
361 | + |
362 | permission = 'launchpad.Edit' |
363 | usedfor = IPerson |
364 | |
365 | def checkAuthenticated(self, user): |
366 | - """A user can edit the Person who is herself. |
367 | + """A user can edit his or her own object. |
368 | |
369 | - The admin team can also edit any Person. |
370 | + The registry experts or admin teams can also edit any Person. |
371 | """ |
372 | - return self.obj.id == user.person.id or user.in_admin |
373 | + return (self.obj.id == user.person.id or |
374 | + user.in_registry_experts or |
375 | + user.in_admin) |
376 | |
377 | |
378 | class EditTranslationsPersonByPerson(AuthorizationBase): |
379 | + |
380 | permission = 'launchpad.Edit' |
381 | usedfor = ITranslationsPerson |
382 | |
383 | @@ -682,6 +746,7 @@ |
384 | |
385 | |
386 | class ViewPersonLocation(AuthorizationBase): |
387 | + |
388 | permission = 'launchpad.View' |
389 | usedfor = IPersonLocation |
390 | |
391 | @@ -696,6 +761,7 @@ |
392 | |
393 | |
394 | class EditPersonBySelf(AuthorizationBase): |
395 | + |
396 | permission = 'launchpad.Special' |
397 | usedfor = IPerson |
398 | |
399 | @@ -710,6 +776,7 @@ |
400 | Only members of a team with a private membership can view the |
401 | membership list. |
402 | """ |
403 | + |
404 | permission = 'launchpad.View' |
405 | usedfor = IPerson |
406 | |
407 | @@ -740,17 +807,20 @@ |
408 | |
409 | class EditPollByTeamOwnerOrTeamAdminsOrAdmins( |
410 | EditTeamMembershipByTeamOwnerOrTeamAdminsOrAdmins): |
411 | + |
412 | permission = 'launchpad.Edit' |
413 | usedfor = IPoll |
414 | |
415 | |
416 | class EditPollSubsetByTeamOwnerOrTeamAdminsOrAdmins( |
417 | EditPollByTeamOwnerOrTeamAdminsOrAdmins): |
418 | + |
419 | permission = 'launchpad.Edit' |
420 | usedfor = IPollSubset |
421 | |
422 | |
423 | class EditPollOptionByTeamOwnerOrTeamAdminsOrAdmins(AuthorizationBase): |
424 | + |
425 | permission = 'launchpad.Edit' |
426 | usedfor = IPollOption |
427 | |
428 | @@ -762,21 +832,21 @@ |
429 | """Soyuz involves huge chunks of data in the archive and librarian, |
430 | so for the moment we are locking down admin and edit on distributions |
431 | and distroseriess to the Launchpad admin team.""" |
432 | + |
433 | permission = 'launchpad.Admin' |
434 | usedfor = IDistribution |
435 | |
436 | |
437 | -class EditDistributionByDistroOwnersOrAdmins(AuthorizationBase): |
438 | +class EditDistributionByOwnersRegistryExpertsOrAdmins( |
439 | + EditByOwnersRegistryExpertsOrAdmins): |
440 | """The owner of a distribution should be able to edit its |
441 | information; it is mainly administrative data, such as bug |
442 | contacts. Note that creation of new distributions and distribution |
443 | series is still protected with launchpad.Admin""" |
444 | + |
445 | permission = 'launchpad.Edit' |
446 | usedfor = IDistribution |
447 | |
448 | - def checkAuthenticated(self, user): |
449 | - return user.isOwner(self.obj) or user.in_admin |
450 | - |
451 | |
452 | class AppendDistributionByDriversOrOwnersOrAdmins(AuthorizationBase): |
453 | """Distribution drivers, owners, and admins may plan releases. |
454 | @@ -784,6 +854,7 @@ |
455 | Drivers of `IDerivativeDistribution`s can create series. Owners and |
456 | admins can create series for all `IDistribution`s. |
457 | """ |
458 | + |
459 | permission = 'launchpad.Append' |
460 | usedfor = IDistribution |
461 | |
462 | @@ -798,6 +869,7 @@ |
463 | class EditDistributionSourcePackageByDistroOwnersOrAdmins(AuthorizationBase): |
464 | """The owner of a distribution should be able to edit its source |
465 | package information""" |
466 | + |
467 | permission = 'launchpad.Edit' |
468 | usedfor = IDistributionSourcePackage |
469 | |
470 | @@ -816,6 +888,7 @@ |
471 | files moved to the new namespace, and mirrors would get very very |
472 | upset. Then James T would be on your case. |
473 | """ |
474 | + |
475 | permission = 'launchpad.Admin' |
476 | usedfor = IDistroSeries |
477 | |
478 | @@ -828,6 +901,7 @@ |
479 | please consult with Kiko and MDZ on the mailing list before modifying |
480 | these permissions. |
481 | """ |
482 | + |
483 | permission = 'launchpad.Edit' |
484 | usedfor = IDistroSeries |
485 | |
486 | @@ -844,11 +918,13 @@ |
487 | |
488 | class ViewDistroSeries(AnonymousAuthorization): |
489 | """Anyone can view a DistroSeries.""" |
490 | + |
491 | usedfor = IDistroSeries |
492 | |
493 | |
494 | class ViewCountry(AnonymousAuthorization): |
495 | """Anyone can view a Country.""" |
496 | + |
497 | usedfor = ICountry |
498 | |
499 | |
500 | @@ -858,6 +934,7 @@ |
501 | Drivers exist for distribution and product series. Distribution and |
502 | product owners are implicitly drivers too. |
503 | """ |
504 | + |
505 | permission = 'launchpad.Driver' |
506 | usedfor = IHasDrivers |
507 | |
508 | @@ -873,6 +950,7 @@ |
509 | |
510 | |
511 | class EditProductSeries(EditByOwnersOrAdmins): |
512 | + |
513 | usedfor = IProductSeries |
514 | |
515 | def checkAuthenticated(self, user): |
516 | @@ -898,6 +976,7 @@ |
517 | bugs. Allow only explicit subscribers to edit objects linked to |
518 | private bugs. |
519 | """ |
520 | + |
521 | permission = 'launchpad.Edit' |
522 | usedfor = IHasBug |
523 | |
524 | @@ -923,6 +1002,7 @@ |
525 | |
526 | |
527 | class PublicToAllOrPrivateToExplicitSubscribersForBugTask(AuthorizationBase): |
528 | + |
529 | permission = 'launchpad.View' |
530 | usedfor = IHasBug |
531 | |
532 | @@ -936,6 +1016,7 @@ |
533 | |
534 | class EditPublicByLoggedInUserAndPrivateByExplicitSubscribers( |
535 | AuthorizationBase): |
536 | + |
537 | permission = 'launchpad.Edit' |
538 | usedfor = IBug |
539 | |
540 | @@ -963,6 +1044,7 @@ |
541 | |
542 | |
543 | class PublicToAllOrPrivateToExplicitSubscribersForBug(AuthorizationBase): |
544 | + |
545 | permission = 'launchpad.View' |
546 | usedfor = IBug |
547 | |
548 | @@ -978,6 +1060,7 @@ |
549 | |
550 | |
551 | class EditBugBranch(EditPublicByLoggedInUserAndPrivateByExplicitSubscribers): |
552 | + |
553 | permission = 'launchpad.Edit' |
554 | usedfor = IBugBranch |
555 | |
556 | @@ -994,6 +1077,7 @@ |
557 | If the user is authorized to view the bug, he's allowed to view the |
558 | attachment. |
559 | """ |
560 | + |
561 | permission = 'launchpad.View' |
562 | usedfor = IBugAttachment |
563 | |
564 | @@ -1009,6 +1093,7 @@ |
565 | If the user is authorized to view the bug, he's allowed to edit the |
566 | attachment. |
567 | """ |
568 | + |
569 | permission = 'launchpad.Edit' |
570 | usedfor = IBugAttachment |
571 | |
572 | @@ -1028,6 +1113,7 @@ |
573 | |
574 | |
575 | class ViewAnnouncement(AuthorizationBase): |
576 | + |
577 | permission = 'launchpad.View' |
578 | usedfor = IAnnouncement |
579 | |
580 | @@ -1054,6 +1140,7 @@ |
581 | |
582 | |
583 | class EditAnnouncement(AuthorizationBase): |
584 | + |
585 | permission = 'launchpad.Edit' |
586 | usedfor = IAnnouncement |
587 | |
588 | @@ -1067,6 +1154,7 @@ |
589 | |
590 | |
591 | class UseApiDoc(AuthorizationBase): |
592 | + |
593 | permission = 'zope.app.apidoc.UseAPIDoc' |
594 | usedfor = Interface |
595 | |
596 | @@ -1096,6 +1184,7 @@ |
597 | Currently, we restrict the visibility of the new code import |
598 | system to members of ~vcs-imports and Launchpad admins. |
599 | """ |
600 | + |
601 | permission = 'launchpad.Edit' |
602 | usedfor = ICodeImport |
603 | |
604 | @@ -1106,6 +1195,7 @@ |
605 | Currently, we restrict the visibility of the new code import |
606 | system to members of ~vcs-imports and Launchpad admins. |
607 | """ |
608 | + |
609 | permission = 'launchpad.View' |
610 | usedfor = ICodeImportJobSet |
611 | |
612 | @@ -1116,6 +1206,7 @@ |
613 | Currently, we restrict the visibility of the new code import |
614 | system to members of ~vcs-imports and Launchpad admins. |
615 | """ |
616 | + |
617 | permission = 'launchpad.Edit' |
618 | usedfor = ICodeImportJobWorkflow |
619 | |
620 | @@ -1125,6 +1216,7 @@ |
621 | |
622 | Access is restricted to members of ~bazaar-experts and Launchpad admins. |
623 | """ |
624 | + |
625 | permission = 'launchpad.Edit' |
626 | usedfor = ICodeImportMachine |
627 | |
628 | @@ -1137,6 +1229,7 @@ |
629 | and limits access to Rosetta experts, Launchpad admins and distribution |
630 | translation group owner. |
631 | """ |
632 | + |
633 | permission = 'launchpad.TranslationsAdmin' |
634 | usedfor = IDistribution |
635 | |
636 | @@ -1154,12 +1247,13 @@ |
637 | return True |
638 | else: |
639 | return (user.in_rosetta_experts or |
640 | - EditDistributionByDistroOwnersOrAdmins( |
641 | + EditByOwnersOrAdmins( |
642 | self.obj).checkAuthenticated(user)) |
643 | |
644 | |
645 | class ViewPOTemplates(AnonymousAuthorization): |
646 | """Anyone can view an IPOTemplate.""" |
647 | + |
648 | usedfor = IPOTemplate |
649 | |
650 | |
651 | @@ -1191,6 +1285,7 @@ |
652 | |
653 | |
654 | class EditPOTemplateDetails(AdminPOTemplateDetails, EditByOwnersOrAdmins): |
655 | + |
656 | permission = 'launchpad.Edit' |
657 | usedfor = IPOTemplate |
658 | |
659 | @@ -1211,16 +1306,19 @@ |
660 | # XXX: Carlos Perello Marin 2005-05-24 bug=753: |
661 | # This should be using SuperSpecialPermissions when implemented. |
662 | class AddPOTemplate(OnlyRosettaExpertsAndAdmins): |
663 | + |
664 | permission = 'launchpad.Append' |
665 | usedfor = IProductSeries |
666 | |
667 | |
668 | class ViewPOFile(AnonymousAuthorization): |
669 | """Anyone can view an IPOFile.""" |
670 | + |
671 | usedfor = IPOFile |
672 | |
673 | |
674 | class EditPOFileDetails(EditByOwnersOrAdmins): |
675 | + |
676 | usedfor = IPOFile |
677 | |
678 | def checkAuthenticated(self, user): |
679 | @@ -1233,6 +1331,7 @@ |
680 | |
681 | |
682 | class AdminTranslator(OnlyRosettaExpertsAndAdmins): |
683 | + |
684 | permission = 'launchpad.Admin' |
685 | usedfor = ITranslator |
686 | |
687 | @@ -1244,6 +1343,7 @@ |
688 | |
689 | |
690 | class EditTranslator(OnlyRosettaExpertsAndAdmins): |
691 | + |
692 | permission = 'launchpad.Edit' |
693 | usedfor = IEditTranslator |
694 | |
695 | @@ -1256,6 +1356,7 @@ |
696 | |
697 | |
698 | class EditTranslationGroup(OnlyRosettaExpertsAndAdmins): |
699 | + |
700 | permission = 'launchpad.Edit' |
701 | usedfor = ITranslationGroup |
702 | |
703 | @@ -1267,6 +1368,7 @@ |
704 | |
705 | |
706 | class EditTranslationGroupSet(OnlyRosettaExpertsAndAdmins): |
707 | + |
708 | permission = 'launchpad.Admin' |
709 | usedfor = ITranslationGroupSet |
710 | |
711 | @@ -1312,10 +1414,12 @@ |
712 | |
713 | class ViewBugTracker(AnonymousAuthorization): |
714 | """Anyone can view a bug tracker.""" |
715 | + |
716 | usedfor = IBugTracker |
717 | |
718 | |
719 | class EditBugTracker(AuthorizationBase): |
720 | + |
721 | permission = 'launchpad.Edit' |
722 | usedfor = IBugTracker |
723 | |
724 | @@ -1325,6 +1429,7 @@ |
725 | |
726 | |
727 | class EditProductRelease(EditByOwnersOrAdmins): |
728 | + |
729 | permission = 'launchpad.Edit' |
730 | usedfor = IProductRelease |
731 | |
732 | @@ -1344,6 +1449,7 @@ |
733 | |
734 | |
735 | class AdminTranslationImportQueueEntry(AuthorizationBase): |
736 | + |
737 | permission = 'launchpad.Admin' |
738 | usedfor = ITranslationImportQueueEntry |
739 | |
740 | @@ -1352,6 +1458,7 @@ |
741 | |
742 | |
743 | class EditTranslationImportQueueEntry(AuthorizationBase): |
744 | + |
745 | permission = 'launchpad.Edit' |
746 | usedfor = ITranslationImportQueueEntry |
747 | |
748 | @@ -1363,11 +1470,13 @@ |
749 | |
750 | |
751 | class AdminTranslationImportQueue(OnlyRosettaExpertsAndAdmins): |
752 | + |
753 | permission = 'launchpad.Admin' |
754 | usedfor = ITranslationImportQueue |
755 | |
756 | |
757 | class EditPackageUploadQueue(AdminByAdminsTeam): |
758 | + |
759 | permission = 'launchpad.Edit' |
760 | usedfor = IPackageUploadQueue |
761 | |
762 | @@ -1384,6 +1493,7 @@ |
763 | |
764 | |
765 | class EditPackageUpload(AdminByAdminsTeam): |
766 | + |
767 | permission = 'launchpad.Edit' |
768 | usedfor = IPackageUpload |
769 | |
770 | @@ -1416,6 +1526,7 @@ |
771 | |
772 | |
773 | class AdminByBuilddAdmin(AuthorizationBase): |
774 | + |
775 | permission = 'launchpad.Admin' |
776 | |
777 | def checkAuthenticated(self, user): |
778 | @@ -1424,10 +1535,12 @@ |
779 | |
780 | |
781 | class AdminBuilderSet(AdminByBuilddAdmin): |
782 | + |
783 | usedfor = IBuilderSet |
784 | |
785 | |
786 | class AdminBuilder(AdminByBuilddAdmin): |
787 | + |
788 | usedfor = IBuilder |
789 | |
790 | |
791 | @@ -1435,20 +1548,24 @@ |
792 | # in the original plan, we should grant some rights to the owners and |
793 | # that's what Edit is for. |
794 | class EditBuilder(AdminByBuilddAdmin): |
795 | + |
796 | permission = 'launchpad.Edit' |
797 | usedfor = IBuilder |
798 | |
799 | |
800 | class AdminBuildRecord(AdminByBuilddAdmin): |
801 | + |
802 | usedfor = IBuildFarmJob |
803 | |
804 | |
805 | class EditBuildFarmJob(AdminByBuilddAdmin): |
806 | + |
807 | permission = 'launchpad.Edit' |
808 | usedfor = IBuildFarmJob |
809 | |
810 | |
811 | class EditPackageBuild(EditBuildFarmJob): |
812 | + |
813 | usedfor = IPackageBuild |
814 | |
815 | def checkAuthenticated(self, user): |
816 | @@ -1463,6 +1580,7 @@ |
817 | user.inTeam(self.obj.archive.owner)) |
818 | |
819 | class EditBinaryPackageBuild(EditPackageBuild): |
820 | + |
821 | permission = 'launchpad.Edit' |
822 | usedfor = IBinaryPackageBuild |
823 | |
824 | @@ -1492,6 +1610,7 @@ |
825 | |
826 | |
827 | class ViewBinaryPackageBuild(EditBinaryPackageBuild): |
828 | + |
829 | permission = 'launchpad.View' |
830 | |
831 | # This code MUST match the logic in |
832 | @@ -1539,6 +1658,7 @@ |
833 | This permission is based entirely on permission to view the |
834 | associated `IBinaryPackageBuild` and/or `IBranch`. |
835 | """ |
836 | + |
837 | permission = 'launchpad.View' |
838 | usedfor = IBuildFarmJobOld |
839 | |
840 | @@ -1581,6 +1701,7 @@ |
841 | |
842 | |
843 | class AdminQuestion(AdminByAdminsTeam): |
844 | + |
845 | permission = 'launchpad.Admin' |
846 | usedfor = IQuestion |
847 | |
848 | @@ -1592,6 +1713,7 @@ |
849 | |
850 | |
851 | class ModerateQuestion(AdminQuestion): |
852 | + |
853 | permission = 'launchpad.Moderate' |
854 | usedfor = IQuestion |
855 | |
856 | @@ -1606,6 +1728,7 @@ |
857 | |
858 | |
859 | class QuestionOwner(AuthorizationBase): |
860 | + |
861 | permission = 'launchpad.Owner' |
862 | usedfor = IQuestion |
863 | |
864 | @@ -1615,6 +1738,7 @@ |
865 | |
866 | |
867 | class ModerateFAQTarget(EditByOwnersOrAdmins): |
868 | + |
869 | permission = 'launchpad.Moderate' |
870 | usedfor = IFAQTarget |
871 | |
872 | @@ -1630,6 +1754,7 @@ |
873 | |
874 | |
875 | class EditFAQ(AuthorizationBase): |
876 | + |
877 | permission = 'launchpad.Edit' |
878 | usedfor = IFAQ |
879 | |
880 | @@ -1649,20 +1774,24 @@ |
881 | |
882 | class ViewLanguageSet(AnonymousAuthorization): |
883 | """Anyone can view an ILangaugeSet.""" |
884 | + |
885 | usedfor = ILanguageSet |
886 | |
887 | |
888 | class AdminLanguageSet(OnlyRosettaExpertsAndAdmins): |
889 | + |
890 | permission = 'launchpad.Admin' |
891 | usedfor = ILanguageSet |
892 | |
893 | |
894 | class ViewLanguage(AnonymousAuthorization): |
895 | """Anyone can view an ILangauge.""" |
896 | + |
897 | usedfor = ILanguage |
898 | |
899 | |
900 | class AdminLanguage(OnlyRosettaExpertsAndAdmins): |
901 | + |
902 | permission = 'launchpad.Admin' |
903 | usedfor = ILanguage |
904 | |
905 | @@ -1674,6 +1803,7 @@ |
906 | of the branch, they are in the team that owns the branch, subscribed to |
907 | the branch, or a launchpad administrator. |
908 | """ |
909 | + |
910 | permission = 'launchpad.View' |
911 | usedfor = IBranch |
912 | |
913 | @@ -1686,6 +1816,7 @@ |
914 | |
915 | class EditBranch(AuthorizationBase): |
916 | """The owner, bazaar experts or admins can edit branches.""" |
917 | + |
918 | permission = 'launchpad.Edit' |
919 | usedfor = IBranch |
920 | |
921 | @@ -1734,6 +1865,7 @@ |
922 | |
923 | class AdminBranch(AuthorizationBase): |
924 | """The bazaar experts or admins can administer branches.""" |
925 | + |
926 | permission = 'launchpad.Admin' |
927 | usedfor = IBranch |
928 | |
929 | @@ -1743,6 +1875,7 @@ |
930 | |
931 | |
932 | class AdminDistroSeriesTranslations(AuthorizationBase): |
933 | + |
934 | permission = 'launchpad.TranslationsAdmin' |
935 | usedfor = IDistroSeries |
936 | |
937 | @@ -1757,6 +1890,7 @@ |
938 | |
939 | |
940 | class BranchMergeProposalView(AuthorizationBase): |
941 | + |
942 | permission = 'launchpad.View' |
943 | usedfor = IBranchMergeProposal |
944 | |
945 | @@ -1781,6 +1915,7 @@ |
946 | |
947 | |
948 | class PreviewDiffView(AuthorizationBase): |
949 | + |
950 | permission = 'launchpad.View' |
951 | usedfor = IPreviewDiff |
952 | |
953 | @@ -1804,6 +1939,7 @@ |
954 | |
955 | |
956 | class CodeReviewVoteReferenceEdit(AuthorizationBase): |
957 | + |
958 | permission = 'launchpad.Edit' |
959 | usedfor = ICodeReviewVoteReference |
960 | |
961 | @@ -1825,6 +1961,7 @@ |
962 | |
963 | |
964 | class CodeReviewCommentView(AuthorizationBase): |
965 | + |
966 | permission = 'launchpad.View' |
967 | usedfor = ICodeReviewComment |
968 | |
969 | @@ -1848,6 +1985,7 @@ |
970 | |
971 | |
972 | class CodeReviewCommentDelete(AuthorizationBase): |
973 | + |
974 | permission = 'launchpad.Edit' |
975 | usedfor = ICodeReviewCommentDeletion |
976 | |
977 | @@ -1871,6 +2009,7 @@ |
978 | |
979 | |
980 | class BranchMergeProposalEdit(AuthorizationBase): |
981 | + |
982 | permission = 'launchpad.Edit' |
983 | usedfor = IBranchMergeProposal |
984 | |
985 | @@ -1896,6 +2035,7 @@ |
986 | Allow the owner of the entitlement, the entitlement registrant, |
987 | or any member of the team or any admin to view the entitlement. |
988 | """ |
989 | + |
990 | permission = 'launchpad.View' |
991 | usedfor = IEntitlement |
992 | |
993 | @@ -1913,6 +2053,7 @@ |
994 | class AdminDistroSeriesLanguagePacks( |
995 | OnlyRosettaExpertsAndAdmins, |
996 | EditDistroSeriesByOwnersOrDistroOwnersOrAdmins): |
997 | + |
998 | permission = 'launchpad.LanguagePacksAdmin' |
999 | usedfor = IDistroSeries |
1000 | |
1001 | @@ -1931,11 +2072,13 @@ |
1002 | |
1003 | |
1004 | class AdminLanguagePack(OnlyRosettaExpertsAndAdmins): |
1005 | + |
1006 | permission = 'launchpad.LanguagePacksAdmin' |
1007 | usedfor = ILanguagePack |
1008 | |
1009 | |
1010 | class ViewHWSubmission(AuthorizationBase): |
1011 | + |
1012 | permission = 'launchpad.View' |
1013 | usedfor = IHWSubmission |
1014 | |
1015 | @@ -1956,6 +2099,7 @@ |
1016 | |
1017 | |
1018 | class EditHWSubmission(AdminByAdminsTeam): |
1019 | + |
1020 | permission = 'launchpad.Edit' |
1021 | usedfor = IHWSubmission |
1022 | |
1023 | @@ -1963,6 +2107,7 @@ |
1024 | class ViewHWDBBase(AuthorizationBase): |
1025 | """Base class to restrict access to HWDB data to members of the HWDB team. |
1026 | """ |
1027 | + |
1028 | permission = 'launchpad.View' |
1029 | |
1030 | def checkAuthenticated(self, user): |
1031 | @@ -1975,34 +2120,42 @@ |
1032 | |
1033 | |
1034 | class ViewHWDriver(ViewHWDBBase): |
1035 | + |
1036 | usedfor = IHWDriver |
1037 | |
1038 | |
1039 | class ViewHWDriverName(ViewHWDBBase): |
1040 | + |
1041 | usedfor = IHWDriverName |
1042 | |
1043 | |
1044 | class ViewHWDriverPackageName(ViewHWDBBase): |
1045 | + |
1046 | usedfor = IHWDriverPackageName |
1047 | |
1048 | |
1049 | class ViewHWVendorID(ViewHWDBBase): |
1050 | + |
1051 | usedfor = IHWVendorID |
1052 | |
1053 | |
1054 | class ViewHWDevice(ViewHWDBBase): |
1055 | + |
1056 | usedfor = IHWDevice |
1057 | |
1058 | |
1059 | class ViewHWSubmissionDevice(ViewHWDBBase): |
1060 | + |
1061 | usedfor = IHWSubmissionDevice |
1062 | |
1063 | |
1064 | class ViewHWDBApplication(ViewHWDBBase): |
1065 | + |
1066 | usedfor = IHWDBApplication |
1067 | |
1068 | |
1069 | class ViewHWDeviceClass(ViewHWDBBase): |
1070 | + |
1071 | usedfor = IHWDeviceClass |
1072 | |
1073 | |
1074 | @@ -2012,6 +2165,7 @@ |
1075 | Only admins or members of a team with a private membership can |
1076 | view the archive. |
1077 | """ |
1078 | + |
1079 | permission = 'launchpad.View' |
1080 | usedfor = IArchive |
1081 | |
1082 | @@ -2059,6 +2213,7 @@ |
1083 | Appending to ubuntu main archives can also be done by the |
1084 | 'ubuntu-security' celebrity. |
1085 | """ |
1086 | + |
1087 | permission = 'launchpad.Append' |
1088 | usedfor = IArchive |
1089 | |
1090 | @@ -2087,6 +2242,7 @@ |
1091 | The user just needs to be mentioned in the token, have append privilege |
1092 | to the archive or be an admin. |
1093 | """ |
1094 | + |
1095 | permission = "launchpad.View" |
1096 | usedfor = IArchiveAuthToken |
1097 | |
1098 | @@ -2103,6 +2259,7 @@ |
1099 | The user should have append privileges to the context archive, or be an |
1100 | admin. |
1101 | """ |
1102 | + |
1103 | permission = "launchpad.Edit" |
1104 | usedfor = IArchiveAuthToken |
1105 | |
1106 | @@ -2119,6 +2276,7 @@ |
1107 | The user should be the subscriber, have append privilege to the archive |
1108 | or be an admin. |
1109 | """ |
1110 | + |
1111 | permission = "launchpad.View" |
1112 | usedfor = IPersonalArchiveSubscription |
1113 | |
1114 | @@ -2139,6 +2297,7 @@ |
1115 | The user should be the subscriber, have append privilege to the |
1116 | archive or be an admin. |
1117 | """ |
1118 | + |
1119 | permission = "launchpad.View" |
1120 | usedfor = IArchiveSubscriber |
1121 | |
1122 | @@ -2154,6 +2313,7 @@ |
1123 | |
1124 | The user should have append privilege to the archive or be an admin. |
1125 | """ |
1126 | + |
1127 | permission = "launchpad.Edit" |
1128 | usedfor = IArchiveSubscriber |
1129 | |
1130 | @@ -2212,6 +2372,7 @@ |
1131 | |
1132 | class ViewSourcePackagePublishingHistory(ViewArchive): |
1133 | """Restrict viewing of source publications.""" |
1134 | + |
1135 | permission = "launchpad.View" |
1136 | usedfor = ISourcePackagePublishingHistory |
1137 | |
1138 | @@ -2221,6 +2382,7 @@ |
1139 | |
1140 | class EditPublishing(AuthorizationBase): |
1141 | """Restrict editing of source and binary packages..""" |
1142 | + |
1143 | permission = "launchpad.Edit" |
1144 | usedfor = IPublishingEdit |
1145 | |
1146 | @@ -2230,12 +2392,14 @@ |
1147 | |
1148 | class ViewBinaryPackagePublishingHistory(ViewSourcePackagePublishingHistory): |
1149 | """Restrict viewing of binary publications.""" |
1150 | + |
1151 | usedfor = IBinaryPackagePublishingHistory |
1152 | |
1153 | |
1154 | class ViewBinaryPackageReleaseDownloadCount( |
1155 | ViewSourcePackagePublishingHistory): |
1156 | """Restrict viewing of binary package download counts.""" |
1157 | + |
1158 | usedfor = IBinaryPackageReleaseDownloadCount |
1159 | |
1160 | |
1161 | @@ -2249,6 +2413,7 @@ |
1162 | automatically viewable even if the package is also published in |
1163 | a private archive. |
1164 | """ |
1165 | + |
1166 | permission = 'launchpad.View' |
1167 | usedfor = ISourcePackageRelease |
1168 | |
1169 | @@ -2273,6 +2438,7 @@ |
1170 | |
1171 | |
1172 | class MailingListApprovalByExperts(AuthorizationBase): |
1173 | + |
1174 | permission = 'launchpad.Admin' |
1175 | usedfor = IMailingListSet |
1176 | |
1177 | @@ -2281,6 +2447,7 @@ |
1178 | |
1179 | |
1180 | class ConfigureTeamMailingList(AuthorizationBase): |
1181 | + |
1182 | permission = 'launchpad.MailingListManager' |
1183 | usedfor = ITeam |
1184 | |
1185 | @@ -2305,6 +2472,7 @@ |
1186 | |
1187 | |
1188 | class ViewEmailAddress(AuthorizationBase): |
1189 | + |
1190 | permission = 'launchpad.View' |
1191 | usedfor = IEmailAddress |
1192 | |
1193 | @@ -2342,6 +2510,7 @@ |
1194 | |
1195 | |
1196 | class EditEmailAddress(EditByOwnersOrAdmins): |
1197 | + |
1198 | permission = 'launchpad.Edit' |
1199 | usedfor = IEmailAddress |
1200 | |
1201 | @@ -2354,18 +2523,22 @@ |
1202 | |
1203 | |
1204 | class ViewGPGKey(AnonymousAuthorization): |
1205 | + |
1206 | usedfor = IGPGKey |
1207 | |
1208 | |
1209 | class ViewIrcID(AnonymousAuthorization): |
1210 | + |
1211 | usedfor = IIrcID |
1212 | |
1213 | |
1214 | class ViewWikiName(AnonymousAuthorization): |
1215 | + |
1216 | usedfor = IWikiName |
1217 | |
1218 | |
1219 | class EditArchivePermissionSet(AuthorizationBase): |
1220 | + |
1221 | permission = 'launchpad.Edit' |
1222 | usedfor = IArchivePermissionSet |
1223 | |
1224 | @@ -2407,6 +2580,7 @@ |
1225 | |
1226 | |
1227 | class EditPackageset(AuthorizationBase): |
1228 | + |
1229 | permission = 'launchpad.Edit' |
1230 | usedfor = IPackageset |
1231 | |
1232 | @@ -2416,6 +2590,7 @@ |
1233 | |
1234 | |
1235 | class EditPackagesetSet(AuthorizationBase): |
1236 | + |
1237 | permission = 'launchpad.Edit' |
1238 | usedfor = IPackagesetSet |
1239 | |
1240 | |
1241 | === added file 'lib/lp/registry/browser/tests/test_edit_permissions.py' |
1242 | --- lib/lp/registry/browser/tests/test_edit_permissions.py 1970-01-01 00:00:00 +0000 |
1243 | +++ lib/lp/registry/browser/tests/test_edit_permissions.py 2010-06-08 13:20:48 +0000 |
1244 | @@ -0,0 +1,97 @@ |
1245 | +# Copyright 2010 Canonical Ltd. This software is licensed under the |
1246 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
1247 | + |
1248 | +"""Test harness for edit view permissions unit tests.""" |
1249 | + |
1250 | +__metaclass__ = type |
1251 | + |
1252 | + |
1253 | +import unittest |
1254 | + |
1255 | +from zope.component import getUtility |
1256 | +from canonical.testing.layers import DatabaseFunctionalLayer |
1257 | +from canonical.launchpad.ftests import ANONYMOUS, login, login_person |
1258 | +from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities |
1259 | +from canonical.launchpad.webapp.authorization import check_permission |
1260 | +from canonical.launchpad.webapp.servers import LaunchpadTestRequest |
1261 | +from lp.registry.interfaces.person import IPersonSet |
1262 | +from lp.testing import TestCaseWithFactory |
1263 | +from lp.testing.views import create_initialized_view |
1264 | + |
1265 | + |
1266 | +class EditViewPermissionBase(TestCaseWithFactory): |
1267 | + """Tests for permissions access the +edit page on the target.""" |
1268 | + |
1269 | + layer = DatabaseFunctionalLayer |
1270 | + |
1271 | + def setUp(self): |
1272 | + super(EditViewPermissionBase, self).setUp() |
1273 | + self.setupTarget() |
1274 | + self.registry_admin = self.factory.makePerson(name='registry-admin') |
1275 | + celebs = getUtility(ILaunchpadCelebrities) |
1276 | + login_person(celebs.registry_experts.teamowner) |
1277 | + celebs.registry_experts.addMember(self.registry_admin, |
1278 | + self.registry_admin) |
1279 | + self.request = LaunchpadTestRequest() |
1280 | + |
1281 | + def setupTarget(self): |
1282 | + """Set up the target context for the test suite.""" |
1283 | + self.target = self.factory.makePerson(name='target-person') |
1284 | + |
1285 | + def test_anon_cannot_edit(self): |
1286 | + login(ANONYMOUS) |
1287 | + view = create_initialized_view(self.target, '+edit') |
1288 | + self.assertFalse(check_permission('launchpad.Edit', view)) |
1289 | + |
1290 | + def test_arbitrary_user_cannot_edit(self): |
1291 | + person = self.factory.makePerson(name='the-dude') |
1292 | + login_person(person) |
1293 | + view = create_initialized_view(self.target, '+edit') |
1294 | + self.assertFalse(check_permission('launchpad.Edit', view)) |
1295 | + |
1296 | + def test_admin_can_edit(self): |
1297 | + admin = getUtility(IPersonSet).getByEmail('foo.bar@canonical.com') |
1298 | + login_person(admin) |
1299 | + view = create_initialized_view(self.target, '+edit') |
1300 | + self.assertTrue(check_permission('launchpad.Edit', view)) |
1301 | + |
1302 | + def test_registry_expert_can_edit(self): |
1303 | + login_person(self.registry_admin) |
1304 | + view = create_initialized_view(self.target, '+edit') |
1305 | + self.assertTrue(check_permission('launchpad.Edit', view)) |
1306 | + |
1307 | + |
1308 | +class PersonEditViewPermissionTestCase(EditViewPermissionBase): |
1309 | + """Tests for permissions to access person +edit page.""" |
1310 | + def test_arbitrary_user_can_edit_her_own_data(self): |
1311 | + login_person(self.target) |
1312 | + view = create_initialized_view(self.target, '+edit') |
1313 | + self.assertTrue(check_permission('launchpad.Edit', view)) |
1314 | + |
1315 | + |
1316 | +class ProductEditViewPermissionTestCase(EditViewPermissionBase): |
1317 | + """Tests for permissions to access prodcut +edit page.""" |
1318 | + def setupTarget(self): |
1319 | + self.target = self.factory.makeProduct() |
1320 | + |
1321 | + |
1322 | +class ProjectEditViewPermissionTestCase(EditViewPermissionBase): |
1323 | + """Tests for permissions to access prodcut +edit page.""" |
1324 | + def setupTarget(self): |
1325 | + self.target = self.factory.makeProject() |
1326 | + |
1327 | + |
1328 | +class DistributionEditViewPermissionTestCase(EditViewPermissionBase): |
1329 | + """Tests for permissions to access prodcut +edit page.""" |
1330 | + def setupTarget(self): |
1331 | + self.target = self.factory.makeDistribution() |
1332 | + |
1333 | + |
1334 | +def test_suite(): |
1335 | + suite = unittest.TestSuite() |
1336 | + suite.addTest(unittest.TestLoader().loadTestsFromName(__name__)) |
1337 | + return suite |
1338 | + |
1339 | + |
1340 | +if __name__ == '__main__': |
1341 | + unittest.main() |
1342 | |
1343 | === modified file 'lib/lp/registry/stories/product/xx-product-edit.txt' |
1344 | --- lib/lp/registry/stories/product/xx-product-edit.txt 2010-05-24 20:23:19 +0000 |
1345 | +++ lib/lp/registry/stories/product/xx-product-edit.txt 2010-06-08 13:20:48 +0000 |
1346 | @@ -235,20 +235,17 @@ |
1347 | ... |
1348 | Unauthorized:... |
1349 | |
1350 | -Even if we add them to the Registry Experts team: |
1351 | +If we add them to the Registry Experts team: |
1352 | |
1353 | >>> admin_browser.open("http://launchpad.dev/~registry/+addmember") |
1354 | >>> admin_browser.getControl('New member').value = 'no-priv' |
1355 | >>> admin_browser.getControl('Add Member').click() |
1356 | |
1357 | -They still cannot edit projects. |
1358 | +They now can edit projects. |
1359 | |
1360 | >>> browser.open('http://launchpad.dev/firefox/+edit') |
1361 | - Traceback (most recent call last): |
1362 | - ... |
1363 | - Unauthorized:... |
1364 | |
1365 | -And they still can't access +admin. |
1366 | +But they still can't access +admin. |
1367 | |
1368 | >>> browser.open('http://launchpad.dev/firefox/+admin') |
1369 | Traceback (most recent call last): |
Here is the incremental to fix the lint issue:
=== modified file 'lib/canonical/ launchpad/ security. py' launchpad/ security. py 2010-06-07 15:52:21 +0000 launchpad/ security. py 2010-06-07 16:29:17 +0000
--- lib/canonical/
+++ lib/canonical/
@@ -781,7 +781,7 @@
usedfor = IDistribution
-class EditDistroByOwn ersRegistryExpe rtOrAdmins( nByOwnersRegist ryExpertsOrAdmi ns( rsRegistryExper tsOrAdmins) : rosetta_ experts or nByDistroOwners OrAdmins( dmins(
self. obj).checkAuthe nticated( user))
+class EditDistributio
EditByOwne
"""The owner of a distribution should be able to edit its
information; it is mainly administrative data, such as bug
@@ -1167,7 +1167,7 @@
return True
else:
return (user.in_
- EditDistributio
+ EditByOwnersOrA