10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
1 |
= PersonRoles = |
2 |
||
10121.2.14
by Henning Eggers
Documentation and code improvements as per review. |
3 |
To make it more convenient to check which roles a person has, |
10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
4 |
the IPersonRoles adapter is provided. It's main use is to easily check if a |
5 |
person is the member of a celebrity team or is a celebrity person. In |
|
6 |
addition, methods for common checks are provided, too. |
|
7 |
||
8 |
The IPersonRoles interface is closely tight to the ILaunchpadCelebrities |
|
9 |
interface. Any addition or removal of a person celebrity must be reflected in |
|
10 |
adding or removing the corresponding property in IPersonRoles. Luckily the |
|
10121.2.14
by Henning Eggers
Documentation and code improvements as per review. |
11 |
celebrities.txt doctest includes a check for this and will give useful |
12 |
information on which attribute needs to be added or removed. Both interfaces |
|
10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
13 |
are found in the same file. There is no need to adapt the implementation |
14 |
class PersonRoles, though (thanks to __getattr__). |
|
15 |
||
16 |
PersonRoles is most prominent in AuthenticationBase in security.py. The user |
|
10121.2.14
by Henning Eggers
Documentation and code improvements as per review. |
17 |
parameter to checkAuthenticated is a PersonRoles object (was a Person object). |
10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
18 |
|
19 |
||
20 |
== The person object and the adapter == |
|
21 |
||
22 |
PersonRoles is registered as an unnamed adapter for IPersonRoles. |
|
23 |
||
13130.1.8
by Curtis Hovey
Updated import of hasdriver. |
24 |
>>> from lp.registry.interfaces.role import IPersonRoles |
10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
25 |
>>> person = factory.makePerson() |
26 |
>>> print IPersonRoles(person) |
|
13130.1.6
by Curtis Hovey
Move ILaunchpadCelebrity to lp.app. |
27 |
<lp.registry.model.personroles.PersonRoles object at ...> |
10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
28 |
|
29 |
The original Person object can be reached through the person attribute. |
|
30 |
||
31 |
>>> roles = IPersonRoles(person) |
|
32 |
>>> print roles.person is person |
|
33 |
True |
|
34 |
||
35 |
||
36 |
== Celebrity persons == |
|
37 |
||
38 |
There are a number of celebrity persons defined in ILaunchpadCelebrities. |
|
39 |
PersonRoles has a corresponding attribute of the same name prefixed with |
|
40 |
"in_" to check if the person in question is a member of this celebrity or is |
|
41 |
this celebrity. The following tests are identical. |
|
42 |
||
13130.1.6
by Curtis Hovey
Move ILaunchpadCelebrity to lp.app. |
43 |
>>> from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
44 |
>>> rosetta_experts = getUtility(ILaunchpadCelebrities).rosetta_experts |
45 |
>>> print person.inTeam(rosetta_experts) |
|
46 |
False |
|
47 |
||
48 |
>>> print roles.in_rosetta_experts |
|
49 |
False |
|
50 |
||
51 |
The test will succeed once we make person a member of the team. Need to be an |
|
52 |
admin to do that. |
|
53 |
||
54 |
>>> login("foo.bar@canonical.com") |
|
55 |
>>> rosetta_experts.addMember(person, rosetta_experts.teamowner) |
|
56 |
(True, ...Approved>) |
|
57 |
>>> print roles.in_rosetta_experts |
|
58 |
True |
|
59 |
||
60 |
To stay consistent, all attributes are prefixed with "in_" although the |
|
10121.2.14
by Henning Eggers
Documentation and code improvements as per review. |
61 |
attribute names of ILaunchpadCelebrities are not all lexically correct |
62 |
plurals, nor are all the attributes teams. This makes for odd sounding |
|
10121.2.9
by Henning Eggers
Added doc test for PersonRoles. |
63 |
attribute names in IPersonRoles. |
64 |
||
65 |
>>> print roles.in_admin |
|
66 |
False |
|
67 |
>>> print roles.in_janitor |
|
68 |
False |
|
69 |
||
70 |
>>> janitor = getUtility(ILaunchpadCelebrities).janitor |
|
71 |
>>> janitor_roles = IPersonRoles(janitor) |
|
72 |
>>> print janitor_roles.in_janitor |
|
73 |
True |
|
74 |
||
75 |
||
76 |
== inTeam == |
|
77 |
||
78 |
The Person.inTeam method is available directly through PersonRoles. This can |
|
79 |
be used to check for any non-celebrity team. |
|
80 |
||
81 |
>>> new_team = factory.makeTeam() |
|
82 |
>>> new_team.addMember(person, new_team.teamowner) |
|
83 |
(True, ...Approved>) |
|
84 |
>>> print person.inTeam(new_team) |
|
85 |
True |
|
86 |
||
87 |
>>> print roles.inTeam(new_team) |
|
88 |
True |
|
89 |
||
90 |
||
91 |
== isOwner, isDriver == |
|
92 |
||
93 |
We can easily check for ownership and drivership. This is admittedly not much |
|
94 |
shorter than calling inTeam but clearer to read. |
|
95 |
||
96 |
>>> product = factory.makeProduct(owner=person) |
|
97 |
>>> print roles.isOwner(product) |
|
98 |
True |
|
99 |
||
100 |
>>> print roles.isDriver(product) |
|
101 |
False |
|
102 |
>>> product.driver = person |
|
103 |
>>> print roles.isDriver(product) |
|
104 |
True |
|
105 |
||
106 |
||
107 |
== isOneOfDrivers == |
|
108 |
||
109 |
If an object implements IHasDrivers it lists all drivers of the object and |
|
110 |
possible parent objects. The method isOneOfDrivers lets us check for those. |
|
111 |
||
112 |
>>> productseries = factory.makeProductSeries(product=product) |
|
113 |
>>> print roles.isDriver(productseries) |
|
114 |
False |
|
115 |
>>> print roles.isOneOfDrivers(productseries) |
|
116 |
True |
|
117 |
||
118 |
||
119 |
== isOneOf == |
|
120 |
||
121 |
Finally, sometimes a person may be one of multiple roles for an object. The |
|
122 |
method isOneOf makes checking all of these a breeze. |
|
123 |
||
124 |
>>> spec = factory.makeSpecification() |
|
125 |
>>> spec.assignee = person |
|
126 |
>>> print roles.isOwner(spec) |
|
127 |
False |
|
128 |
>>> print roles.isOneOf(spec, ['owner', 'approver', 'assignee']) |
|
129 |
True |