~launchpad-pqm/launchpad/devel

12467.2.5 by j.c.sackett
Copyright notices.
1
# Copyright 2010-2011 Canonical Ltd.  This software is licensed under the
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
"""Security adapters for the bugs module."""
5
6
__metaclass__ = type
7
__all__ = []
8
14186.3.3 by Ian Booth
Implement code review changes
9
from zope.component import getUtility
10
11
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
12927.1.2 by Henning Eggers
Moved AuthorizationBAse.
12
from lp.app.security import (
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
13
    AnonymousAuthorization,
14
    AuthorizationBase,
13843.9.9 by Brad Crittenden
Merged ForwardedAuthorization and DerivedAuthorization to become DelegatedAuthorization
15
    DelegatedAuthorization,
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
16
    )
17
from lp.bugs.interfaces.bug import IBug
18
from lp.bugs.interfaces.bugattachment import IBugAttachment
19
from lp.bugs.interfaces.bugbranch import IBugBranch
20
from lp.bugs.interfaces.bugnomination import IBugNomination
21
from lp.bugs.interfaces.bugsubscription import IBugSubscription
11526.4.40 by Gavin Panella
Security adapter for IBugSubscriptionFilter.
22
from lp.bugs.interfaces.bugsubscriptionfilter import IBugSubscriptionFilter
14186.3.3 by Ian Booth
Implement code review changes
23
from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor
14142.1.4 by Ian Booth
Tweak security config to use new IBugTaskDelete interface and web service test
24
from lp.bugs.interfaces.bugtask import IBugTaskDelete
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
25
from lp.bugs.interfaces.bugtracker import IBugTracker
26
from lp.bugs.interfaces.bugwatch import IBugWatch
14612.2.1 by William Grant
format-imports on lib/. So many imports.
27
from lp.bugs.interfaces.hasbug import IHasBug
7675.1025.1 by Gary Poster
structural subscriptions are moved from registry to bugs. moved tests pass.
28
from lp.bugs.interfaces.structuralsubscription import IStructuralSubscription
14186.3.3 by Ian Booth
Implement code review changes
29
from lp.registry.interfaces.role import IHasOwner
14550.1.1 by Steve Kowalik
Run format-imports over lib/lp and lib/canonical/launchpad
30
from lp.services.messages.interfaces.message import IMessage
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
31
12467.2.4 by j.c.sackett
Lint fixes.
32
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
33
class EditBugNominationStatus(AuthorizationBase):
34
    permission = 'launchpad.Driver'
35
    usedfor = IBugNomination
36
37
    def checkAuthenticated(self, user):
38
        return self.obj.canApprove(user.person)
39
40
41
class EditBugTask(AuthorizationBase):
42
    """Permission checker for editing objects linked to a bug.
43
44
    Allow any logged-in user to edit objects linked to public
45
    bugs. Allow only explicit subscribers to edit objects linked to
46
    private bugs.
47
    """
48
    permission = 'launchpad.Edit'
49
    usedfor = IHasBug
50
51
    def checkAuthenticated(self, user):
52
        # Delegated entirely to the bug.
53
        return self.obj.bug.userCanView(user)
54
55
14142.1.1 by Ian Booth
Add api to delete bug tasks
56
class DeleteBugTask(AuthorizationBase):
57
    permission = 'launchpad.Delete'
14142.1.4 by Ian Booth
Tweak security config to use new IBugTaskDelete interface and web service test
58
    usedfor = IBugTaskDelete
14142.1.1 by Ian Booth
Add api to delete bug tasks
59
60
    def checkAuthenticated(self, user):
14186.3.3 by Ian Booth
Implement code review changes
61
        """Check that a user may delete a bugtask.
62
63
        A user may delete a bugtask if:
64
         - project maintainer
65
         - task creator
66
         - bug supervisor
67
        """
68
        if user is None:
69
            return False
70
71
        # Admins can always delete bugtasks.
72
        if user.inTeam(getUtility(ILaunchpadCelebrities).admin):
