Merge lp:~jcsackett/launchpad/api-pillar-redirects-715992 into lp:launchpad

Proposed by j.c.sackett
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 12364
Proposed branch: lp:~jcsackett/launchpad/api-pillar-redirects-715992
Merge into: lp:launchpad
Diff against target: 89 lines (+35/-7)
3 files modified
lib/canonical/launchpad/browser/launchpad.py (+2/-1)
lib/canonical/launchpad/webapp/publisher.py (+5/-6)
lib/lp/registry/tests/test_product_webservice.py (+28/-0)
To merge this branch: bzr merge lp:~jcsackett/launchpad/api-pillar-redirects-715992
Reviewer Review Type Date Requested Status
Robert Collins (community) Approve
Review via email: mp+49279@code.launchpad.net

Commit message

[r=lifeless][bug=715992] Corrects use of canonical_url so that requests for pillars via alias on the API do not redirect outside of the API layer.

Description of the change

Summary
=======

Pillars can have aliases, which are linked back to their actual names/pages through use of canonical_url. This use of canonical_url, when dealing with webservice requests, accidentally redirects the request outside of the api layer. This branch deals with that by making sure the use of canonical_url is aware of the current request, so it doesn't have to guess at it.

Preimplementation
=================

Spoke with Leonard Richardson.

Followed up with Robert Collins on some confusing code in canonical_url.

Proposed Fix
============

Per Leonard Richardson, find the method that forgets the current request, and make sure request is passed in.

Implementation
==============

lib/canonical/launchpad/browser/launchpad.py
--------------------------------------------

The use of canonical_url to find the url of the pillar with the supplied alias now has the request passed into it.

lib/canonical/launchpad/webapp/publisher.py
-------------------------------------------

Comment changes on canonical_url to make it clearer what's going on with the request parameter.

lib/lp/registry/tests/test_product_webservice.py
------------------------------------------------

Created tests.

Tests
=====

bin/test -t test_product_webservice

Demo & QA
=========

Open http://qastaging.api.launchpad.net/ubuntufontbetatesting. It should redirect to http://qastaging.api.launchpad.net/ubuntu-font-family.

Lint
====

make lint output:

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/canonical/launchpad/browser/launchpad.py
  lib/canonical/launchpad/webapp/publisher.py
  lib/lp/registry/tests/test_product_webservice.py

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/browser/launchpad.py'
2--- lib/canonical/launchpad/browser/launchpad.py 2011-02-02 15:43:31 +0000
3+++ lib/canonical/launchpad/browser/launchpad.py 2011-02-10 19:56:21 +0000
4@@ -668,7 +668,8 @@
5 if pillar.name != name:
6 # This pillar was accessed through one of its aliases, so we
7 # must redirect to its canonical URL.
8- return self.redirectSubTree(canonical_url(pillar), status=301)
9+ return self.redirectSubTree(
10+ canonical_url(pillar, self.request), status=301)
11 return pillar
12 return None
13
14
15=== modified file 'lib/canonical/launchpad/webapp/publisher.py'
16--- lib/canonical/launchpad/webapp/publisher.py 2010-08-20 20:31:18 +0000
17+++ lib/canonical/launchpad/webapp/publisher.py 2011-02-10 19:56:21 +0000
18@@ -226,6 +226,7 @@
19 return self._user
20
21 _is_beta = None
22+
23 @property
24 def isBetaUser(self):
25 """Return True if the user is in the beta testers team."""
26@@ -474,9 +475,9 @@
27 the request. If a request is not provided, but a web-request is in
28 progress, the protocol, host and port are taken from the current request.
29
30- If there is no request available, the protocol, host and port are taken
31- from the root_url given in launchpad.conf.
32-
33+ :param request: The web request; if not provided, canonical_url attempts
34+ to guess at the current request, using the protocol, host, and port
35+ taken from the root_url given in launchpad.conf.
36 :param path_only_if_possible: If the protocol and hostname can be omitted
37 for the current request, return a url containing only the path.
38 :param view_name: Provide the canonical url for the specified view,
39@@ -550,8 +551,7 @@
40 if ((path_only_if_possible and
41 request is not None and
42 root_url.startswith(request.getApplicationURL()))
43- or force_local_path
44- ):
45+ or force_local_path):
46 return unicode('/' + path)
47 return unicode(root_url + path)
48
49@@ -651,7 +651,6 @@
50 return RedirectionView(target, self.request, status)
51
52 # The next methods are for use by the Zope machinery.
53-
54 def publishTraverse(self, request, name):
55 """Shim, to set objects in the launchbag when traversing them.
56
57
58=== added file 'lib/lp/registry/tests/test_product_webservice.py'
59--- lib/lp/registry/tests/test_product_webservice.py 1970-01-01 00:00:00 +0000
60+++ lib/lp/registry/tests/test_product_webservice.py 2011-02-10 19:56:21 +0000
61@@ -0,0 +1,28 @@
62+# Copyright 2011 Canonical Ltd. This software is licensed under the
63+# GNU Affero General Public License version 3 (see the file LICENSE).
64+
65+__metaclass__ = type
66+
67+from zope.security.proxy import removeSecurityProxy
68+
69+from canonical.launchpad.testing.pages import LaunchpadWebServiceCaller
70+from canonical.testing.layers import DatabaseFunctionalLayer
71+from lp.testing import TestCaseWithFactory
72+
73+
74+class TestProductAlias(TestCaseWithFactory):
75+ """Aliases should behave well with the webservice."""
76+
77+ layer = DatabaseFunctionalLayer
78+
79+ def test_alias_redirects_in_webservice(self):
80+ # When a redirect occurs for a product, it should remain in the
81+ # webservice.
82+ product = self.factory.makeProduct(name='lemur')
83+ removeSecurityProxy(product).setAliases(['monkey'])
84+ webservice = LaunchpadWebServiceCaller(
85+ 'launchpad-library', 'salgado-change-anything')
86+ response = webservice.get('/monkey')
87+ self.assertEqual(
88+ 'http://api.launchpad.dev/beta/lemur',
89+ response.getheader('location'))