Merge lp:~canonical-isd-hackers/canonical-identity-provider/bugs-659246-675933-test-consumer-logout-and-related-fixes into lp:canonical-identity-provider/release

Proposed by Stuart Metcalfe
Status: Merged
Approved by: Michael Foord
Approved revision: no longer in the source branch.
Merged at revision: 116
Proposed branch: lp:~canonical-isd-hackers/canonical-identity-provider/bugs-659246-675933-test-consumer-logout-and-related-fixes
Merge into: lp:canonical-identity-provider/release
Diff against target: 212 lines (+61/-23)
8 files modified
identityprovider/media/launchpad/styles.css (+5/-0)
identityprovider/media/ubuntu/styles.css (+3/-0)
identityprovider/models/openidmodels.py (+5/-2)
identityprovider/templates/consumer/index.html (+5/-0)
identityprovider/templates/launchpad/registration/logout.html (+7/-4)
identityprovider/templates/ubuntu/registration/logout.html (+6/-6)
identityprovider/tests/test_views_ui_logout.py (+19/-1)
identityprovider/views/ui.py (+11/-10)
To merge this branch: bzr merge lp:~canonical-isd-hackers/canonical-identity-provider/bugs-659246-675933-test-consumer-logout-and-related-fixes
Reviewer Review Type Date Requested Status
Michael Foord Pending
Review via email: mp+40965@code.launchpad.net

Commit message

Added logout links to the test consumer and related logout return_to fixes

Description of the change

This branch adds logout links to the test consumer, both with and without a return_to argument, to test the new feature enabling returning to a consumer.

As part of this work, I also picked up a few issues which are also fixed in this branch:

 * Display the consumer's rpconfig name, rather than the URL, in the template.
 * Make the return link more obvious.
 * Match rpconfigs where the return_to url exactly matches the rpconfig trust root and has a trailing slash.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'identityprovider/media/launchpad/styles.css'