73
            return True
74
14142.1.1 by Ian Booth
Add api to delete bug tasks
75
        bugtask = self.obj
14186.3.3 by Ian Booth
Implement code review changes
76
        owner = None
77
        if IHasOwner.providedBy(bugtask.pillar):
78
            owner = bugtask.pillar.owner
79
        bugsupervisor = None
80
        if IHasBugSupervisor.providedBy(bugtask.pillar):
81
            bugsupervisor = bugtask.pillar.bug_supervisor
82
        return (
83
            user.inTeam(owner) or
84
            user.inTeam(bugsupervisor) or
85
            user.inTeam(bugtask.owner))
14142.1.1 by Ian Booth
Add api to delete bug tasks
86
87
14142.2.1 by Ian Booth
Allow admins to delete bug tasks
88
class AdminDeleteBugTask(DeleteBugTask):
89
    """Launchpad admins can also delete bug tasks."""
90
    permission = 'launchpad.Admin'
91
92
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
93
class PublicToAllOrPrivateToExplicitSubscribersForBugTask(AuthorizationBase):
94
    permission = 'launchpad.View'
95
    usedfor = IHasBug
96
97
    def checkAuthenticated(self, user):
98
        return self.obj.bug.userCanView(user.person)
99
100
    def checkUnauthenticated(self):
101
        """Allow anonymous users to see non-private bugs only."""
102
        return not self.obj.bug.private
103
104
105
class EditPublicByLoggedInUserAndPrivateByExplicitSubscribers(
106
    AuthorizationBase):
107
    permission = 'launchpad.Edit'
108
    usedfor = IBug
109
110
    def checkAuthenticated(self, user):
111
        """Allow any logged in user to edit a public bug, and only
12278.1.1 by Graham Binns
Reverted the reversion of devel r12272.
112
        explicit subscribers to edit private bugs. Any bug that can be
113
        seen can be edited.
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
114
        """
115
        return self.obj.userCanView(user)
116
117
    def checkUnauthenticated(self):
118
        """Never allow unauthenticated users to edit a bug."""
119
        return False
120
121
122
class PublicToAllOrPrivateToExplicitSubscribersForBug(AuthorizationBase):
123
    permission = 'launchpad.View'
124
    usedfor = IBug
125
126
    def checkAuthenticated(self, user):
127
        """Allow any user to see non-private bugs, but only explicit
128
        subscribers to see private bugs.
129
        """
130
        return self.obj.userCanView(user.person)
131
132
    def checkUnauthenticated(self):
133
        """Allow anonymous users to see non-private bugs only."""
134
        return not self.obj.private
135
136
137
class EditBugBranch(EditPublicByLoggedInUserAndPrivateByExplicitSubscribers):
138
    permission = 'launchpad.Edit'
139
    usedfor = IBugBranch
140
141
    def __init__(self, bug_branch):
142
        # The same permissions as for the BugBranch's bug should apply
143
        # to the BugBranch itself.
13843.9.2 by Brad Crittenden
Remove direct specification of security adapters in favor of using ForwardedAuthorization
144
        super(EditBugBranch, self).__init__(bug_branch.bug)
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
145
146
13843.9.9 by Brad Crittenden
Merged ForwardedAuthorization and DerivedAuthorization to become DelegatedAuthorization
147
class ViewBugAttachment(DelegatedAuthorization):
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
148
    """Security adapter for viewing a bug attachment.
149
150
    If the user is authorized to view the bug, he's allowed to view the
151
    attachment.
152
    """
153
    permission = 'launchpad.View'
154
    usedfor = IBugAttachment
155
156
    def __init__(self, bugattachment):
13843.9.11 by Brad Crittenden
Added saving of obj to DelegatedAuthorization
157
        super(ViewBugAttachment, self).__init__(
158
            bugattachment, bugattachment.bug)
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
159
160
13843.9.9 by Brad Crittenden
Merged ForwardedAuthorization and DerivedAuthorization to become DelegatedAuthorization
161
class EditBugAttachment(DelegatedAuthorization):
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
162
    """Security adapter for editing a bug attachment.
163
164
    If the user is authorized to view the bug, he's allowed to edit the
165
    attachment.
166
    """
