~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/registry/doc/private-team-visibility.txt

  • Committer: James Westby
  • Date: 2011-12-21 15:57:03 UTC
  • mto: This revision was merged to the branch mainline in revision 14568.
  • Revision ID: james.westby@canonical.com-20111221155703-eax3knjnxr33f6ci
Add the new file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=========================
 
2
 Private team visibility
 
3
=========================
 
4
 
 
5
Private teams restrict the visibility of their attributes to select
 
6
sets of users in order to prevent leaking confidential data.
 
7
 
 
8
Private teams restrict the viewing of the membership list
 
9
to team administrators, other members of the team, and Launchpad
 
10
administrators .
 
11
 
 
12
    >>> from lp.registry.interfaces.person import PersonVisibility
 
13
    >>> from lp.testing import login_celebrity
 
14
 
 
15
    >>> priv_owner = factory.makePerson(name="priv-owner")
 
16
    >>> priv_member = factory.makePerson(name="priv-member")
 
17
    >>> commercial_admin = login_celebrity('commercial_admin')
 
18
    >>> priv_team = factory.makeTeam(owner=priv_owner, name="priv-team",
 
19
    ...                              visibility=PersonVisibility.PRIVATE)
 
20
    >>> login_person(priv_owner)
 
21
    >>> ignored = priv_team.addMember(priv_member, reviewer=priv_owner)
 
22
 
 
23
The team owner can see the membership.
 
24
 
 
25
    >>> members = priv_team.activemembers
 
26
    >>> for member in members:
 
27
    ...     print member.name
 
28
    priv-member
 
29
    priv-owner
 
30
 
 
31
A team member can access the membership.
 
32
 
 
33
    >>> login_person(priv_member)
 
34
    >>> members = priv_team.activemembers
 
35
 
 
36
A commercial admin can view private teams and private team memberships.
 
37
 
 
38
    >>> from canonical.launchpad.webapp.authorization import check_permission
 
39
 
 
40
    >>> commercial_admin = login_celebrity('commercial_admin')
 
41
    >>> check_permission('launchpad.View', priv_team)
 
42
    True
 
43
    >>> team_membership = priv_member.team_memberships[0]
 
44
    >>> check_permission('launchpad.View', team_membership)
 
45
    True
 
46
 
 
47
A person who is not in the team cannot see the membership and cannot
 
48
see other details of the team, such as the name.
 
49
 
 
50
    >>> login('no-priv@canonical.com')
 
51
    >>> members = priv_team.activemembers
 
52
    Traceback (most recent call last):
 
53
    ...
 
54
    Unauthorized: (<Person at ... priv-team (Priv Team)>,
 
55
        'activemembers', 'launchpad.View')
 
56
 
 
57
    >>> print priv_team.name
 
58
    Traceback (most recent call last):
 
59
    ...
 
60
    Unauthorized: (<Person at ... priv-team (Priv Team)>,
 
61
        'name', 'launchpad.LimitedView')
 
62
 
 
63
Public teams can join private teams.  When adding one team to another
 
64
the team is invited to join and that invitation must be accepted by
 
65
one of the invited team's admins.  Normally the admin of the invited
 
66
team is not a member of the private team and therefore cannot even see
 
67
the page to accept the invitation!  To resolve that situation the
 
68
rules for viewing a private team include admins of invited teams.
 
69
 
 
70
    >>> pub_owner = factory.makePerson(name="pub-owner")
 
71
    >>> pub_member = factory.makePerson(name="pub-member")
 
72
    >>> pub_team = factory.makeTeam(owner=pub_owner, name="pubteam")
 
73
    >>> login_person(pub_owner)
 
74
    >>> ignored = pub_team.addMember(pub_member, reviewer=pub_owner)
 
75
 
 
76
At this point the public team owner cannot see the priv-team's bits.
 
77
 
 
78
    >>> print priv_team.name
 
79
    Traceback (most recent call last):
 
80
    ...
 
81
    Unauthorized: (<Person at ... priv-team (Priv Team)>,
 
82
        'name', 'launchpad.LimitedView')
 
83
 
 
84
    >>> login_person(priv_owner)
 
85
    >>> ignored = priv_team.addMember(pub_team, reviewer=priv_owner)
 
86
 
 
87
The public team is not yet a member of the priv-team.
 
88
 
 
89
    >>> pub_team in priv_team.activemembers
 
90
    False
 
91
    >>> pub_owner in priv_team.activemembers
 
92
    False
 
93
 
 
94
The public team's owner can now see the priv-team's bits since his team
 
95
has been invited to join.
 
96
 
 
97
    >>> login_person(pub_owner)
 
98
    >>> print priv_team.name
 
99
    priv-team
 
100
 
 
101
But a non-admin member of the public team still cannot see anything
 
102
about the team.
 
103
 
 
104
    >>> login_person(pub_member)
 
