Merge lp:~salgado/launchpad/remove-lp-services-openid into lp:launchpad
- remove-lp-services-openid
- Merge into devel
Proposed by
Guilherme Salgado
Status: | Merged |
---|---|
Approved by: | Aaron Bentley |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~salgado/launchpad/remove-lp-services-openid |
Merge into: | lp:launchpad |
Prerequisite: | lp:~salgado/launchpad/remove-auth-store |
Diff against target: |
943 lines (+0/-861) 11 files modified
lib/canonical/launchpad/browser/launchpad.py (+0/-2) lib/lp/services/openid/browser/configure.zcml (+0/-60) lib/lp/services/openid/browser/openidrpconfig.py (+0/-124) lib/lp/services/openid/configure.zcml (+0/-18) lib/lp/services/openid/doc/openid-rp-config.txt (+0/-171) lib/lp/services/openid/interfaces/openidrpconfig.py (+0/-120) lib/lp/services/openid/model/openidrpconfig.py (+0/-111) lib/lp/services/openid/stories/rpconfig-admin.txt (+0/-190) lib/lp/services/openid/templates/openidrpconfig-add.pt (+0/-16) lib/lp/services/openid/templates/openidrpconfig-edit.pt (+0/-16) lib/lp/services/openid/templates/openidrpconfigset-index.pt (+0/-33) |
To merge this branch: | bzr merge lp:~salgado/launchpad/remove-lp-services-openid |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Aaron Bentley (community) | Approve | ||
Review via email: mp+22807@code.launchpad.net |
Commit message
Description of the change
Remove the unused bits from lp/services/openid. These were once used by canonical-
To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) : | # |
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 2010-03-04 20:19:39 +0000 | |||
3 | +++ lib/canonical/launchpad/browser/launchpad.py 2010-04-05 15:45:44 +0000 | |||
4 | @@ -100,7 +100,6 @@ | |||
5 | 100 | from lp.registry.interfaces.mentoringoffer import IMentoringOfferSet | 100 | from lp.registry.interfaces.mentoringoffer import IMentoringOfferSet |
6 | 101 | from lp.registry.interfaces.person import IPersonSet | 101 | from lp.registry.interfaces.person import IPersonSet |
7 | 102 | from lp.registry.interfaces.pillar import IPillarNameSet | 102 | from lp.registry.interfaces.pillar import IPillarNameSet |
8 | 103 | from lp.services.openid.interfaces.openidrpconfig import IOpenIDRPConfigSet | ||
9 | 104 | from lp.services.worlddata.interfaces.language import ILanguageSet | 103 | from lp.services.worlddata.interfaces.language import ILanguageSet |
10 | 105 | from lp.soyuz.interfaces.packageset import IPackagesetSet | 104 | from lp.soyuz.interfaces.packageset import IPackagesetSet |
11 | 106 | from lp.registry.interfaces.product import ( | 105 | from lp.registry.interfaces.product import ( |
12 | @@ -578,7 +577,6 @@ | |||
13 | 578 | 'translations': IRosettaApplication, | 577 | 'translations': IRosettaApplication, |
14 | 579 | 'testopenid': ITestOpenIDApplication, | 578 | 'testopenid': ITestOpenIDApplication, |
15 | 580 | 'questions': IQuestionSet, | 579 | 'questions': IQuestionSet, |
16 | 581 | '+rpconfig': IOpenIDRPConfigSet, | ||
17 | 582 | 'temporary-blobs': ITemporaryStorageManager, | 580 | 'temporary-blobs': ITemporaryStorageManager, |
18 | 583 | # These three have been renamed, and no redirects done, as the old | 581 | # These three have been renamed, and no redirects done, as the old |
19 | 584 | # urls now point to the product pages. | 582 | # urls now point to the product pages. |
20 | 585 | 583 | ||
21 | === removed file 'lib/lp/services/openid/browser/configure.zcml' | |||
22 | --- lib/lp/services/openid/browser/configure.zcml 2009-11-23 03:10:04 +0000 | |||
23 | +++ lib/lp/services/openid/browser/configure.zcml 1970-01-01 00:00:00 +0000 | |||
24 | @@ -1,60 +0,0 @@ | |||
25 | 1 | <!-- Copyright 2009 Canonical Ltd. This software is licensed under the | ||
26 | 2 | GNU Affero General Public License version 3 (see the file LICENSE). | ||
27 | 3 | --> | ||
28 | 4 | |||
29 | 5 | <configure xmlns="http://namespaces.zope.org/zope" | ||
30 | 6 | xmlns:browser="http://namespaces.zope.org/browser"> | ||
31 | 7 | |||
32 | 8 | <browser:url | ||
33 | 9 | for="..interfaces.openidrpconfig.IOpenIDRPConfig" | ||
34 | 10 | path_expression="string:${id}" | ||
35 | 11 | parent_utility="..interfaces.openidrpconfig.IOpenIDRPConfigSet" | ||
36 | 12 | /> | ||
37 | 13 | |||
38 | 14 | <browser:page | ||
39 | 15 | for="..interfaces.openidrpconfig.IOpenIDRPConfig" | ||
40 | 16 | name="+edit" | ||
41 | 17 | class=".openidrpconfig.OpenIDRPConfigEditView" | ||
42 | 18 | permission="launchpad.Admin" | ||
43 | 19 | template="../templates/openidrpconfig-edit.pt" | ||
44 | 20 | /> | ||
45 | 21 | |||
46 | 22 | <browser:defaultView | ||
47 | 23 | for="..interfaces.openidrpconfig.IOpenIDRPConfig" | ||
48 | 24 | name="+edit" | ||
49 | 25 | /> | ||
50 | 26 | |||
51 | 27 | <!-- IOpenIDRPConfigSet --> | ||
52 | 28 | |||
53 | 29 | <browser:url | ||
54 | 30 | for="..interfaces.openidrpconfig.IOpenIDRPConfigSet" | ||
55 | 31 | path_expression="string:+rpconfig" | ||
56 | 32 | parent_utility="canonical.launchpad.interfaces.ILaunchpadRoot" | ||
57 | 33 | /> | ||
58 | 34 | |||
59 | 35 | <browser:navigation | ||
60 | 36 | module=".openidrpconfig" | ||
61 | 37 | classes="OpenIDRPConfigSetNavigation" | ||
62 | 38 | /> | ||
63 | 39 | |||
64 | 40 | <browser:page | ||
65 | 41 | for="..interfaces.openidrpconfig.IOpenIDRPConfigSet" | ||
66 | 42 | name="+add" | ||
67 | 43 | class=".openidrpconfig.OpenIDRPConfigAddView" | ||
68 | 44 | permission="launchpad.Admin" | ||
69 | 45 | template="../templates/openidrpconfig-add.pt" | ||
70 | 46 | /> | ||
71 | 47 | |||
72 | 48 | <browser:page | ||
73 | 49 | for="..interfaces.openidrpconfig.IOpenIDRPConfigSet" | ||
74 | 50 | name="+index" | ||
75 | 51 | class=".openidrpconfig.OpenIDRPConfigSetView" | ||
76 | 52 | permission="launchpad.Admin" | ||
77 | 53 | template="../templates/openidrpconfigset-index.pt" | ||
78 | 54 | /> | ||
79 | 55 | |||
80 | 56 | <browser:defaultView | ||
81 | 57 | for="..interfaces.openidrpconfig.IOpenIDRPConfigSet" | ||
82 | 58 | name="+index" | ||
83 | 59 | /> | ||
84 | 60 | </configure> | ||
85 | 61 | 0 | ||
86 | === removed file 'lib/lp/services/openid/browser/openidrpconfig.py' | |||
87 | --- lib/lp/services/openid/browser/openidrpconfig.py 2009-11-23 16:14:39 +0000 | |||
88 | +++ lib/lp/services/openid/browser/openidrpconfig.py 1970-01-01 00:00:00 +0000 | |||
89 | @@ -1,124 +0,0 @@ | |||
90 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | ||
91 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
92 | 3 | |||
93 | 4 | """View classes used to edit `IOpenIDRPConfig` objects. | ||
94 | 5 | |||
95 | 6 | OpenID Relying Party configurations are used to customise the | ||
96 | 7 | appearance and behaviour of the login page when authenticating to a | ||
97 | 8 | particular RP. | ||
98 | 9 | """ | ||
99 | 10 | |||
100 | 11 | __metaclass__ = type | ||
101 | 12 | __all__ = [] | ||
102 | 13 | |||
103 | 14 | from zope.component import getUtility | ||
104 | 15 | |||
105 | 16 | from canonical.launchpad import _ | ||
106 | 17 | from lp.services.openid.interfaces.openidrpconfig import ( | ||
107 | 18 | IOpenIDRPConfig, IOpenIDRPConfigSet) | ||
108 | 19 | from canonical.launchpad.webapp import ( | ||
109 | 20 | LaunchpadEditFormView, LaunchpadFormView, Navigation, action, | ||
110 | 21 | canonical_url, custom_widget) | ||
111 | 22 | from canonical.launchpad.webapp.publisher import LaunchpadView | ||
112 | 23 | from canonical.widgets import LabeledMultiCheckBoxWidget | ||
113 | 24 | from canonical.widgets.image import ImageChangeWidget | ||
114 | 25 | from lp.registry.interfaces.person import PersonCreationRationale | ||
115 | 26 | |||
116 | 27 | |||
117 | 28 | class OpenIDRPConfigSetNavigation(Navigation): | ||
118 | 29 | """Navigation for `IOpenIDRPConfigSet`.""" | ||
119 | 30 | usedfor = IOpenIDRPConfigSet | ||
120 | 31 | |||
121 | 32 | def traverse(self, config_id): | ||
122 | 33 | """Traverse to RP configs by ID.""" | ||
123 | 34 | try: | ||
124 | 35 | config_id = int(config_id) | ||
125 | 36 | except ValueError: | ||
126 | 37 | return None | ||
127 | 38 | |||
128 | 39 | return getUtility(IOpenIDRPConfigSet).get(config_id) | ||
129 | 40 | |||
130 | 41 | |||
131 | 42 | class OpenIDRPConfigSetView(LaunchpadView): | ||
132 | 43 | page_title = 'OpenID Relying Party Configurations' | ||
133 | 44 | label = page_title | ||
134 | 45 | |||
135 | 46 | |||
136 | 47 | class OpenIDRPConfigAddView(LaunchpadFormView): | ||
137 | 48 | """View class for adding new RP configurations.""" | ||
138 | 49 | |||
139 | 50 | schema = IOpenIDRPConfig | ||
140 | 51 | field_names = ['trust_root', 'displayname', 'description', 'logo', | ||
141 | 52 | 'allowed_sreg', 'creation_rationale', 'can_query_any_team', | ||
142 | 53 | 'auto_authorize'] | ||
143 | 54 | custom_widget('logo', ImageChangeWidget, ImageChangeWidget.ADD_STYLE) | ||
144 | 55 | custom_widget('allowed_sreg', LabeledMultiCheckBoxWidget) | ||
145 | 56 | label = 'Add an OpenID Relying Party Configuration' | ||
146 | 57 | page_title = label | ||
147 | 58 | |||
148 | 59 | initial_values = { | ||
149 | 60 | 'creation_rationale': | ||
150 | 61 | PersonCreationRationale.OWNER_CREATED_UNKNOWN_TRUSTROOT, | ||
151 | 62 | } | ||
152 | 63 | |||
153 | 64 | @action(_('Create'), name='create') | ||
154 | 65 | def create_action(self, action, data): | ||
155 | 66 | """Create the new RP configuration.""" | ||
156 | 67 | rpconfig = getUtility(IOpenIDRPConfigSet).new( | ||
157 | 68 | trust_root=data['trust_root'], | ||
158 | 69 | displayname=data['displayname'], | ||
159 | 70 | description=data['description'], | ||
160 | 71 | logo=data['logo'], | ||
161 | 72 | allowed_sreg=data['allowed_sreg'], | ||
162 | 73 | creation_rationale=data['creation_rationale'], | ||
163 | 74 | can_query_any_team=data['can_query_any_team'], | ||
164 | 75 | auto_authorize=data['auto_authorize']) | ||
165 | 76 | self.request.response.addInfoNotification( | ||
166 | 77 | _('Created RP configuration for ${trust_root}.', | ||
167 | 78 | mapping=dict(trust_root=data['trust_root']))) | ||
168 | 79 | |||
169 | 80 | @property | ||
170 | 81 | def next_url(self): | ||
171 | 82 | return canonical_url(getUtility(IOpenIDRPConfigSet)) | ||
172 | 83 | |||
173 | 84 | cancel_url = next_url | ||
174 | 85 | |||
175 | 86 | |||
176 | 87 | class OpenIDRPConfigEditView(LaunchpadEditFormView): | ||
177 | 88 | """View class for editing or removing RP configurations.""" | ||
178 | 89 | |||
179 | 90 | @property | ||
180 | 91 | def label(self): | ||
181 | 92 | return 'Edit Relying Party Configuration for %s' % ( | ||
182 | 93 | self.context.displayname) | ||
183 | 94 | page_title = label | ||
184 | 95 | |||
185 | 96 | schema = IOpenIDRPConfig | ||
186 | 97 | field_names = ['trust_root', 'displayname', 'description', 'logo', | ||
187 | 98 | 'allowed_sreg', 'creation_rationale', 'can_query_any_team', | ||
188 | 99 | 'auto_authorize'] | ||
189 | 100 | custom_widget('logo', ImageChangeWidget, ImageChangeWidget.EDIT_STYLE) | ||
190 | 101 | custom_widget('allowed_sreg', LabeledMultiCheckBoxWidget) | ||
191 | 102 | |||
192 | 103 | @action(_('Save'), name='save') | ||
193 | 104 | def save_action(self, action, data): | ||
194 | 105 | """Save the RP configuration.""" | ||
195 | 106 | if self.updateContextFromData(data): | ||
196 | 107 | self.request.response.addInfoNotification( | ||
197 | 108 | _('Updated RP configuration for ${trust_root}.', | ||
198 | 109 | mapping=dict(trust_root=self.context.trust_root))) | ||
199 | 110 | |||
200 | 111 | @action(_('Remove'), name='remove') | ||
201 | 112 | def remove_action(self, action, data): | ||
202 | 113 | """Remove the RP configuration.""" | ||
203 | 114 | trust_root = self.context.trust_root | ||
204 | 115 | self.context.destroySelf() | ||
205 | 116 | self.request.response.addInfoNotification( | ||
206 | 117 | _('Removed RP configuration for ${trust_root}.', | ||
207 | 118 | mapping=dict(trust_root=trust_root))) | ||
208 | 119 | |||
209 | 120 | @property | ||
210 | 121 | def next_url(self): | ||
211 | 122 | return canonical_url(getUtility(IOpenIDRPConfigSet)) | ||
212 | 123 | |||
213 | 124 | cancel_url = next_url | ||
214 | 125 | 0 | ||
215 | === modified file 'lib/lp/services/openid/configure.zcml' | |||
216 | --- lib/lp/services/openid/configure.zcml 2009-07-18 00:05:49 +0000 | |||
217 | +++ lib/lp/services/openid/configure.zcml 2010-04-05 15:45:44 +0000 | |||
218 | @@ -9,23 +9,6 @@ | |||
219 | 9 | i18n_domain="launchpad"> | 9 | i18n_domain="launchpad"> |
220 | 10 | 10 | ||
221 | 11 | <class | 11 | <class |
222 | 12 | class=".model.openidrpconfig.OpenIDRPConfig"> | ||
223 | 13 | <allow interface=".interfaces.openidrpconfig.IOpenIDRPConfig" /> | ||
224 | 14 | <require | ||
225 | 15 | permission="launchpad.Admin" | ||
226 | 16 | attributes="destroySelf" | ||
227 | 17 | set_schema=".interfaces.openidrpconfig.IOpenIDRPConfig" /> | ||
228 | 18 | </class> | ||
229 | 19 | |||
230 | 20 | <securedutility | ||
231 | 21 | class=".model.openidrpconfig.OpenIDRPConfigSet" | ||
232 | 22 | provides=".interfaces.openidrpconfig.IOpenIDRPConfigSet"> | ||
233 | 23 | <allow | ||
234 | 24 | interface=".interfaces.openidrpconfig.IOpenIDRPConfigSet" | ||
235 | 25 | /> | ||
236 | 26 | </securedutility> | ||
237 | 27 | |||
238 | 28 | <class | ||
239 | 29 | class=".model.openidrpsummary.OpenIDRPSummary"> | 12 | class=".model.openidrpsummary.OpenIDRPSummary"> |
240 | 30 | <allow interface=".interfaces.openidrpsummary.IOpenIDRPSummary" /> | 13 | <allow interface=".interfaces.openidrpsummary.IOpenIDRPSummary" /> |
241 | 31 | </class> | 14 | </class> |
242 | @@ -44,5 +27,4 @@ | |||
243 | 44 | <adapter factory=".adapters.openid.OpenIDPersistentIdentity" /> | 27 | <adapter factory=".adapters.openid.OpenIDPersistentIdentity" /> |
244 | 45 | <adapter factory=".adapters.openid.person_to_openidpersistentidentity" /> | 28 | <adapter factory=".adapters.openid.person_to_openidpersistentidentity" /> |
245 | 46 | 29 | ||
246 | 47 | <include package=".browser" /> | ||
247 | 48 | </configure> | 30 | </configure> |
248 | 49 | 31 | ||
249 | === removed directory 'lib/lp/services/openid/doc' | |||
250 | === removed file 'lib/lp/services/openid/doc/__init__.py' | |||
251 | === removed file 'lib/lp/services/openid/doc/openid-rp-config.txt' | |||
252 | --- lib/lp/services/openid/doc/openid-rp-config.txt 2010-02-11 20:33:07 +0000 | |||
253 | +++ lib/lp/services/openid/doc/openid-rp-config.txt 1970-01-01 00:00:00 +0000 | |||
254 | @@ -1,171 +0,0 @@ | |||
255 | 1 | =================================== | ||
256 | 2 | OpenID Relying Party Configurations | ||
257 | 3 | =================================== | ||
258 | 4 | |||
259 | 5 | Launchpad can store information about OpenID relying parties in order | ||
260 | 6 | to provide a better user experience when using Launchpad to log in. | ||
261 | 7 | This includes: | ||
262 | 8 | |||
263 | 9 | * Providing a human readable name for the relying party, so we don't | ||
264 | 10 | have to display the raw URL to the user. | ||
265 | 11 | |||
266 | 12 | * Providing a logo image to display on the log in page. | ||
267 | 13 | |||
268 | 14 | * Specify what fields may be disclosed to the RP via OpenID Simple | ||
269 | 15 | Registration protocol. | ||
270 | 16 | |||
271 | 17 | * What person creation rationale should be used for accounts created | ||
272 | 18 | while signing in to the RP. | ||
273 | 19 | |||
274 | 20 | |||
275 | 21 | Creating OpenIDRPConfigs | ||
276 | 22 | ======================== | ||
277 | 23 | |||
278 | 24 | Configurations are created using the IOpenIDRPConfigSet utility: | ||
279 | 25 | |||
280 | 26 | >>> from zope.component import getUtility | ||
281 | 27 | >>> from lp.services.openid.interfaces.openidrpconfig import ( | ||
282 | 28 | ... IOpenIDRPConfigSet) | ||
283 | 29 | >>> login(ANONYMOUS) | ||
284 | 30 | >>> rpconfig = getUtility(IOpenIDRPConfigSet).new( | ||
285 | 31 | ... trust_root='http://*.example.com/', | ||
286 | 32 | ... displayname='Example RP', | ||
287 | 33 | ... description='Example RP description', | ||
288 | 34 | ... allowed_sreg=['fullname', 'nickname']) | ||
289 | 35 | |||
290 | 36 | The resulting object implements the IOpenIDRPConfig interface: | ||
291 | 37 | |||
292 | 38 | >>> from canonical.launchpad.webapp.testing import verifyObject | ||
293 | 39 | >>> from lp.services.openid.interfaces.openidrpconfig import ( | ||
294 | 40 | ... IOpenIDRPConfig) | ||
295 | 41 | |||
296 | 42 | >>> verifyObject(IOpenIDRPConfig, rpconfig) | ||
297 | 43 | True | ||
298 | 44 | |||
299 | 45 | The utility itself implements IOpenIDRPConfigSet: | ||
300 | 46 | |||
301 | 47 | >>> verifyObject(IOpenIDRPConfigSet, getUtility(IOpenIDRPConfigSet)) | ||
302 | 48 | True | ||
303 | 49 | |||
304 | 50 | Some RPs include a trailing '/' on their URLs, which is the standard, | ||
305 | 51 | while others do not. The `trust_root` is always normalized to have a | ||
306 | 52 | trailing slash. | ||
307 | 53 | |||
308 | 54 | >>> rpconfig2 = getUtility(IOpenIDRPConfigSet).new( | ||
309 | 55 | ... trust_root='http://foo.example.com', | ||
310 | 56 | ... displayname='Example RP', | ||
311 | 57 | ... description='Example RP description', | ||
312 | 58 | ... allowed_sreg=['fullname', 'nickname']) | ||
313 | 59 | >>> print rpconfig2.trust_root | ||
314 | 60 | http://foo.example.com/ | ||
315 | 61 | |||
316 | 62 | |||
317 | 63 | Modifying OpenIDRPConfig objects | ||
318 | 64 | ================================ | ||
319 | 65 | |||
320 | 66 | OpenIDRPConfig objects may only be modified by an administrator: | ||
321 | 67 | |||
322 | 68 | >>> rpconfig.displayname = 'New title' | ||
323 | 69 | Traceback (most recent call last): | ||
324 | 70 | ... | ||
325 | 71 | Unauthorized: (<OpenIDRPConfig at ...>, 'displayname', 'launchpad.Admin') | ||
326 | 72 | >>> login('foo.bar@canonical.com') | ||
327 | 73 | >>> rpconfig.displayname = 'New title' | ||
328 | 74 | >>> print rpconfig.displayname | ||
329 | 75 | New title | ||
330 | 76 | |||
331 | 77 | The allowed simple registration fields attribute sorts the field names | ||
332 | 78 | to normalise the result: | ||
333 | 79 | |||
334 | 80 | >>> rpconfig.allowed_sreg = ['fullname', 'email'] | ||
335 | 81 | >>> print rpconfig.allowed_sreg | ||
336 | 82 | [u'email', u'fullname'] | ||
337 | 83 | |||
338 | 84 | The auto_authorize attribute specifies whether this RP is allowed to | ||
339 | 85 | skip the authorization page. This behaviour is not turned on by | ||
340 | 86 | default: | ||
341 | 87 | |||
342 | 88 | >>> rpconfig.auto_authorize | ||
343 | 89 | False | ||
344 | 90 | >>> rpconfig.auto_authorize = True | ||
345 | 91 | >>> rpconfig.auto_authorize | ||
346 | 92 | True | ||
347 | 93 | |||
348 | 94 | |||
349 | 95 | Searching for OpenIDRPConfig objects | ||
350 | 96 | ==================================== | ||
351 | 97 | |||
352 | 98 | An RP config can be looked up by its ID using the get() method of the | ||
353 | 99 | IOpenIDRPConfigSet: | ||
354 | 100 | |||
355 | 101 | >>> rpconfig2 = getUtility(IOpenIDRPConfigSet).get(rpconfig.id) | ||
356 | 102 | >>> print rpconfig2.trust_root | ||
357 | 103 | http://*.example.com/ | ||
358 | 104 | >>> rpconfig2.id == rpconfig.id | ||
359 | 105 | True | ||
360 | 106 | |||
361 | 107 | The get() method will return None for an unknown ID: | ||
362 | 108 | |||
363 | 109 | >>> print getUtility(IOpenIDRPConfigSet).get(-42) | ||
364 | 110 | None | ||
365 | 111 | |||
366 | 112 | It is also possible to look up RP configs by their trust root: | ||
367 | 113 | |||
368 | 114 | >>> rpconfig3 = getUtility(IOpenIDRPConfigSet).getByTrustRoot( | ||
369 | 115 | ... 'http://*.example.com/') | ||
370 | 116 | >>> print rpconfig3.trust_root | ||
371 | 117 | http://*.example.com/ | ||
372 | 118 | >>> rpconfig3.id == rpconfig.id | ||
373 | 119 | True | ||
374 | 120 | |||
375 | 121 | The getByTrustRoot() method will return None for an unknown trust | ||
376 | 122 | root: | ||
377 | 123 | |||
378 | 124 | >>> print getUtility(IOpenIDRPConfigSet).getByTrustRoot('http://unknown') | ||
379 | 125 | None | ||
380 | 126 | |||
381 | 127 | Most RPs include the trailing '/' in their trust root URL but some do | ||
382 | 128 | not. The search should match whether the trailing slash is there or | ||
383 | 129 | not. | ||
384 | 130 | |||
385 | 131 | >>> rpconfig3 = getUtility(IOpenIDRPConfigSet).getByTrustRoot( | ||
386 | 132 | ... 'http://*.example.com') | ||
387 | 133 | >>> print rpconfig3.trust_root | ||
388 | 134 | http://*.example.com/ | ||
389 | 135 | >>> rpconfig3.id == rpconfig.id | ||
390 | 136 | True | ||
391 | 137 | |||
392 | 138 | |||
393 | 139 | Listing all OpenIDRPConfig objects | ||
394 | 140 | ================================== | ||
395 | 141 | |||
396 | 142 | The getAll() method of the IOpenIDRPConfigSet will return a result set | ||
397 | 143 | containing all OpenIDRP's. | ||
398 | 144 | |||
399 | 145 | >>> configs = getUtility(IOpenIDRPConfigSet).getAll() | ||
400 | 146 | >>> rpconfig in configs | ||
401 | 147 | True | ||
402 | 148 | |||
403 | 149 | |||
404 | 150 | Destroying OpenIDRPConfig objects | ||
405 | 151 | ================================= | ||
406 | 152 | |||
407 | 153 | RP configs can be removed using the destroySelf() method, which is | ||
408 | 154 | only available to administrators: | ||
409 | 155 | |||
410 | 156 | >>> login(ANONYMOUS) | ||
411 | 157 | >>> rpconfig = getUtility(IOpenIDRPConfigSet).getByTrustRoot( | ||
412 | 158 | ... 'http://*.example.com/') | ||
413 | 159 | >>> rpconfig.destroySelf() | ||
414 | 160 | Traceback (most recent call last): | ||
415 | 161 | ... | ||
416 | 162 | Unauthorized: (<OpenIDRPConfig at ...>, 'destroySelf', 'launchpad.Admin') | ||
417 | 163 | |||
418 | 164 | The same method succeeds when run as an administrator. Afterwards, | ||
419 | 165 | attempts to get the RP config fail: | ||
420 | 166 | |||
421 | 167 | >>> login('foo.bar@canonical.com') | ||
422 | 168 | >>> rpconfig.destroySelf() | ||
423 | 169 | >>> print getUtility(IOpenIDRPConfigSet).getByTrustRoot( | ||
424 | 170 | ... 'http://*.example.com/') | ||
425 | 171 | None | ||
426 | 172 | 0 | ||
427 | === removed file 'lib/lp/services/openid/interfaces/openidrpconfig.py' | |||
428 | --- lib/lp/services/openid/interfaces/openidrpconfig.py 2009-07-17 02:25:09 +0000 | |||
429 | +++ lib/lp/services/openid/interfaces/openidrpconfig.py 1970-01-01 00:00:00 +0000 | |||
430 | @@ -1,120 +0,0 @@ | |||
431 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | ||
432 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
433 | 3 | |||
434 | 4 | """OpenIDRPConfig related interfaces.""" | ||
435 | 5 | |||
436 | 6 | __metaclass__ = type | ||
437 | 7 | __all__ = [ | ||
438 | 8 | 'IOpenIDRPConfig', | ||
439 | 9 | 'IOpenIDRPConfigSet', | ||
440 | 10 | ] | ||
441 | 11 | |||
442 | 12 | from zope.component import getUtility | ||
443 | 13 | from zope.schema import Bool, Choice, Int, List, Text, TextLine | ||
444 | 14 | from zope.interface import Interface | ||
445 | 15 | from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary | ||
446 | 16 | |||
447 | 17 | from canonical.launchpad import _ | ||
448 | 18 | from canonical.launchpad.fields import ( | ||
449 | 19 | BaseImageUpload, URIField, UniqueField) | ||
450 | 20 | from lp.registry.interfaces.person import PersonCreationRationale | ||
451 | 21 | |||
452 | 22 | |||
453 | 23 | class TrustRootField(UniqueField, URIField): | ||
454 | 24 | """An OpenID Relying Party trust root, which is unique.""" | ||
455 | 25 | |||
456 | 26 | attribute = 'trust_root' | ||
457 | 27 | errormessage = _("%s is already in use for another Relying Party.") | ||
458 | 28 | |||
459 | 29 | @property | ||
460 | 30 | def _content_iface(self): | ||
461 | 31 | return IOpenIDRPConfig | ||
462 | 32 | |||
463 | 33 | def _getByAttribute(self, trust_root): | ||
464 | 34 | return getUtility(IOpenIDRPConfigSet).getByTrustRoot(trust_root) | ||
465 | 35 | |||
466 | 36 | |||
467 | 37 | class RPLogoImageUpload(BaseImageUpload): | ||
468 | 38 | |||
469 | 39 | dimensions = (400, 100) | ||
470 | 40 | exact_dimensions = False | ||
471 | 41 | max_size = 100*1024 | ||
472 | 42 | |||
473 | 43 | |||
474 | 44 | sreg_fields_vocabulary = SimpleVocabulary([ | ||
475 | 45 | SimpleTerm('fullname', 'fullname', 'Full name'), | ||
476 | 46 | SimpleTerm('nickname', 'nickname', 'Launchpad ID'), | ||
477 | 47 | SimpleTerm('email', 'email', 'Email address'), | ||
478 | 48 | SimpleTerm('timezone', 'timezone', 'Time zone'), | ||
479 | 49 | SimpleTerm('x_address1', 'x_address1', 'Address line 1'), | ||
480 | 50 | SimpleTerm('x_address2', 'x_address2', 'Address line 2'), | ||
481 | 51 | SimpleTerm('x_city', 'x_city', 'City'), | ||
482 | 52 | SimpleTerm('x_province', 'x_province', 'State/Province'), | ||
483 | 53 | SimpleTerm('country', 'country', 'Country'), | ||
484 | 54 | SimpleTerm('postcode', 'postcode', 'Postcode'), | ||
485 | 55 | SimpleTerm('x_phone', 'x_phone', 'Phone number'), | ||
486 | 56 | SimpleTerm('x_organization', 'x_organization', 'Organization')]) | ||
487 | 57 | |||
488 | 58 | |||
489 | 59 | class IOpenIDRPConfig(Interface): | ||
490 | 60 | """Configuration for a particular OpenID Relying Party.""" | ||
491 | 61 | id = Int(title=u'ID', required=True) | ||
492 | 62 | trust_root = TrustRootField( | ||
493 | 63 | title=_('Trust Root'), required=True, | ||
494 | 64 | trailing_slash=True, | ||
495 | 65 | description=_('The openid.trust_root value sent by the ' | ||
496 | 66 | 'Relying Party')) | ||
497 | 67 | displayname = TextLine( | ||
498 | 68 | title=_('Display Name'), required=True, | ||
499 | 69 | description=_('A human readable name for the Relying Party')) | ||
500 | 70 | description = Text( | ||
501 | 71 | title=_('Description'), required=True, | ||
502 | 72 | description=_('A description of the Relying Party, explaining why ' | ||
503 | 73 | 'the user should authenticate.')) | ||
504 | 74 | logo = RPLogoImageUpload( | ||
505 | 75 | title=_('Logo'), required=False, | ||
506 | 76 | default_image_resource='/@@/nyet-logo', | ||
507 | 77 | description=_('A banner that identifies the Relying Party, ' | ||
508 | 78 | 'no larger than 400x100 pixels.')) | ||
509 | 79 | allowed_sreg = List( | ||
510 | 80 | title=_('Allowed Sreg Fields'), | ||
511 | 81 | description=_('The simple registration fields that may be ' | ||
512 | 82 | 'transferred to this Relying Party'), | ||
513 | 83 | value_type=Choice(vocabulary=sreg_fields_vocabulary)) | ||
514 | 84 | creation_rationale = Choice( | ||
515 | 85 | title=_('Creation Rationale'), | ||
516 | 86 | description=_('The creation rationale to use for user accounts ' | ||
517 | 87 | 'created while logging in to this Relying Party'), | ||
518 | 88 | vocabulary=PersonCreationRationale) | ||
519 | 89 | can_query_any_team = Bool( | ||
520 | 90 | title=_('Query Any Team'), | ||
521 | 91 | description=_( | ||
522 | 92 | 'Teammembership of any team can be requested, including ' | ||
523 | 93 | 'private teams.'), | ||
524 | 94 | required=True, readonly=False) | ||
525 | 95 | auto_authorize = Bool( | ||
526 | 96 | title=_('Automatically authorize requests'), | ||
527 | 97 | description=_( | ||
528 | 98 | 'Authentication requests for this RP are responded to ' | ||
529 | 99 | 'automatically without explicit user authorization'), | ||
530 | 100 | required=True, readonly=False) | ||
531 | 101 | |||
532 | 102 | |||
533 | 103 | class IOpenIDRPConfigSet(Interface): | ||
534 | 104 | """The set of OpenID Relying Party configurations.""" | ||
535 | 105 | def new(trust_root, displayname, description, logo=None, | ||
536 | 106 | allowed_sreg=None, creation_rationale=PersonCreationRationale | ||
537 | 107 | .OWNER_CREATED_UNKNOWN_TRUSTROOT, can_query_any_team=False, | ||
538 | 108 | auto_authorize=False): | ||
539 | 109 | """Create a new IOpenIDRPConfig""" | ||
540 | 110 | |||
541 | 111 | def get(id): | ||
542 | 112 | """Get the IOpenIDRPConfig with a particular ID.""" | ||
543 | 113 | |||
544 | 114 | def getAll(): | ||
545 | 115 | """Return a sequence of all IOpenIDRPConfigs.""" | ||
546 | 116 | |||
547 | 117 | def getByTrustRoot(trust_root): | ||
548 | 118 | """Return the IOpenIDRPConfig for a particular trust root""" | ||
549 | 119 | |||
550 | 120 | |||
551 | 121 | 0 | ||
552 | === removed file 'lib/lp/services/openid/model/openidrpconfig.py' | |||
553 | --- lib/lp/services/openid/model/openidrpconfig.py 2009-07-17 02:25:09 +0000 | |||
554 | +++ lib/lp/services/openid/model/openidrpconfig.py 1970-01-01 00:00:00 +0000 | |||
555 | @@ -1,111 +0,0 @@ | |||
556 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | ||
557 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
558 | 3 | |||
559 | 4 | """OpenIDRPConfig related database classes.""" | ||
560 | 5 | |||
561 | 6 | __metaclass__ = type | ||
562 | 7 | __all__ = [ | ||
563 | 8 | 'OpenIDRPConfig', | ||
564 | 9 | 'OpenIDRPConfigSet', | ||
565 | 10 | ] | ||
566 | 11 | |||
567 | 12 | |||
568 | 13 | import re | ||
569 | 14 | |||
570 | 15 | from sqlobject import BoolCol, ForeignKey, SQLObjectNotFound, StringCol | ||
571 | 16 | from storm.expr import Or | ||
572 | 17 | from zope.interface import implements | ||
573 | 18 | |||
574 | 19 | from canonical.database.enumcol import EnumCol | ||
575 | 20 | from canonical.database.sqlbase import SQLBase | ||
576 | 21 | from canonical.launchpad.interfaces import IStore | ||
577 | 22 | from lp.registry.interfaces.person import PersonCreationRationale | ||
578 | 23 | from lp.services.openid.interfaces.openidrpconfig import ( | ||
579 | 24 | IOpenIDRPConfig, IOpenIDRPConfigSet) | ||
580 | 25 | |||
581 | 26 | |||
582 | 27 | class OpenIDRPConfig(SQLBase): | ||
583 | 28 | implements(IOpenIDRPConfig) | ||
584 | 29 | |||
585 | 30 | _table = 'OpenIDRPConfig' | ||
586 | 31 | trust_root = StringCol(dbName='trust_root', notNull=True) | ||
587 | 32 | displayname = StringCol(dbName='displayname', notNull=True) | ||
588 | 33 | description = StringCol(dbName='description', notNull=True) | ||
589 | 34 | logo = ForeignKey( | ||
590 | 35 | dbName='logo', foreignKey='LibraryFileAlias', default=None) | ||
591 | 36 | _allowed_sreg = StringCol(dbName='allowed_sreg') | ||
592 | 37 | creation_rationale = EnumCol( | ||
593 | 38 | dbName='creation_rationale', notNull=True, | ||
594 | 39 | schema=PersonCreationRationale, | ||
595 | 40 | default=PersonCreationRationale.OWNER_CREATED_UNKNOWN_TRUSTROOT) | ||
596 | 41 | can_query_any_team = BoolCol( | ||
597 | 42 | dbName='can_query_any_team', notNull=True, default=False) | ||
598 | 43 | auto_authorize = BoolCol() | ||
599 | 44 | |||
600 | 45 | def allowed_sreg(self): | ||
601 | 46 | value = self._allowed_sreg | ||
602 | 47 | if not value: | ||
603 | 48 | return [] | ||
604 | 49 | return value.split(',') | ||
605 | 50 | |||
606 | 51 | def _set_allowed_sreg(self, value): | ||
607 | 52 | if not value: | ||
608 | 53 | self._allowed_sreg = None | ||
609 | 54 | self._allowed_sreg = ','.join(sorted(value)) | ||
610 | 55 | |||
611 | 56 | allowed_sreg = property(allowed_sreg, _set_allowed_sreg) | ||
612 | 57 | |||
613 | 58 | |||
614 | 59 | class OpenIDRPConfigSet: | ||
615 | 60 | implements(IOpenIDRPConfigSet) | ||
616 | 61 | |||
617 | 62 | url_re = re.compile("^(.+?)\/*$") | ||
618 | 63 | |||
619 | 64 | def _normalizeTrustRoot(self, trust_root): | ||
620 | 65 | """Given a trust root URL ensure it ends with exactly one '/'.""" | ||
621 | 66 | match = self.url_re.match(trust_root) | ||
622 | 67 | assert match is not None, ( | ||
623 | 68 | "Attempting to normalize trust root %s failed." % trust_root) | ||
624 | 69 | return "%s/" % match.group(1) | ||
625 | 70 | |||
626 | 71 | def new(self, trust_root, displayname, description, logo=None, | ||
627 | 72 | allowed_sreg=None, | ||
628 | 73 | creation_rationale= | ||
629 | 74 | PersonCreationRationale.OWNER_CREATED_UNKNOWN_TRUSTROOT, | ||
630 | 75 | can_query_any_team=False, auto_authorize=False): | ||
631 | 76 | """See `IOpenIDRPConfigSet`""" | ||
632 | 77 | if allowed_sreg: | ||
633 | 78 | allowed_sreg = ','.join(sorted(allowed_sreg)) | ||
634 | 79 | else: | ||
635 | 80 | allowed_sreg = None | ||
636 | 81 | trust_root = self._normalizeTrustRoot(trust_root) | ||
637 | 82 | return OpenIDRPConfig( | ||
638 | 83 | trust_root=trust_root, displayname=displayname, | ||
639 | 84 | description=description, logo=logo, | ||
640 | 85 | _allowed_sreg=allowed_sreg, creation_rationale=creation_rationale, | ||
641 | 86 | can_query_any_team=can_query_any_team, | ||
642 | 87 | auto_authorize=auto_authorize) | ||
643 | 88 | |||
644 | 89 | def get(self, id): | ||
645 | 90 | """See `IOpenIDRPConfigSet`""" | ||
646 | 91 | try: | ||
647 | 92 | return OpenIDRPConfig.get(id) | ||
648 | 93 | except SQLObjectNotFound: | ||
649 | 94 | return None | ||
650 | 95 | |||
651 | 96 | def getAll(self): | ||
652 | 97 | """See `IOpenIDRPConfigSet`""" | ||
653 | 98 | return OpenIDRPConfig.select(orderBy=['displayname', 'trust_root']) | ||
654 | 99 | |||
655 | 100 | def getByTrustRoot(self, trust_root): | ||
656 | 101 | """See `IOpenIDRPConfigSet`""" | ||
657 | 102 | trust_root = self._normalizeTrustRoot(trust_root) | ||
658 | 103 | # XXX: BradCrittenden 2008-09-26 bug=274774: Until the database is | ||
659 | 104 | # updated to normalize existing data the query must look for | ||
660 | 105 | # trust_roots that end in '/' and those that do not. | ||
661 | 106 | return IStore(OpenIDRPConfig).find( | ||
662 | 107 | OpenIDRPConfig, | ||
663 | 108 | Or(OpenIDRPConfig.trust_root==trust_root, | ||
664 | 109 | OpenIDRPConfig.trust_root==trust_root[:-1])).one() | ||
665 | 110 | |||
666 | 111 | |||
667 | 112 | 0 | ||
668 | === removed directory 'lib/lp/services/openid/stories' | |||
669 | === removed file 'lib/lp/services/openid/stories/__init__.py' | |||
670 | === removed file 'lib/lp/services/openid/stories/rpconfig-admin.txt' | |||
671 | --- lib/lp/services/openid/stories/rpconfig-admin.txt 2009-07-15 15:39:49 +0000 | |||
672 | +++ lib/lp/services/openid/stories/rpconfig-admin.txt 1970-01-01 00:00:00 +0000 | |||
673 | @@ -1,190 +0,0 @@ | |||
674 | 1 | = Managing OpenID Relying Party Configurations = | ||
675 | 2 | |||
676 | 3 | While Launchpad can act as an OpenID Provider for any Relying Party, | ||
677 | 4 | it can provide a better user experience for RPs that it knows about, | ||
678 | 5 | including: | ||
679 | 6 | |||
680 | 7 | * A human readable name for the RP. | ||
681 | 8 | * A logo for the RP to display on the login page. | ||
682 | 9 | * Some descriptive text indicating why the user should authenticate | ||
683 | 10 | to the RP. | ||
684 | 11 | * A creation rationale for new accounts created as part of the login | ||
685 | 12 | process for this RP. | ||
686 | 13 | |||
687 | 14 | The pages used to view and edit these configurations are only visible | ||
688 | 15 | to Launchpad administrators: | ||
689 | 16 | |||
690 | 17 | >>> user_browser.open('http://launchpad.dev/+rpconfig') | ||
691 | 18 | Traceback (most recent call last): | ||
692 | 19 | ... | ||
693 | 20 | Unauthorized: ... | ||
694 | 21 | >>> admin_browser.open('http://launchpad.dev/+rpconfig') | ||
695 | 22 | >>> print admin_browser.title | ||
696 | 23 | OpenID Relying Party Configurations | ||
697 | 24 | |||
698 | 25 | |||
699 | 26 | == Adding RP Configurations == | ||
700 | 27 | |||
701 | 28 | We can add new RP configurations from this page: | ||
702 | 29 | |||
703 | 30 | >>> admin_browser.getLink('Add an RP config').click() | ||
704 | 31 | >>> print admin_browser.title | ||
705 | 32 | Add an OpenID Relying Party Configuration | ||
706 | 33 | |||
707 | 34 | >>> import os | ||
708 | 35 | >>> from canonical.config import config | ||
709 | 36 | >>> logo_file = os.path.join( | ||
710 | 37 | ... config.root, 'lib/canonical/launchpad/images/nyet-logo.png') | ||
711 | 38 | |||
712 | 39 | >>> admin_browser.getControl('Trust Root').value = 'http://example.com/' | ||
713 | 40 | >>> admin_browser.getControl('Display Name').value = 'Example RP' | ||
714 | 41 | >>> admin_browser.getControl('Description').value = 'example description' | ||
715 | 42 | >>> admin_browser.getControl(name='field.logo.action').value = ['change'] | ||
716 | 43 | >>> admin_browser.getControl(name='field.logo.image').add_file( | ||
717 | 44 | ... open(logo_file), 'image/png', 'logo.png') | ||
718 | 45 | >>> admin_browser.getControl('Full name').click() | ||
719 | 46 | >>> admin_browser.getControl('Email address').click() | ||
720 | 47 | >>> admin_browser.getControl('Automatically authorize requests').click() | ||
721 | 48 | >>> admin_browser.getControl('Create').click() | ||
722 | 49 | >>> print admin_browser.title | ||
723 | 50 | OpenID Relying Party Configurations | ||
724 | 51 | |||
725 | 52 | The new RP configuration page is now included in the list: | ||
726 | 53 | |||
727 | 54 | >>> print admin_browser.contents | ||
728 | 55 | <... | ||
729 | 56 | <td><a href="...">Example RP</a></td> | ||
730 | 57 | <td>http://example.com/</td> | ||
731 | 58 | ... | ||
732 | 59 | |||
733 | 60 | The RP config contains all the information we'd expect: | ||
734 | 61 | |||
735 | 62 | >>> from zope.component import getUtility | ||
736 | 63 | >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout | ||
737 | 64 | >>> from lp.services.openid.interfaces.openidrpconfig import ( | ||
738 | 65 | ... IOpenIDRPConfigSet) | ||
739 | 66 | |||
740 | 67 | >>> login(ANONYMOUS) | ||
741 | 68 | >>> rpconfig = getUtility(IOpenIDRPConfigSet).getByTrustRoot( | ||
742 | 69 | ... 'http://example.com/') | ||
743 | 70 | >>> print rpconfig.displayname | ||
744 | 71 | Example RP | ||
745 | 72 | >>> print rpconfig.description | ||
746 | 73 | example description | ||
747 | 74 | >>> print rpconfig.logo.filename | ||
748 | 75 | logo.png | ||
749 | 76 | >>> print rpconfig.allowed_sreg | ||
750 | 77 | [u'email', u'fullname'] | ||
751 | 78 | >>> print rpconfig.creation_rationale.name | ||
752 | 79 | OWNER_CREATED_UNKNOWN_TRUSTROOT | ||
753 | 80 | >>> print rpconfig.auto_authorize | ||
754 | 81 | True | ||
755 | 82 | >>> logout() | ||
756 | 83 | |||
757 | 84 | The trust_root will have a trailing slash appended even if the user | ||
758 | 85 | does not specify one. | ||
759 | 86 | |||
760 | 87 | >>> admin_browser.open('http://launchpad.dev/+rpconfig') | ||
761 | 88 | >>> admin_browser.getLink('Add an RP config').click() | ||
762 | 89 | >>> admin_browser.getControl('Trust Root').value = 'http://example-two.com' | ||
763 | 90 | >>> admin_browser.getControl('Display Name').value = 'Example Two RP' | ||
764 | 91 | >>> admin_browser.getControl('Description').value = 'example description' | ||
765 | 92 | >>> admin_browser.getControl('Create').click() | ||
766 | 93 | |||
767 | 94 | The new RP configuration page is now included in the list, with the | ||
768 | 95 | trailing slash in the trust root: | ||
769 | 96 | |||
770 | 97 | >>> print admin_browser.contents | ||
771 | 98 | <... | ||
772 | 99 | <td><a href="...">Example Two RP</a></td> | ||
773 | 100 | <td>http://example-two.com/</td> | ||
774 | 101 | ... | ||
775 | 102 | |||
776 | 103 | |||
777 | 104 | == Editing RP Configurations == | ||
778 | 105 | |||
779 | 106 | We can also edit existing RP configurations: | ||
780 | 107 | |||
781 | 108 | >>> admin_browser.getLink('Example RP').click() | ||
782 | 109 | >>> print admin_browser.title | ||
783 | 110 | Edit Relying Party Configuration for Example RP | ||
784 | 111 | |||
785 | 112 | >>> admin_browser.getControl('Description').value = 'new description' | ||
786 | 113 | >>> admin_browser.getControl('Launchpad ID').click() | ||
787 | 114 | >>> admin_browser.getControl('Automatically authorize requests').click() | ||
788 | 115 | >>> admin_browser.getControl('Save').click() | ||
789 | 116 | >>> print admin_browser.title | ||
790 | 117 | OpenID Relying Party Configurations | ||
791 | 118 | |||
792 | 119 | The changes have now been made to the RP configuration: | ||
793 | 120 | |||
794 | 121 | >>> login(ANONYMOUS) | ||
795 | 122 | >>> rpconfig = getUtility(IOpenIDRPConfigSet).getByTrustRoot( | ||
796 | 123 | ... 'http://example.com/') | ||
797 | 124 | >>> print rpconfig.description | ||
798 | 125 | new description | ||
799 | 126 | >>> print rpconfig.allowed_sreg | ||
800 | 127 | [u'email', u'fullname', u'nickname'] | ||
801 | 128 | >>> print rpconfig.auto_authorize | ||
802 | 129 | False | ||
803 | 130 | >>> logout() | ||
804 | 131 | |||
805 | 132 | |||
806 | 133 | == Only One RP Configuration Per Trust Root == | ||
807 | 134 | |||
808 | 135 | There can only be one RP configuration per trust root. Trying to | ||
809 | 136 | create a second configuration fails: | ||
810 | 137 | |||
811 | 138 | >>> admin_browser.getLink('Add an RP config').click() | ||
812 | 139 | >>> admin_browser.getControl('Trust Root').value = 'http://example.com/' | ||
813 | 140 | >>> admin_browser.getControl('Display Name').value = 'Second RP' | ||
814 | 141 | >>> admin_browser.getControl('Description').value = 'description' | ||
815 | 142 | >>> admin_browser.getControl('Create').click() | ||
816 | 143 | >>> print admin_browser.title | ||
817 | 144 | Add an OpenID Relying Party Configuration | ||
818 | 145 | |||
819 | 146 | >>> for error in find_tags_by_class(admin_browser.contents, 'message'): | ||
820 | 147 | ... print extract_text(error) | ||
821 | 148 | There is 1 error. | ||
822 | 149 | http://example.com/ is already in use for another Relying Party. | ||
823 | 150 | |||
824 | 151 | Changing the trust root value fixes the problem: | ||
825 | 152 | |||
826 | 153 | >>> admin_browser.getControl('Trust Root').value = 'http://example.net/' | ||
827 | 154 | >>> admin_browser.getControl('Create').click() | ||
828 | 155 | >>> print admin_browser.title | ||
829 | 156 | OpenID Relying Party Configurations | ||
830 | 157 | |||
831 | 158 | Similarly, we can't change the trust root of a configuration to | ||
832 | 159 | conflict with another configuration: | ||
833 | 160 | |||
834 | 161 | >>> admin_browser.getLink('Second RP').click() | ||
835 | 162 | >>> admin_browser.getControl('Trust Root').value = 'http://example.com/' | ||
836 | 163 | >>> admin_browser.getControl('Save').click() | ||
837 | 164 | >>> print admin_browser.title | ||
838 | 165 | Edit Relying Party Configuration for Second RP | ||
839 | 166 | |||
840 | 167 | >>> for error in find_tags_by_class(admin_browser.contents, 'message'): | ||
841 | 168 | ... print extract_text(error) | ||
842 | 169 | There is 1 error. | ||
843 | 170 | http://example.com/ is already in use for another Relying Party. | ||
844 | 171 | |||
845 | 172 | |||
846 | 173 | == Deleting RP Configurations == | ||
847 | 174 | |||
848 | 175 | RP configurations can be deleted from the edit form: | ||
849 | 176 | |||
850 | 177 | >>> admin_browser.open('http://launchpad.dev/+rpconfig') | ||
851 | 178 | >>> admin_browser.getLink('Example RP').click() | ||
852 | 179 | >>> admin_browser.getControl('Remove').click() | ||
853 | 180 | >>> print admin_browser.title | ||
854 | 181 | OpenID Relying Party Configurations | ||
855 | 182 | |||
856 | 183 | The RP configuration has now been removed: | ||
857 | 184 | |||
858 | 185 | >>> login(ANONYMOUS) | ||
859 | 186 | >>> rpconfig = getUtility(IOpenIDRPConfigSet).getByTrustRoot( | ||
860 | 187 | ... 'http://example.com/') | ||
861 | 188 | >>> print rpconfig | ||
862 | 189 | None | ||
863 | 190 | >>> logout() | ||
864 | 191 | 0 | ||
865 | === removed file 'lib/lp/services/openid/templates/openidrpconfig-add.pt' | |||
866 | --- lib/lp/services/openid/templates/openidrpconfig-add.pt 2009-11-23 03:10:04 +0000 | |||
867 | +++ lib/lp/services/openid/templates/openidrpconfig-add.pt 1970-01-01 00:00:00 +0000 | |||
868 | @@ -1,16 +0,0 @@ | |||
869 | 1 | <html | ||
870 | 2 | xmlns="http://www.w3.org/1999/xhtml" | ||
871 | 3 | xmlns:tal="http://xml.zope.org/namespaces/tal" | ||
872 | 4 | xmlns:metal="http://xml.zope.org/namespaces/metal" | ||
873 | 5 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" | ||
874 | 6 | metal:use-macro="view/macro:page/main_only" | ||
875 | 7 | i18n:domain="launchpad"> | ||
876 | 8 | |||
877 | 9 | <body> | ||
878 | 10 | |||
879 | 11 | <div metal:fill-slot="main"> | ||
880 | 12 | <div metal:use-macro="context/@@launchpad_form/form" /> | ||
881 | 13 | </div> | ||
882 | 14 | |||
883 | 15 | </body> | ||
884 | 16 | </html> | ||
885 | 17 | 0 | ||
886 | === removed file 'lib/lp/services/openid/templates/openidrpconfig-edit.pt' | |||
887 | --- lib/lp/services/openid/templates/openidrpconfig-edit.pt 2009-11-23 03:10:04 +0000 | |||
888 | +++ lib/lp/services/openid/templates/openidrpconfig-edit.pt 1970-01-01 00:00:00 +0000 | |||
889 | @@ -1,16 +0,0 @@ | |||
890 | 1 | <html | ||
891 | 2 | xmlns="http://www.w3.org/1999/xhtml" | ||
892 | 3 | xmlns:tal="http://xml.zope.org/namespaces/tal" | ||
893 | 4 | xmlns:metal="http://xml.zope.org/namespaces/metal" | ||
894 | 5 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" | ||
895 | 6 | metal:use-macro="view/macro:page/main_only" | ||
896 | 7 | i18n:domain="launchpad"> | ||
897 | 8 | |||
898 | 9 | <body> | ||
899 | 10 | |||
900 | 11 | <div metal:fill-slot="main"> | ||
901 | 12 | <div metal:use-macro="context/@@launchpad_form/form" /> | ||
902 | 13 | </div> | ||
903 | 14 | |||
904 | 15 | </body> | ||
905 | 16 | </html> | ||
906 | 17 | 0 | ||
907 | === removed file 'lib/lp/services/openid/templates/openidrpconfigset-index.pt' | |||
908 | --- lib/lp/services/openid/templates/openidrpconfigset-index.pt 2009-11-23 16:14:39 +0000 | |||
909 | +++ lib/lp/services/openid/templates/openidrpconfigset-index.pt 1970-01-01 00:00:00 +0000 | |||
910 | @@ -1,33 +0,0 @@ | |||
911 | 1 | <html xml:lang="en" lang="en" | ||
912 | 2 | xmlns="http://www.w3.org/1999/xhtml" | ||
913 | 3 | xmlns:tal="http://xml.zope.org/namespaces/tal" | ||
914 | 4 | xmlns:metal="http://xml.zope.org/namespaces/metal" | ||
915 | 5 | xmlns:i18n="http://xml.zope.org/namespaces/i18n" | ||
916 | 6 | metal:use-macro="view/macro:page/main_only" | ||
917 | 7 | i18n:domain="launchpad"> | ||
918 | 8 | |||
919 | 9 | <body> | ||
920 | 10 | <div metal:fill-slot="main"> | ||
921 | 11 | <table class="listing" tal:condition="context/getAll"> | ||
922 | 12 | <thead> | ||
923 | 13 | <tr> | ||
924 | 14 | <th>Relying Party</th> | ||
925 | 15 | <th>Trust Root</th> | ||
926 | 16 | </tr> | ||
927 | 17 | </thead> | ||
928 | 18 | <tbody> | ||
929 | 19 | <tr tal:repeat="rpconfig context/getAll"> | ||
930 | 20 | <td><a tal:attributes="href rpconfig/fmt:url" | ||
931 | 21 | tal:content="rpconfig/displayname">RP Config</a></td> | ||
932 | 22 | <td tal:content="rpconfig/trust_root">http://blah</td> | ||
933 | 23 | </tr> | ||
934 | 24 | </tbody> | ||
935 | 25 | </table> | ||
936 | 26 | |||
937 | 27 | <div> | ||
938 | 28 | <a tal:attributes="href string:${context/fmt:url}/+add"> | ||
939 | 29 | Add an RP config</a> | ||
940 | 30 | </div> | ||
941 | 31 | </div> | ||
942 | 32 | </body> | ||
943 | 33 | </html> |