167
    permission = 'launchpad.Edit'
168
    usedfor = IBugAttachment
169
170
    def __init__(self, bugattachment):
13843.9.11 by Brad Crittenden
Added saving of obj to DelegatedAuthorization
171
        super(EditBugAttachment, self).__init__(
172
            bugattachment, bugattachment.bug)
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
173
174
175
class ViewBugSubscription(AnonymousAuthorization):
176
177
    usedfor = IBugSubscription
178
179
12278.1.1 by Graham Binns
Reverted the reversion of devel r12272.
180
class EditBugSubscription(AuthorizationBase):
181
    permission = 'launchpad.Edit'
182
    usedfor = IBugSubscription
183
184
    def checkAuthenticated(self, user):
185
        """Check that a user may edit a subscription.
186
187
        A user may edit a subscription if:
188
         - They are the owner of the subscription.
189
         - They are the owner of the team that owns the subscription.
190
         - They are an admin of the team that owns the subscription.
191
        """
14449.6.1 by Curtis Hovey
Remove isTeam(). Replace calls with .is_team.
192
        if self.obj.person.is_team:
12278.1.1 by Graham Binns
Reverted the reversion of devel r12272.
193
            return (
194
                self.obj.person.teamowner == user.person or
195
                user.person in self.obj.person.adminmembers)
196
        else:
197
            return user.person == self.obj.person
198
199
11526.1.1 by Gavin Panella
Move bugs-specific security adapters to lp.bugs.security.
200
class ViewBugMessage(AnonymousAuthorization):
201
202
    usedfor = IMessage
203
204
205
class ViewBugTracker(AnonymousAuthorization):
206
    """Anyone can view a bug tracker."""
207
    usedfor = IBugTracker
208
209
210
class EditBugTracker(AuthorizationBase):
211
    permission = 'launchpad.Edit'
212
    usedfor = IBugTracker
213
214
    def checkAuthenticated(self, user):
215
        """Any logged-in user can edit a bug tracker."""
216
        return True
217
218
219
class AdminBugTracker(AuthorizationBase):
220
    permission = 'launchpad.Admin'
221
    usedfor = IBugTracker
222
223
    def checkAuthenticated(self, user):
224
        return (
225
            user.in_janitor or
226
            user.in_admin or
227
            user.in_launchpad_developers)
228
229
230
class AdminBugWatch(AuthorizationBase):
231
    permission = 'launchpad.Admin'
232
    usedfor = IBugWatch
233
234
    def checkAuthenticated(self, user):
235
        return (
236
            user.in_admin or
237
            user.in_launchpad_developers)
11526.4.40 by Gavin Panella
Security adapter for IBugSubscriptionFilter.
238
239
7675.1025.1 by Gary Poster
structural subscriptions are moved from registry to bugs. moved tests pass.
240
class EditStructuralSubscription(AuthorizationBase):
241
    """Edit permissions for `IStructuralSubscription`."""
242
    permission = "launchpad.Edit"
243
    usedfor = IStructuralSubscription
244
245
    def checkAuthenticated(self, user):
246
        """Subscribers can edit their own structural subscriptions."""
247
        return user.inTeam(self.obj.subscriber)
248
249
11526.4.40 by Gavin Panella
Security adapter for IBugSubscriptionFilter.
250
class EditBugSubscriptionFilter(AuthorizationBase):
251
    """Bug subscription filters may only be modified by the subscriber."""
252
    permission = 'launchpad.Edit'
253
    usedfor = IBugSubscriptionFilter
254
255
    def checkAuthenticated(self, user):
256
        return (
257
            self.obj.structural_subscription is None or
258
            user.inTeam(self.obj.structural_subscription.subscriber))