~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).

# pylint: disable-msg=E0213

"""ArchivePermission interface."""

__metaclass__ = type

__all__ = [
    'IArchivePermission',
    'IArchivePermissionSet',
    'IArchiveUploader',
    'IArchiveQueueAdmin',
    ]

from lazr.restful.declarations import (
    export_as_webservice_entry,
    exported,
    )
from lazr.restful.fields import Reference
from zope.interface import (
    Attribute,
    Interface,
    )
from zope.schema import (
    Bool,
    Choice,
    Datetime,
    TextLine,
    )

from lp import _
from lp.registry.interfaces.sourcepackagename import ISourcePackageName
from lp.services.fields import PublicPersonChoice
from lp.soyuz.enums import ArchivePermissionType
from lp.soyuz.interfaces.archive import IArchive
from lp.soyuz.interfaces.component import IComponent
from lp.soyuz.interfaces.packageset import IPackageset


class IArchivePermission(Interface):
    """The interface for `ArchivePermission`."""
    export_as_webservice_entry(publish_web_link=False)

    id = Attribute("The archive permission ID.")

    date_created = exported(
        Datetime(
            title=_('Date Created'), required=False, readonly=False,
            description=_("The timestamp when the permission was created.")))

    archive = exported(
        Reference(
            IArchive,
            title=_("Archive"),
            description=_("The archive that this permission is for.")))

    permission = exported(
        Choice(
            title=_("The permission type being granted."),
            values=ArchivePermissionType, readonly=False, required=True))

    person = exported(
        PublicPersonChoice(
            title=_("Person"),
            description=_("The person or team being granted the permission."),
            required=True, vocabulary="ValidPersonOrTeam"))

    component = Reference(
        IComponent,
        title=_("Component"),
        description=_("The component that this permission is related to."))

    sourcepackagename = Reference(
        ISourcePackageName,
        title=_("Source Package Name"),
        description=_("The source package name that this permission is "
                      "related to."))

    # This is the *text* component name, as opposed to `component` above
    # which is the `IComponent` and we don't want to export that.
    component_name = exported(
        TextLine(
            title=_("Component Name"),
            required=True))

    # This is the *text* package name, as opposed to `sourcepackagename`
    # which is the `ISourcePackageName` and we don't want to export
    # that.
    source_package_name = exported(
        TextLine(
            title=_("Source Package Name"),
            required=True))

    packageset = Reference(
            IPackageset,
            title=_("Packageset"),
            description=_("The package set that this permission is for."))

    explicit = exported(
        Bool(
            title=_("Explicit"),
            description=_(
                "Set this flag for package sets with high-profile packages "
                "requiring specialist skills for proper handling.")))

    package_set_name = exported(
        TextLine(
            title=_("Package set name"),
            required=True))

    distro_series_name = exported(
        TextLine(
            title=_(
                "The name of the distro series associated with the "
                "package set."),
            required=True))


class IArchiveUploader(IArchivePermission):
    """Marker interface for URL traversal of uploader permissions."""


class IArchiveQueueAdmin(IArchivePermission):
    """Marker interface for URL traversal of queue admin permissions."""


