~launchpad-pqm/launchpad/devel

14557.1.20 by Curtis Hovey
Updated copyright.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.15 by Karl Fogel
Add the copyright header block to files under lib/lp/bugs/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3598.1.1 by Brad Bollenbach
checkpoint
3
4
"""XML-RPC APIs for Malone."""
5
6
__metaclass__ = type
6002.3.8 by Graham Binns
Actually committed the changes for the token generator. Whoops.
7
__all__ = ["FileBugAPI", "ExternalBugTrackerTokenAPI"]
3598.1.1 by Brad Bollenbach
checkpoint
8
3598.1.6 by Brad Bollenbach
checkpoint
9
from zope.component import getUtility
6002.3.8 by Graham Binns
Actually committed the changes for the token generator. Whoops.
10
from zope.interface import implements
3598.1.6 by Brad Bollenbach
checkpoint
11
14557.1.9 by Curtis Hovey
Moved logintoken to lp.verification.
12
from lp.services.verification.interfaces.authtoken import LoginTokenType
13
from lp.services.verification.interfaces.logintoken import ILoginTokenSet
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
14
from canonical.launchpad.webapp import (
15
    canonical_url,
16
    LaunchpadXMLRPCView,
17
    )
18
from canonical.launchpad.xmlrpc import faults
11270.1.3 by Tim Penhey
Changed NotFoundError imports - gee there were a lot of them.
19
from lp.app.errors import NotFoundError
8523.3.1 by Gavin Panella
Bugs tree reorg after automated migration.
20
from lp.bugs.interfaces.bug import CreateBugParams
21
from lp.bugs.interfaces.externalbugtracker import IExternalBugTrackerTokenAPI
22
from lp.registry.interfaces.distribution import IDistributionSet
23
from lp.registry.interfaces.person import IPersonSet
24
from lp.registry.interfaces.product import IProductSet
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
25
3598.1.1 by Brad Bollenbach
checkpoint
26
27
class FileBugAPI(LaunchpadXMLRPCView):
3598.1.6 by Brad Bollenbach
checkpoint
28
    """The XML-RPC API for filing bugs in Malone."""
29
3598.1.25 by Brad Bollenbach
incorporate feedback from paris sprint
30
    def filebug(self, params):
31
        """Report a bug in a distribution or product.
32
33
        :params: A dict containing the following keys:
34
35
        REQUIRED:
3598.1.31 by Brad Bollenbach
response to code review
36
          summary: A string
37
          comment: A string
3598.1.25 by Brad Bollenbach
incorporate feedback from paris sprint
38
39
        OPTIONAL:
3598.1.31 by Brad Bollenbach
response to code review
40
          product: The product name, as a string. Default None.
41
          distro: The distro name, as a string. Default None.
42
          package: A string, allowed only if distro is specified.
43
                   Default None.
44
          security_related: Is this a security vulnerability?
45
                            Default False.
46
          subscribers: A list of email addresses. Default None.
47
48
        Either product or distro must be provided.
3598.1.25 by Brad Bollenbach
incorporate feedback from paris sprint
49
        """
50
        product = params.get('product')
51
        distro = params.get('distro')
52
        package = params.get('package')
53
        summary = params.get('summary')
54
        comment = params.get('comment')
55
        security_related = params.get('security_related')
56
        subscribers = params.get('subscribers')
57
3598.1.12 by Brad Bollenbach
checkpoint
58
        if product and distro:
59
            return faults.FileBugGotProductAndDistro()
60
3598.1.6 by Brad Bollenbach
checkpoint
61
        if product:
62
            target = getUtility(IProductSet).getByName(product)
3598.1.12 by Brad Bollenbach
checkpoint
63
            if target is None:
64
                return faults.NoSuchProduct(product)
3598.1.6 by Brad Bollenbach
checkpoint
65
        elif distro:
3598.1.14 by Brad Bollenbach
get all xmlrpc error handling tests passing
66
            distro_object = getUtility(IDistributionSet).getByName(distro)
67
68
            if distro_object is None:
3598.1.12 by Brad Bollenbach
checkpoint
69
                return faults.NoSuchDistribution(distro)
3598.1.14 by Brad Bollenbach
get all xmlrpc error handling tests passing
70
71
            if package:
72
                try:
13155.2.1 by Francis J. Lacoste
Made guessPackageNames return only the source package name. Renamed it to guessPublishedSourcePackageName. Convert its tests to unit tests. Get rid of the Binary package hint: comment.
73
                    spname = distro_object.guessPublishedSourcePackageName(
74
                        package)
3598.1.14 by Brad Bollenbach
get all xmlrpc error handling tests passing
75
                except NotFoundError:
76
                    return faults.NoSuchPackage(package)
77
78
                target = distro_object.getSourcePackage(spname)
79
            else:
80
                target = distro_object
3598.1.12 by Brad Bollenbach
checkpoint
81
        else:
82
            return faults.FileBugMissingProductOrDistribution()
3598.1.6 by Brad Bollenbach
checkpoint
83
3598.1.25 by Brad Bollenbach
incorporate feedback from paris sprint
84
        if not summary:
85
            return faults.RequiredParameterMissing('summary')
3598.1.14 by Brad Bollenbach
get all xmlrpc error handling tests passing
86
87
        if not comment:
88
            return faults.RequiredParameterMissing('comment')
89
3598.1.18 by Brad Bollenbach
ensure an SQLObjectCreatedEvent is also published when reporting a bug via xmlrpc
90
        # Convert arguments into values that IBugTarget.createBug
91
        # understands.
3598.1.10 by Brad Bollenbach
checkpoint
92
        personset = getUtility(IPersonSet)
3598.1.14 by Brad Bollenbach
get all xmlrpc error handling tests passing
93
        subscriber_list = []
3598.1.10 by Brad Bollenbach
checkpoint
94
        if subscribers:
3598.1.14 by Brad Bollenbach
get all xmlrpc error handling tests passing
95
            for subscriber_email in subscribers:
96
                subscriber = personset.getByEmail(subscriber_email)
97
                if not subscriber:
98
                    return faults.NoSuchPerson(
99
                        type="subscriber", email_address=subscriber_email)
100
                else:
101
                    subscriber_list.append(subscriber)
3598.1.10 by Brad Bollenbach
checkpoint
102
103
        security_related = bool(security_related)
104
3598.1.25 by Brad Bollenbach
incorporate feedback from paris sprint
105
        # Privacy is always set the same as security, by default.
106
        private = security_related
107
3598.1.10 by Brad Bollenbach
checkpoint
108
        params = CreateBugParams(
3598.1.25 by Brad Bollenbach
incorporate feedback from paris sprint
109
            owner=self.user, title=summary, comment=comment,
110
            security_related=security_related, private=private,
111
            subscribers=subscriber_list)
3598.1.18 by Brad Bollenbach
ensure an SQLObjectCreatedEvent is also published when reporting a bug via xmlrpc
112
3598.1.10 by Brad Bollenbach
checkpoint
113
        bug = target.createBug(params)
3598.1.6 by Brad Bollenbach
checkpoint
114
115
        return canonical_url(bug)
6002.3.5 by Graham Binns
Added stub implementation of the BugTokenAPI.
116
117
6002.3.8 by Graham Binns
Actually committed the changes for the token generator. Whoops.
118
class ExternalBugTrackerTokenAPI(LaunchpadXMLRPCView):
6002.3.5 by Graham Binns
Added stub implementation of the BugTokenAPI.
119
    """The private XML-RPC API for generating bug tracker login tokens."""
120
6002.3.8 by Graham Binns
Actually committed the changes for the token generator. Whoops.
121
    implements(IExternalBugTrackerTokenAPI)
122
6002.3.13 by Graham Binns
Altered other tests.
123
    def newBugTrackerToken(self):
6002.3.5 by Graham Binns
Added stub implementation of the BugTokenAPI.
124
        """Generate a new `LoginToken` for a bug tracker and return it.
125
126
        The `LoginToken` will be of `LoginTokenType` BUGTRACKER.
127
        """
6002.3.8 by Graham Binns
Actually committed the changes for the token generator. Whoops.
128
        login_token = getUtility(ILoginTokenSet).new(
129
            None, None, 'externalbugtrackers@launchpad.net',
130
            LoginTokenType.BUGTRACKER)
131
6002.4.1 by Graham Binns
newBugTrackerToken() now returns a token string.
132
        return login_token.token