~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/canonical/launchpad/webapp/servers.py

  • Committer: Steve Kowalik
  • Date: 2011-08-07 04:05:52 UTC
  • mto: This revision was merged to the branch mainline in revision 13626.
  • Revision ID: stevenk@ubuntu.com-20110807040552-mwnxo0flmhvl35e8
Correct the notification based on review comments, and remove request{,ed}
from the function names, switching to create{,d}.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
 
1
# Copyright 2009 Canonical Ltd.  This software is licensed under the
2
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
3
 
4
4
# pylint: disable-msg=W0231,E1002
34
34
from zope.app.server import wsgi
35
35
from zope.app.wsgi import WSGIPublisherApplication
36
36
from zope.component import getUtility
37
 
from zope.event import notify
38
37
from zope.interface import (
39
38
    alsoProvides,
40
39
    implements,
61
60
from zope.server.http.wsgihttpserver import PMDBWSGIHTTPServer
62
61
from zope.session.interfaces import ISession
63
62
 
64
 
from lp.app.errors import UnexpectedFormData
65
 
import lp.layers
66
 
from lp.services.config import config
67
 
from lp.services.features import get_relevant_feature_controller
68
 
from lp.services.features.flags import NullFeatureController
69
 
from lp.services.feeds.interfaces.application import IFeedsApplication
70
 
from lp.services.feeds.interfaces.feed import IFeed
71
 
from lp.services.oauth.interfaces import (
 
63
from canonical.config import config
 
64
from canonical.launchpad.interfaces.launchpad import (
 
65
    IFeedsApplication,
 
66
    IPrivateApplication,
 
67
    IWebServiceApplication,
 
68
    )
 
69
from canonical.launchpad.interfaces.oauth import (
72
70
    IOAuthConsumerSet,
73
71
    IOAuthSignedRequest,
74
72
    TokenException,
75
73
    )
76
 
from lp.services.propertycache import cachedproperty
77
 
from lp.services.webapp.authentication import (
 
74
import canonical.launchpad.layers
 
75
from canonical.launchpad.webapp.authentication import (
78
76
    check_oauth_signature,
79
77
    get_oauth_authorization,
80
78
    )
81
 
from lp.services.webapp.authorization import (
 
79
from canonical.launchpad.webapp.authorization import (
82
80
    LAUNCHPAD_SECURITY_POLICY_CACHE_KEY,
83
81
    )
84
 
from lp.services.webapp.errorlog import ErrorReportRequest
85
 
from lp.services.webapp.interfaces import (
86
 
    FinishReadOnlyRequestEvent,
 
82
from canonical.launchpad.webapp.errorlog import ErrorReportRequest
 
83
from canonical.launchpad.webapp.interfaces import (
87
84
    IAPIDocRoot,
88
85
    IBasicLaunchpadRequest,
89
86
    IBrowserFormNG,
95
92
    IPlacelessLoginSource,
96
93
    OAuthPermission,
97
94
    )
98
 
from lp.services.webapp.notifications import (
 
95
from canonical.launchpad.webapp.notifications import (
99
96
    NotificationList,
100
97
    NotificationRequest,
101
98
    NotificationResponse,
102
99
    )
103
 
from lp.services.webapp.opstats import OpStats
104
 
from lp.services.webapp.publication import LaunchpadBrowserPublication
105
 
from lp.services.webapp.publisher import (
 
100
from canonical.launchpad.webapp.opstats import OpStats
 
101
from canonical.launchpad.webapp.publication import LaunchpadBrowserPublication
 
102
from canonical.launchpad.webapp.publisher import (
106
103
    get_current_browser_request,
107
104
    RedirectionView,
108
105
    )
109
 
from lp.services.webapp.vhosts import allvhosts
110
 
from lp.services.webservice.interfaces import IWebServiceApplication
 
106
from canonical.launchpad.webapp.vhosts import allvhosts
 
107
from canonical.lazr.interfaces.feed import IFeed
 
108
from lp.app.errors import UnexpectedFormData
 
109
from lp.services.features import get_relevant_feature_controller
 
110
from lp.services.features.flags import NullFeatureController
 
111
from lp.services.propertycache import cachedproperty
111
112
from lp.testopenid.interfaces.server import ITestOpenIDApplication
112
 
from lp.xmlrpc.interfaces import IPrivateApplication
113
113
 
114
114
 
115
115
class StepsToGo:
542
542
        """See `IBasicLaunchpadRequest`."""
543
543
        return 'XMLHttpRequest' == self.getHeader('HTTP_X_REQUESTED_WITH')
544
544
 
545
 
    def getURL(self, level=0, path_only=False, include_query=False):
546
 
        """See `IBasicLaunchpadRequest`."""
547
 
        sup = super(LaunchpadBrowserRequestMixin, self)
548
 
        url = sup.getURL(level, path_only)
549
 
        if include_query:
550
 
            query_string = self.get('QUERY_STRING')
551
 
            if query_string is not None and len(query_string) > 0:
552
 
                url = "%s?%s" % (url, query_string)
553
 
        return url
554
 
 
555
545
 
556
546
class BasicLaunchpadRequest(LaunchpadBrowserRequestMixin):
557
547
    """Mixin request class to provide stepstogo."""
563
553
        self._wsgi_keys = set()
564
554
        self.needs_datepicker_iframe = False
565
555
        self.needs_datetimepicker_iframe = False
 
556
        self.needs_json = False
566
557
        super(BasicLaunchpadRequest, self).__init__(
567
558
            body_instream, environ, response)
568
559
 
615
606
 
616
607
    implements(
617
608
        ILaunchpadBrowserApplicationRequest, ISynchronizer,
618
 
        lp.layers.LaunchpadLayer)
 
609
        canonical.launchpad.layers.LaunchpadLayer)
619
610
 
620
611
    retry_max_count = 5    # How many times we're willing to retry
621
612
 
702
693
def web_service_request_to_browser_request(webservice_request):
703
694
    """Convert a given webservice request into a webapp one.
704
695
 
705
 
    Overrides 'SERVER_URL' to the 'mainsite', preserving headers and
706
 
    body.  Encodes PATH_INFO because it is unconditionally decoded by
707
 
    zope.publisher.http.sane_environment.
 
696
    Simply overrides 'SERVER_URL' to the 'mainsite', preserving headers and
 
697
    body.
708
698
    """
709
699
    body = webservice_request.bodyStream.getCacheStream().read()
710
700
    environ = dict(webservice_request.environment)
711
701
    environ['SERVER_URL'] = allvhosts.configs['mainsite'].rooturl
712
 
    if 'PATH_INFO' in environ:
713
 
        environ['PATH_INFO'] = environ['PATH_INFO'].encode('utf-8')
714
702
    return LaunchpadBrowserRequest(body, environ)
715
703
 
716
704
 
810
798
    return request.response
811
799
 
812
800
 
813
 
class LaunchpadTestRequest(LaunchpadBrowserRequestMixin,
814
 
                           TestRequest, ErrorReportRequest):
 
801
class LaunchpadTestRequest(TestRequest, ErrorReportRequest,
 
802
                           LaunchpadBrowserRequestMixin):
815
803
    """Mock request for use in unit and functional tests.
816
804
 
817
805
    >>> request = LaunchpadTestRequest(SERVER_URL='http://127.0.0.1/foo/bar')
825
813
    It provides LaunchpadLayer and adds a mock INotificationRequest
826
814
    implementation.
827
815
 
828
 
    >>> lp.layers.LaunchpadLayer.providedBy(request)
 
816
    >>> canonical.launchpad.layers.LaunchpadLayer.providedBy(request)
829
817
    True
830
818
    >>> INotificationRequest.providedBy(request)
831
819
    True
857
845
    >>> request.needs_datepicker_iframe
858
846
    False
859
847
 
 
848
    And for JSON:
 
849
 
 
850
    >>> request.needs_json
 
851
    False
 
852
 
860
853
    """
861
 
    implements(
862
 
        INotificationRequest, IBasicLaunchpadRequest, IParticipation,
863
 
        lp.layers.LaunchpadLayer)
864
 
 
 
854
    implements(INotificationRequest, IBasicLaunchpadRequest, IParticipation,
 
855
               canonical.launchpad.layers.LaunchpadLayer)
865
856
    # These two attributes satisfy IParticipation.
866
857
    principal = None
867
858
    interaction = None
874
865
        self.traversed_objects = []
875
866
        self.needs_datepicker_iframe = False
876
867
        self.needs_datetimepicker_iframe = False
 
868
        self.needs_json = False
877
869
        # Use an existing feature controller if one exists, otherwise use the
878
870
        # null controller.
879
871
        self.features = get_relevant_feature_controller()
959
951
        """See zope.app.publication.interfaces.IPublicationRequestFactory"""
960
952
        assert output_stream is None, 'output_stream is deprecated in Z3.2'
961
953
 
962
 
        # Mark the request with the 'lp.layers.debug' layer
 
954
        # Mark the request with the 'canonical.launchpad.layers.debug' layer
963
955
        request = HTTPPublicationRequestFactory.__call__(
964
956
            self, input_stream, env)
965
 
        lp.layers.setFirstLayer(
966
 
            request, lp.layers.DebugLayer)
 
957
        canonical.launchpad.layers.setFirstLayer(
 
958
            request, canonical.launchpad.layers.DebugLayer)
967
959
        return request
968
960
 
969
961
 
1122
1114
 
1123
1115
class FeedsBrowserRequest(LaunchpadBrowserRequest):
1124
1116
    """Request type for a launchpad feed."""
1125
 
    implements(lp.layers.FeedsLayer)
 
1117
    implements(canonical.launchpad.layers.FeedsLayer)
1126
1118
 
1127
1119
 
1128
1120
# ---- apidoc
1129
1121
 
1130
1122
class APIDocBrowserRequest(LaunchpadBrowserRequest):
1131
 
    implements(lp.layers.APIDocLayer)
 
1123
    implements(canonical.launchpad.layers.APIDocLayer)
1132
1124
 
1133
1125
 
1134
1126
class APIDocBrowserPublication(LaunchpadBrowserPublication):
1138
1130
# ---- testopenid
1139
1131
 
1140
1132
class TestOpenIDBrowserRequest(LaunchpadBrowserRequest):
1141
 
    implements(lp.layers.TestOpenIDLayer)
 
1133
    implements(canonical.launchpad.layers.TestOpenIDLayer)
1142
1134
 
1143
1135
 
1144
1136
class TestOpenIDBrowserPublication(LaunchpadBrowserPublication):
1175
1167
                pageid += ':' + collection_identifier
1176
1168
        op = (view.request.get('ws.op')
1177
1169
            or view.request.query_string_params.get('ws.op'))
1178
 
        if op and isinstance(op, basestring):
 
1170
        if op:
1179
1171
            pageid += ':' + op
1180
1172
        return pageid
1181
1173
 
1201
1193
        else:
1202
1194
            return super(WebServicePublication, self).getResource(request, ob)
1203
1195
 
1204
 
    def finishReadOnlyRequest(self, request, ob, txn):
 
1196
    def finishReadOnlyRequest(self, txn):
1205
1197
        """Commit the transaction so that created OAuthNonces are stored."""
1206
 
        notify(FinishReadOnlyRequestEvent(ob, request))
1207
1198
        # Transaction commits usually need to be aware of the possibility of
1208
1199
        # a doomed transaction.  We do not expect that this code will
1209
1200
        # encounter doomed transactions.  If it does, this will need to be
1307
1298
 
1308
1299
 
1309
1300
class LaunchpadWebServiceRequestTraversal(WebServiceRequestTraversal):
1310
 
    implements(lp.layers.WebServiceLayer)
 
1301
    implements(canonical.launchpad.layers.WebServiceLayer)
1311
1302
 
1312
1303
    def getRootURL(self, rootsite):
1313
1304
        """See IBasicLaunchpadRequest."""