class IArchivePermissionSet(Interface):
    """The interface for `ArchivePermissionSet`."""

    # Do not export this utility directly on the webservice.  There is
    # no reasonable security model we can implement for it because it
    # requires the archive context to be able to make an informed
    # security decision.
    #
    # For this reason, the security declaration in the zcml is
    # deliberately permissive.  We don't expect anything to access this
    # utility except the IArchive code, which is appropriately protected.

    def checkAuthenticated(person, archive, permission, item):
        """The `ArchivePermission` records that authenticate the person.

        :param person: An `IPerson` whom should be checked for authentication.
        :param archive: The context `IArchive` for the permission check.
        :param permission: The `ArchivePermissionType` to check.
        :param item: The context `IComponent` or `ISourcePackageName` for the
            permission check.

        :return: all the `ArchivePermission` records that match the parameters
        supplied.  If none are returned, it means the person is not
        authenticated in that context.
        """

    def permissionsForPerson(person, archive):
        """All `ArchivePermission` records for the person.

        :param person: An `IPerson`
        :param archive: An `IArchive`
        """

    def uploadersForComponent(archive, component=None):
        """The `ArchivePermission` records for authorised component uploaders.

        :param archive: The context `IArchive` for the permission check.
        :param component: Optional `IComponent`, if specified will only
            return records for uploaders to that component, otherwise
            all components are considered.  You can also supply a string
            component name instead.
        :raises ComponentNotFound: if the named component does not exist.

        :return: `ArchivePermission` records for all the uploaders who
            are authorised for the supplied component.
        """

    def componentsForUploader(archive, person):
        """The `ArchivePermission` records for the person's upload components.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to find out which
            components he has access to.

        :return: `ArchivePermission` records for all the components that
            'person' is allowed to upload to.
        """

    def packagesForUploader(archive, person):
        """The `ArchivePermission` records for the person's upload packages.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to find out which
            packages he has access to.

        :return: `ArchivePermission` records for all the packages that
            'person' is allowed to upload to.
        """

    def uploadersForPackage(archive, sourcepackagename):
        """The `ArchivePermission` records for authorised package uploaders.

        :param archive: The context `IArchive` for the permission check.
        :param sourcepackagename: An `ISourcePackageName` or a string
            package name.
        :raises SourceNotFound: if the string package name does not exist.

        :return: `ArchivePermission` records for all the uploaders who are
            authorised to upload the named source package.
        """

    def packagesetsForUploader(archive, person):
        """The `ArchivePermission` records for the person's package sets.

        :param archive: The archive the permission applies to.
        :param person: An `IPerson` for whom you want to find out which
            package sets he has access to.

        :return: `ArchivePermission` records for all the package sets that
            'person' is allowed to upload to.
        """

    def packagesetsForSourceUploader(archive, sourcepackagename, person):
        """The package set based permissions for a given source and uploader.

        Return the `IArchivePermission` records that
            * apply to the given `archive`
            * relate to
                - package sets that include the given source package name
                - the given `person`

        :param archive: The archive the permission applies to.
        :param sourcepackagename: the source package name; can be
            either a string or a `ISourcePackageName`.
        :param person: An `IPerson` for whom you want to find out which
            package sets he has access to.

        :raises SourceNotFound: if a source package with the given
            name could not be found.
        :return: `ArchivePermission` records for the package sets that
            include the given source package name and to which the given
            person may upload.
        """

    def packagesetsForSource(
        archive, sourcepackagename, direct_permissions=True):
        """All package set based permissions for the given archive and source.

        This method is meant to aid the process of "debugging" package set
        based archive permission since It allows the listing of permissions
        for the given source package irrespective of a person.

        :param archive: The archive the permission applies to.
        :param sourcepackagename: the source package name; can be
            either a string or a `ISourcePackageName`.
        :param direct_permissions: If set, only package sets that directly
            include the given source will be considered.

        :raises SourceNotFound: if a source package with the given
            name could not be found.
        :return: `ArchivePermission` records for the package sets that
            include the given source package name and apply to the
            archive in question.
        """

    def isSourceUploadAllowed(
        archive, sourcepackagename, person, distroseries=None):
        """True if the person is allowed to upload the given source package.

        Return True if there exists a permission that combines
            * the given `archive`
            * a package set that includes the given source package name
            * the given person or a team he is a member of

        If the source package name is included by *any* package set with
        an explicit permission then only such explicit permissions will
        be considered.

        :param archive: The archive the permission applies to.
        :param sourcepackagename: the source package name; can be
            either a string or a `ISourcePackageName`.
        :param person: An `IPerson` for whom you want to find out which
            package sets he has access to.
        :param distroseries: The `IDistroSeries` for which to check
            permissions. If none is supplied then `currentseries` in
            Ubuntu is assumed.

        :raises SourceNotFound: if a source package with the given
            name could not be found.
        :return: True if the person is allowed to upload the source package.
        """

    def uploadersForPackageset(archive, packageset, direct_permissions=True):
        """The `ArchivePermission` records for uploaders to the package set.

        Please note: if a package set *name* is passed the respective
                     package set in the current distro series will be used.

        :param archive: The archive the permission applies to.
        :param packageset: An `IPackageset` or a string package set name.
        :param direct_permissions: If True only consider permissions granted
            directly for the package set at hand. Otherwise, include any
            uploaders for package sets that include this one.
        :raises NotFoundError: if no package set exists with the given name.

        :return: `ArchivePermission` records for all the uploaders who are
            authorized to upload to the named source package set.
        """

    def queueAdminsForComponent(archive, component):
        """The `ArchivePermission` records for authorised queue admins.

        :param archive: The context `IArchive` for the permission check.
        :param component: The context `IComponent` for the permission check.
            You can also supply a string component name instead.

        :return: `ArchivePermission` records for all the person who are
            allowed to administer the distroseries upload queue.
        """

    def componentsForQueueAdmin(archive, person):
        """Return `ArchivePermission` for the person's queue admin components.

        :param archive: The context `IArchive` for the permission check, or
            an iterable of `IArchive`s.
        :param person: An `IPerson` for whom you want to find out which
            components he has access to.

        :return: `ArchivePermission` records for all the components that
            'person' is allowed to administer the queue for.
        """

    def newPackageUploader(archive, person, sourcepackagename):
        """Create and return a new `ArchivePermission` for an uploader.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to add permission.
        :param sourcepackagename: An `ISourcePackageName` or a string
            package name.

        :return: The new `ArchivePermission`, or the existing one if it
            already exists.
        """

    def newPackagesetUploader(archive, person, packageset, explicit=False):
        """Create and return a new `ArchivePermission` for an uploader.

        Please note: if a package set *name* is passed the respective
                     package set in the current distro series will be used.

        :param archive: The archive the permission applies to.
        :param person: An `IPerson` for whom you want to add permission.
        :param packageset: An `IPackageset` or a string package set name.
        :param explicit: True if the permissions granted by this package set
            exclude permissions granted by non-explicit package sets.
        :raises ValueError: if an `ArchivePermission` record for this
            person and packageset already exists *but* with a different
            'explicit' flag value.

        :return: The new `ArchivePermission`, or the existing one if it
            already exists.
        """

    def newComponentUploader(archive, person, component):
        """Create and return a new `ArchivePermission` for an uploader.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to add permission.
        :param component: An `IComponent` or a string package name.

        :return: The new `ArchivePermission`, or the existing one if it
            already exists.
        """

    def newQueueAdmin(archive, person, component):
        """Create and return a new `ArchivePermission` for a queue admin.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to add permission.
        :param component: An `IComponent` or a string package name.

        :return: The new `ArchivePermission`, or the existing one if it
            already exists.
        """

    def deletePackageUploader(archive, person, sourcepackagename):
        """Revoke upload permissions for a person.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to revoke permission.
        :param sourcepackagename: An `ISourcePackageName` or a string
            package name.
        """

    def deletePackagesetUploader(archive, person, packageset, explicit=False):
        """Revoke upload permissions for a person.

        Please note: if a package set *name* is passed the respective
                     package set in the current distro series will be used.

        :param archive: The archive the permission applies to.
        :param person: An `IPerson` for whom you want to revoke permission.
        :param packageset: An `IPackageset` or a string package set name.
        :param explicit: The value of the 'explicit' flag for the permission
            to be revoked.
        """

    def deleteComponentUploader(archive, person, component):
        """Revoke upload permissions for a person.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to revoke permission.
        :param component: An `IComponent` or a string package name.
        """

    def deleteQueueAdmin(archive, person, component):
        """Revoke queue admin permissions for a person.

        :param archive: The context `IArchive` for the permission check.
        :param person: An `IPerson` for whom you want to revoke permission.
        :param component: An `IComponent` or a string package name.
        """