2--- identityprovider/media/launchpad/styles.css 2010-08-23 13:21:38 +0000
3+++ identityprovider/media/launchpad/styles.css 2010-11-16 14:18:57 +0000
4@@ -113,6 +113,11 @@
5 color: #666;
6 }
7
8+p.returnto {
9+ font-size: 16px;
10+ text-align: center;
11+}
12+
13 #rp {
14 width: 49%;
15 float: left;
16
17=== modified file 'identityprovider/media/ubuntu/styles.css'
18--- identityprovider/media/ubuntu/styles.css 2010-11-11 19:50:54 +0000
19+++ identityprovider/media/ubuntu/styles.css 2010-11-16 14:18:57 +0000
20@@ -265,6 +265,9 @@
21 font-size: 16px;
22 line-height: 20px;
23 }
24+p.returnto {
25+ margin: 20px 0px;
26+}
27 p.services {
28 color: #fff;
29 }
30
31=== modified file 'identityprovider/models/openidmodels.py'
32--- identityprovider/models/openidmodels.py 2010-09-29 11:01:03 +0000
33+++ identityprovider/models/openidmodels.py 2010-11-16 14:18:57 +0000
34@@ -112,7 +112,9 @@
35 class OpenIDRPConfigManager(models.Manager):
36
37 def for_url(self, url):
38- if url.endswith('/'):
39+ if url is None:
40+ return None
41+ elif url.endswith('/'):
42 url = url[:-1]
43 # We need to encode the % character in URLs, so that an
44 # attacker can't maliciously take advantage of it as a
45@@ -128,6 +130,7 @@
46 # PostgreSQL uses it as a wild card in LIKE-patterns; so
47 # they're escaped here.
48 condition = """
49+ rtrim(trust_root, '/') = %s OR
50 replace(replace(%s, '~', '~T'), '%%', '~P')
51 LIKE (replace(replace(trust_root, '~', '~T'), '%%', '~P') || '%%')
52 """
53@@ -135,7 +138,7 @@
54 q = self.extra(
55 select={'len': 'length(trust_root)'},
56 where=[condition],
57- params=(url,),
58+ params=(url, url),
59 order_by=['-len'] # Select the longest match
60 )
61 return q[0] if q else None
62
63=== modified file 'identityprovider/templates/consumer/index.html'
64--- identityprovider/templates/consumer/index.html 2010-11-10 03:57:51 +0000
65+++ identityprovider/templates/consumer/index.html 2010-11-16 14:18:57 +0000
66@@ -152,6 +152,11 @@
67 <input type="submit" value="Begin" />
68 </form>
69
70+ <h2>Test logout</h2>
71+ <ul>
72+ <li><a href="{{ openid }}+logout?return_to={{ consumer_url|urlencode }}">Logout with return URL</a></li>
73+ <li><a href="{{ openid }}+logout">Normal logout</a></li>
74+ </ul>
75 </div>
76 </div>
77 </div>
78
79=== modified file 'identityprovider/templates/launchpad/registration/logout.html'
80--- identityprovider/templates/launchpad/registration/logout.html 2010-11-10 15:49:10 +0000
81+++ identityprovider/templates/launchpad/registration/logout.html 2010-11-16 14:18:57 +0000
82@@ -13,12 +13,15 @@
83 {% endblock %}
84
85 {% block content %}
86- <p>{{ brand.logout }}
87+ <p>{{ brand.logout }}</p>
88+
89+ <p class="returnto">
90 {% if return_to_url %}
91- {% blocktrans with return_to_url as url and return_to_site_name as site_name %}<span class="big">Return to <a href="{{ return_to_url }}">{{ site_name }}</a></span>{% endblocktrans %}
92+ {% blocktrans with return_to_url as url and return_to_site_name as site_name %}
93+ <a href="{{ return_to_url }}">Return to {{ site_name }}</a>{% endblocktrans %}
94+ {% else %}
95+ <a href="/+login">{% trans "Log back in to Launchpad Login Service" %}</a>
96 {% endif %}
97 </p>
98-
99- <p><a href="/+login">{% trans "Login back to Launchpad Login Service" %}</a></p>
100 {% endblock %}
101
102
103=== modified file 'identityprovider/templates/ubuntu/registration/logout.html'
104--- identityprovider/templates/ubuntu/registration/logout.html 2010-11-09 14:37:43 +0000
105+++ identityprovider/templates/ubuntu/registration/logout.html 2010-11-16 14:18:57 +0000
106@@ -13,12 +13,12 @@
107 {% endblock %}
108
109 {% block content %}
110- <p>{{ brand.logout }}
111- {% if return_to_url %}
112- {% blocktrans with return_to_url as url and return_to_site_name as site_name %}
113- <span class="big">Return to <a href="{{ return_to_url }}">{{ site_name }}</a></span>{% endblocktrans %}
114- {% endif %}
115- </p>
116+ <p>{{ brand.logout }}</p>
117+
118+ {% if return_to_url %}
119+ {% blocktrans with return_to_url as url and return_to_site_name as site_name %}
120+ <p class="returnto highlight"><a href="{{ return_to_url }}">Return to {{ site_name }}</a></p>{% endblocktrans %}
121+ {% endif %}
122
123 {% if other_sites %}
124 <div>
125
126=== modified file 'identityprovider/tests/test_views_ui_logout.py'
127--- identityprovider/tests/test_views_ui_logout.py 2010-09-29 03:48:52 +0000
128+++ identityprovider/tests/test_views_ui_logout.py 2010-11-16 14:18:57 +0000
129@@ -54,7 +54,13 @@
130 displayname="Example",
131 creation_rationale=AccountCreationRationale.UNKNOWN)
132
133- def test_get_return_to_url_whithout_referer_and_url_is_recognized(self):
134+ def test_get_return_to_root_url_without_referer_and_url_is_recognized(self):
135+ trust_root = 'http://example.com/'
136+ self.create_openid_rp_config(trust_root)
137+ return_to = self.view.get_return_to_url(trust_root, None)
138+ self.assertEquals(return_to, trust_root)
139+
140+ def test_get_return_to_url_without_referer_and_url_is_recognized(self):
141 trust_root = 'http://example.com/r'
142 self.create_openid_rp_config(trust_root)
143 return_to = self.view.get_return_to_url(trust_root, None)
144@@ -109,6 +115,18 @@
145
146 self.assertTrue(return_to is None)
147
148+ def test_get_site_name_with_valid_return_to(self):
149+ trust_root = 'http://example.com/'
150+ self.create_openid_rp_config(trust_root)
151+ site_name = self.view.get_site_name(trust_root)
152+ self.assertEquals(site_name, "Example")
153+
154+ def test_get_site_name_with_invalid_return_to(self):
155+ trust_root = 'http://example.com/'
156+ self.create_openid_rp_config(trust_root)
157+ site_name = self.view.get_site_name('http://notvalid.com/')
158+ self.assertTrue(site_name is None)
159+
160
161 def sites_with_active_sessions(self):
162 return []
163
164=== modified file 'identityprovider/views/ui.py'
165--- identityprovider/views/ui.py 2010-11-10 08:19:40 +0000
166+++ identityprovider/views/ui.py 2010-11-16 14:18:57 +0000
167@@ -99,7 +99,6 @@
168
169
170 class LogoutView(object):
171-
172 def get_language(self, user):
173 try:
174 return user.preferredlanguage
175@@ -111,15 +110,15 @@
176 response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language)
177
178 def get_return_to_url(self, return_to, http_referer):
179+ rpconfig = OpenIDRPConfig.objects.for_url(return_to)
180 if not return_to:
181 return None
182- rp_config = OpenIDRPConfig.objects.for_url(return_to)
183- if rp_config is not None:
184- if http_referer is not None and http_referer != return_to:
185- return None
186+ elif rpconfig is None:
187+ return None
188+ elif http_referer is not None and http_referer != return_to:
189+ return None
190+ else:
191 return return_to
192- else:
193- return None
194
195 def set_orequest(self, session, token, raw_orequest):
196 if token is not None and raw_orequest is not None:
197@@ -132,11 +131,13 @@
198 if trust_root != site.trust_root]
199
200 def get_site_name(self, trust_root):
201+ rpconfig = OpenIDRPConfig.objects.for_url(trust_root)
202 if not trust_root:
203 return None
204- sites = list(OpenIDRPConfig.objects.filter(trust_root=trust_root))
205- if sites:
206- return sites[0].displayname
207+ elif rpconfig is None:
208+ return None
209+ elif rpconfig.displayname:
210+ return rpconfig.displayname
211 else:
212 return trust_root
213