105
    >>> print priv_team.name
 
106
    Traceback (most recent call last):
 
107
    ...
 
108
    Unauthorized: (<Person at ... priv-team (Priv Team)>,
 
109
        'name', 'launchpad.LimitedView')
 
110
 
 
111
A person with visibility to any of the branches owned by the private team will
 
112
be granted limited view permission on the team.
 
113
 
 
114
For private branches, a user needs to be subscribed to the branch for the
 
115
branch (and hence team) to be visible.
 
116
 
 
117
    >>> login_person(priv_owner)
 
118
    >>> private_team_branch = factory.makeBranch(
 
119
    ...     owner=priv_team, private=True)
 
120
    >>> login_person(pub_member)
 
121
    >>> check_permission('launchpad.LimitedView', priv_team)
 
122
    False
 
123
 
 
124
    >>> login_person(priv_owner)
 
125
    >>> sub = factory.makeBranchSubscription(
 
126
    ...     branch=private_team_branch, person=pub_member,
 
127
    ...     subscribed_by=priv_owner)
 
128
 
 
129
    >>> login_person(pub_member)
 
130
    >>> check_permission('launchpad.LimitedView', priv_team)
 
131
    True
 
132
 
 
133
User who can see a branch can also see private teams for which reviews have
 
134
been requested.
 
135
    >>> some_person = factory.makePerson()
 
136
    >>> login_person(priv_owner)
 
137
    >>> product = factory.makeProduct()
 
138
    >>> target_branch = factory.makeBranch(
 
139
    ...     owner=priv_owner, private=True, product=product)
 
140
    >>> source_branch = factory.makeBranch(
 
141
    ...     owner=priv_owner, product=product)
 
142
    >>> bmp = factory.makeBranchMergeProposal(
 
143
    ...     source_branch=source_branch, target_branch=target_branch,
 
144
    ...     reviewer=priv_team, registrant=priv_owner)
 
145
    >>> login_person(some_person)
 
146
    >>> check_permission('launchpad.LimitedView', priv_team)
 
147
    False
 
148
    >>> login_person(priv_owner)
 
149
    >>> sub = factory.makeBranchSubscription(
 
150
    ...     branch=target_branch, person=some_person,
 
151
    ...     subscribed_by=priv_owner)
 
152
 
 
153
    >>> login_person(some_person)
 
154
    >>> check_permission('launchpad.LimitedView', priv_team)
 
155
    True
 
156
 
 
157
Subscribers to the teams private PPA have limited view permission.
 
158
 
 
159
    >>> login_person(priv_owner)
 
160
    >>> archive = factory.makeArchive(private=True, owner=priv_team)
 
161
    >>> archive_subscriber = factory.makePerson()
 
162
    >>> sub = archive.newSubscription(
 
163
    ...     archive_subscriber, registrant=archive.owner)
 
164
 
 
165
    >>> login_person(archive_subscriber)
 
166
    >>> check_permission('launchpad.LimitedView', priv_team)
 
167
    True
 
168
 
 
169
Users with LimitedView can know identifying information like name,
 
170
displayname, and unique_name, but cannot know other information like
 
171
teamowner.
 
172
 
 
173
    >>> print priv_team.name
 
174
    priv-team
 
175
 
 
176
    >>> print priv_team.displayname
 
177
    Priv Team
 
178
 
 
179
    >>> print priv_team.unique_displayname
 
180
    Priv Team (priv-team)
 
181
 
 
182
    >>> print priv_team.icon
 
183
    None
 
184
 
 
185
    >>> print priv_team.allmembers
 
186
    Traceback (most recent call last):
 
187
    ...
 
188
    Unauthorized: (<Person at ... priv-team (Priv Team)>,
 
189
        'allmembers', 'launchpad.View')
 
190
 
 
191
Anonymous users do not have permission.
 
192
    >>> login(ANONYMOUS)
 
193
    >>> check_permission('launchpad.LimitedView', priv_team)
 
194
    False
 
195
 
 
196
A team owner must be able to access the team even if they are not a team
 
197
member. When a team is created, the owner is automatically made an admin
 
198
member. So we revoke that membership and check that they still have access.
 
199
    >>> from lp.registry.interfaces.teammembership import (
 
200
    ...     ITeamMembershipSet,
 
201
    ...     TeamMembershipStatus,
 
202
    ...     )
 
203
    >>> membership_set = getUtility(ITeamMembershipSet)
 
204
    >>> login_person(priv_owner)
 
205
    >>> tm = membership_set.getByPersonAndTeam(priv_owner, priv_team)
 
206
    >>> tm.setStatus(TeamMembershipStatus.DEACTIVATED, priv_owner)
 
207
    True
 
208
    >>> priv_owner.inTeam(priv_team)
 
209
    False
 
210
    >>> check_permission('launchpad.View', priv_team)
 
211
    True