commit | author | age
|
993216
|
1 |
import unittest |
TS |
2 |
|
9c1e6f
|
3 |
class _Base(unittest.TestCase): |
TS |
4 |
|
|
5 |
def failUnless(self, predicate, message=''): |
|
6 |
self.assertTrue(predicate, message) # Nannies go home! |
|
7 |
|
|
8 |
def failIf(self, predicate, message=''): |
|
9 |
self.assertFalse(predicate, message) # Nannies go home! |
|
10 |
|
|
11 |
class Test_get_api(_Base): |
993216
|
12 |
|
TS |
13 |
def _callFUT(self, environ): |
|
14 |
from repoze.who.api import get_api |
|
15 |
return get_api(environ) |
|
16 |
|
|
17 |
def test___call___empty_environ(self): |
|
18 |
environ = {} |
|
19 |
api = self._callFUT(environ) |
|
20 |
self.failUnless(api is None) |
|
21 |
|
|
22 |
def test___call___w_api_in_environ(self): |
|
23 |
expected = object() |
|
24 |
environ = {'repoze.who.api': expected} |
|
25 |
api = self._callFUT(environ) |
|
26 |
self.failUnless(api is expected) |
|
27 |
|
9c1e6f
|
28 |
class APIFactoryTests(_Base): |
993216
|
29 |
|
TS |
30 |
def _getTargetClass(self): |
|
31 |
from repoze.who.api import APIFactory |
|
32 |
return APIFactory |
|
33 |
|
|
34 |
def _makeOne(self, |
|
35 |
plugins=None, |
|
36 |
identifiers=None, |
|
37 |
authenticators=None, |
|
38 |
challengers=None, |
|
39 |
mdproviders=None, |
|
40 |
request_classifier=None, |
|
41 |
challenge_decider=None, |
b482a1
|
42 |
remote_user_key=None, |
993216
|
43 |
logger=None, |
TS |
44 |
): |
|
45 |
if plugins is None: |
|
46 |
plugins = {} |
|
47 |
if identifiers is None: |
|
48 |
identifiers = () |
|
49 |
if authenticators is None: |
|
50 |
authenticators = () |
|
51 |
if challengers is None: |
|
52 |
challengers = () |
|
53 |
if mdproviders is None: |
|
54 |
mdproviders = () |
|
55 |
return self._getTargetClass()(identifiers, |
|
56 |
authenticators, |
|
57 |
challengers, |
|
58 |
mdproviders, |
|
59 |
request_classifier, |
|
60 |
challenge_decider, |
b482a1
|
61 |
remote_user_key, |
993216
|
62 |
logger, |
TS |
63 |
) |
|
64 |
|
|
65 |
def test_class_conforms_to_IAPIFactory(self): |
|
66 |
from zope.interface.verify import verifyClass |
|
67 |
from repoze.who.interfaces import IAPIFactory |
|
68 |
verifyClass(IAPIFactory, self._getTargetClass()) |
|
69 |
|
|
70 |
def test_instance_conforms_to_IAPIFactory(self): |
|
71 |
from zope.interface.verify import verifyObject |
|
72 |
from repoze.who.interfaces import IAPIFactory |
|
73 |
verifyObject(IAPIFactory, self._makeOne()) |
|
74 |
|
|
75 |
def test_ctor_defaults(self): |
|
76 |
factory = self._makeOne() |
|
77 |
self.assertEqual(len(factory.identifiers), 0) |
|
78 |
self.assertEqual(len(factory.authenticators), 0) |
|
79 |
self.assertEqual(len(factory.challengers), 0) |
|
80 |
self.assertEqual(len(factory.mdproviders), 0) |
|
81 |
self.assertEqual(factory.request_classifier, None) |
|
82 |
self.assertEqual(factory.challenge_decider, None) |
|
83 |
self.assertEqual(factory.logger, None) |
|
84 |
|
|
85 |
def test___call___empty_environ(self): |
|
86 |
from repoze.who.api import API |
|
87 |
environ = {} |
|
88 |
factory = self._makeOne() |
|
89 |
api = factory(environ) |
|
90 |
self.failUnless(isinstance(api, API)) |
|
91 |
self.failUnless(environ['repoze.who.api'] is api) |
|
92 |
|
|
93 |
def test___call___w_api_in_environ(self): |
|
94 |
expected = object() |
|
95 |
environ = {'repoze.who.api': expected} |
|
96 |
factory = self._makeOne() |
|
97 |
api = factory(environ) |
|
98 |
self.failUnless(api is expected) |
|
99 |
|
|
100 |
|
9c1e6f
|
101 |
class TestMakeRegistries(_Base): |
993216
|
102 |
|
TS |
103 |
def _callFUT(self, identifiers, authenticators, challengers, mdproviders): |
|
104 |
from repoze.who.api import make_registries |
|
105 |
return make_registries(identifiers, authenticators, |
|
106 |
challengers, mdproviders) |
|
107 |
|
|
108 |
def test_empty(self): |
|
109 |
iface_reg, name_reg = self._callFUT([], [], [], []) |
|
110 |
self.assertEqual(iface_reg, {}) |
|
111 |
self.assertEqual(name_reg, {}) |
|
112 |
|
|
113 |
def test_brokenimpl(self): |
|
114 |
self.assertRaises(ValueError, self._callFUT, |
|
115 |
[(None, object())], [], [], []) |
|
116 |
|
|
117 |
def test_ok(self): |
|
118 |
from repoze.who.interfaces import IIdentifier |
|
119 |
from repoze.who.interfaces import IAuthenticator |
|
120 |
from repoze.who.interfaces import IChallenger |
|
121 |
from repoze.who.interfaces import IMetadataProvider |
|
122 |
credentials1 = {'login':'chris', 'password':'password'} |
|
123 |
dummy_id1 = DummyIdentifier(credentials1) |
|
124 |
credentials2 = {'login':'chris', 'password':'password'} |
|
125 |
dummy_id2 = DummyIdentifier(credentials2) |
|
126 |
identifiers = [ ('id1', dummy_id1), ('id2', dummy_id2) ] |
|
127 |
dummy_auth = DummyAuthenticator(None) |
|
128 |
authenticators = [ ('auth', dummy_auth) ] |
|
129 |
dummy_challenger = DummyChallenger(None) |
|
130 |
challengers = [ ('challenger', dummy_challenger) ] |
|
131 |
dummy_mdprovider = DummyMDProvider() |
|
132 |
mdproviders = [ ('mdprovider', dummy_mdprovider) ] |
|
133 |
iface_reg, name_reg = self._callFUT(identifiers, authenticators, |
|
134 |
challengers, mdproviders) |
|
135 |
self.assertEqual(iface_reg[IIdentifier], [dummy_id1, dummy_id2]) |
|
136 |
self.assertEqual(iface_reg[IAuthenticator], [dummy_auth]) |
|
137 |
self.assertEqual(iface_reg[IChallenger], [dummy_challenger]) |
|
138 |
self.assertEqual(iface_reg[IMetadataProvider], [dummy_mdprovider]) |
|
139 |
self.assertEqual(name_reg['id1'], dummy_id1) |
|
140 |
self.assertEqual(name_reg['id2'], dummy_id2) |
|
141 |
self.assertEqual(name_reg['auth'], dummy_auth) |
|
142 |
self.assertEqual(name_reg['challenger'], dummy_challenger) |
|
143 |
self.assertEqual(name_reg['mdprovider'], dummy_mdprovider) |
|
144 |
|
9c1e6f
|
145 |
class TestMatchClassification(_Base): |
993216
|
146 |
|
TS |
147 |
def _getFUT(self): |
|
148 |
from repoze.who.api import match_classification |
|
149 |
return match_classification |
|
150 |
|
|
151 |
def test_match_classification(self): |
|
152 |
f = self._getFUT() |
|
153 |
from repoze.who.interfaces import IIdentifier |
|
154 |
from repoze.who.interfaces import IChallenger |
|
155 |
from repoze.who.interfaces import IAuthenticator |
|
156 |
multi1 = DummyMultiPlugin() |
|
157 |
multi2 = DummyMultiPlugin() |
|
158 |
multi1.classifications = {IIdentifier:('foo', 'bar'), |
|
159 |
IChallenger:('buz',), |
|
160 |
IAuthenticator:None} |
|
161 |
multi2.classifications = {IIdentifier:('foo', 'baz', 'biz')} |
|
162 |
plugins = (multi1, multi2) |
|
163 |
# specific |
|
164 |
self.assertEqual(f(IIdentifier, plugins, 'foo'), [multi1, multi2]) |
|
165 |
self.assertEqual(f(IIdentifier, plugins, 'bar'), [multi1]) |
|
166 |
self.assertEqual(f(IIdentifier, plugins, 'biz'), [multi2]) |
|
167 |
# any for multi2 |
|
168 |
self.assertEqual(f(IChallenger, plugins, 'buz'), [multi1, multi2]) |
|
169 |
# any for either |
|
170 |
self.assertEqual(f(IAuthenticator, plugins, 'buz'), [multi1, multi2]) |
|
171 |
|
9c1e6f
|
172 |
class APITests(_Base): |
993216
|
173 |
|
TS |
174 |
def _getTargetClass(self): |
|
175 |
from repoze.who.api import API |
|
176 |
return API |
|
177 |
|
|
178 |
def _makeOne(self, |
b482a1
|
179 |
environ=None, |
993216
|
180 |
identifiers=None, |
TS |
181 |
authenticators=None, |
|
182 |
challengers=None, |
b482a1
|
183 |
request_classifier=None, |
993216
|
184 |
mdproviders=None, |
TS |
185 |
challenge_decider=None, |
b482a1
|
186 |
remote_user_key=None, |
993216
|
187 |
logger=None |
TS |
188 |
): |
b482a1
|
189 |
if environ is None: |
TS |
190 |
environ = {} |
993216
|
191 |
if identifiers is None: |
TS |
192 |
identifiers = [] |
|
193 |
if authenticators is None: |
|
194 |
authenticators = [] |
|
195 |
if challengers is None: |
|
196 |
challengers = [] |
b482a1
|
197 |
if request_classifier is None: |
TS |
198 |
request_classifier = DummyRequestClassifier() |
993216
|
199 |
if mdproviders is None: |
TS |
200 |
mdproviders = [] |
|
201 |
if challenge_decider is None: |
|
202 |
challenge_decider = DummyChallengeDecider() |
b482a1
|
203 |
api = self._getTargetClass()(environ, |
TS |
204 |
identifiers, |
993216
|
205 |
authenticators, |
TS |
206 |
challengers, |
|
207 |
mdproviders, |
b482a1
|
208 |
request_classifier, |
993216
|
209 |
challenge_decider, |
b482a1
|
210 |
remote_user_key, |
993216
|
211 |
logger, |
TS |
212 |
) |
|
213 |
return api |
|
214 |
|
|
215 |
def _makeEnviron(self): |
02a504
|
216 |
from wsgiref.util import setup_testing_defaults |
AO |
217 |
environ = {} |
|
218 |
setup_testing_defaults(environ) |
|
219 |
return environ |
b482a1
|
220 |
|
TS |
221 |
def test_class_conforms_to_IAPI(self): |
|
222 |
from zope.interface.verify import verifyClass |
|
223 |
from repoze.who.interfaces import IAPI |
|
224 |
verifyClass(IAPI, self._getTargetClass()) |
993216
|
225 |
|
52bc23
|
226 |
def test_ctor_accepts_logger_instance(self): |
TS |
227 |
logger = DummyLogger() |
|
228 |
api = self._makeOne(logger=logger) |
|
229 |
self.assertEqual(len(logger._info), 1) |
|
230 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
231 |
self.assertEqual(len(logger._debug), 0) |
|
232 |
|
|
233 |
def test_authenticate_no_identities(self): |
|
234 |
logger = DummyLogger() |
|
235 |
environ = self._makeEnviron() |
|
236 |
plugin = DummyNoResultsIdentifier() |
|
237 |
plugins = [ ('dummy', plugin) ] |
|
238 |
api = self._makeOne(environ=environ, |
|
239 |
identifiers=plugins, |
|
240 |
logger=logger) |
|
241 |
identity = api.authenticate() |
|
242 |
self.assertEqual(identity, None) |
|
243 |
self.assertEqual(len(logger._info), 2) |
|
244 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
245 |
self.assertEqual(logger._info[1], 'no identities found, ' |
|
246 |
'not authenticating') |
|
247 |
|
|
248 |
def test_authenticate_w_identities_no_authenticators(self): |
|
249 |
logger = DummyLogger() |
|
250 |
environ = self._makeEnviron() |
|
251 |
credentials = {'login':'chris', 'password':'password'} |
|
252 |
identifier = DummyIdentifier(credentials) |
|
253 |
identifiers = [ ('i', identifier) ] |
|
254 |
api = self._makeOne(environ=environ, |
|
255 |
identifiers=identifiers, logger=logger) |
|
256 |
identity = api.authenticate() |
|
257 |
self.assertEqual(identity, None) |
|
258 |
self.assertEqual(len(logger._info), 2) |
|
259 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
260 |
# Hmm, should this message distinguish "none found" from |
|
261 |
# "none authenticated"? |
|
262 |
self.assertEqual(logger._info[1], 'no identities found, ' |
|
263 |
'not authenticating') |
|
264 |
|
|
265 |
#def test_authenticate_w_identities_w_authenticators_miss(self): |
|
266 |
def test_authenticate_w_identities_w_authenticators_hit(self): |
|
267 |
logger = DummyLogger() |
|
268 |
environ = self._makeEnviron() |
|
269 |
credentials = {'login':'chris', 'password':'password'} |
|
270 |
identifier = DummyIdentifier(credentials) |
|
271 |
identifiers = [ ('i', identifier) ] |
|
272 |
authenticator = DummyAuthenticator('chrisid') |
|
273 |
authenticators = [ ('a', authenticator) ] |
|
274 |
api = self._makeOne(environ=environ, |
|
275 |
identifiers=identifiers, |
|
276 |
authenticators=authenticators, |
|
277 |
logger=logger) |
|
278 |
identity = api.authenticate() |
|
279 |
self.assertEqual(identity['repoze.who.userid'], 'chrisid') |
|
280 |
self.failUnless(identity['identifier'] is identifier) |
|
281 |
self.failUnless(identity['authenticator'] is authenticator) |
|
282 |
|
|
283 |
self.assertEqual(len(logger._info), 1) |
|
284 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
285 |
|
|
286 |
def test_challenge_noidentifier_noapp(self): |
|
287 |
logger = DummyLogger() |
|
288 |
identity = {'login':'chris', 'password':'password'} |
|
289 |
environ = self._makeEnviron() |
|
290 |
environ['repoze.who.identity'] = identity |
|
291 |
challenger = DummyChallenger() |
|
292 |
plugins = [ ('challenge', challenger) ] |
|
293 |
api = self._makeOne(environ=environ, |
|
294 |
challengers=plugins, |
|
295 |
request_classifier=lambda environ: 'match', |
|
296 |
logger=logger, |
|
297 |
) |
|
298 |
app = api.challenge('401 Unauthorized', []) |
|
299 |
self.assertEqual(app, None) |
|
300 |
self.assertEqual(environ['challenged'], None) |
|
301 |
self.assertEqual(len(logger._info), 2) |
|
302 |
self.assertEqual(logger._info[0], 'request classification: match') |
|
303 |
self.assertEqual(logger._info[1], 'no challenge app returned') |
|
304 |
self.assertEqual(len(logger._debug), 2) |
|
305 |
self.failUnless(logger._debug[0].startswith( |
|
306 |
'challengers registered: [')) |
|
307 |
self.failUnless(logger._debug[1].startswith( |
|
308 |
'challengers matched for ' |
|
309 |
'classification "match": [')) |
|
310 |
|
|
311 |
def test_challenge_noidentifier_with_app(self): |
|
312 |
logger = DummyLogger() |
|
313 |
identity = {'login':'chris', 'password':'password'} |
|
314 |
environ = self._makeEnviron() |
|
315 |
environ['repoze.who.identity'] = identity |
|
316 |
app = DummyApp() |
|
317 |
challenger = DummyChallenger(app) |
|
318 |
plugins = [ ('challenge', challenger) ] |
|
319 |
api = self._makeOne(environ=environ, |
|
320 |
challengers=plugins, |
|
321 |
request_classifier=lambda environ: 'match', |
|
322 |
logger=logger, |
|
323 |
) |
|
324 |
result = api.challenge('401 Unauthorized', []) |
|
325 |
self.assertEqual(result, app) |
|
326 |
self.assertEqual(environ['challenged'], app) |
|
327 |
self.assertEqual(len(logger._info), 2) |
|
328 |
self.assertEqual(logger._info[0], 'request classification: match') |
|
329 |
self.failUnless(logger._info[1].startswith('challenger plugin ')) |
|
330 |
self.failUnless(logger._info[1].endswith( |
|
331 |
'"challenge" returned an app')) |
|
332 |
self.assertEqual(len(logger._debug), 2) |
|
333 |
self.failUnless(logger._debug[0].startswith( |
|
334 |
'challengers registered: [')) |
|
335 |
self.failUnless(logger._debug[1].startswith( |
|
336 |
'challengers matched for ' |
|
337 |
'classification "match": [')) |
|
338 |
|
|
339 |
def test_challenge_identifier_no_app_no_forget_headers(self): |
|
340 |
logger = DummyLogger() |
|
341 |
credentials = {'login':'chris', 'password':'password'} |
|
342 |
identifier = DummyIdentifier(credentials) |
|
343 |
identity = {'login':'chris', |
|
344 |
'password':'password', |
|
345 |
'identifier': identifier} |
|
346 |
environ = self._makeEnviron() |
|
347 |
environ['repoze.who.identity'] = identity |
|
348 |
challenger = DummyChallenger() |
|
349 |
plugins = [ ('challenge', challenger) ] |
|
350 |
api = self._makeOne(environ=environ, |
|
351 |
challengers=plugins, |
|
352 |
request_classifier=lambda environ: 'match', |
|
353 |
logger=logger, |
|
354 |
) |
|
355 |
result = api.challenge('401 Unauthorized', []) |
|
356 |
self.assertEqual(result, None) |
|
357 |
self.assertEqual(environ['challenged'], None) |
|
358 |
self.assertEqual(identifier.forgotten, identity) |
|
359 |
self.assertEqual(len(logger._info), 2) |
|
360 |
self.assertEqual(logger._info[0], 'request classification: match') |
|
361 |
self.assertEqual(logger._info[1], 'no challenge app returned') |
|
362 |
self.assertEqual(len(logger._debug), 2) |
|
363 |
self.failUnless(logger._debug[0].startswith( |
|
364 |
'challengers registered: [')) |
|
365 |
self.failUnless(logger._debug[1].startswith( |
|
366 |
'challengers matched for ' |
|
367 |
'classification "match": [')) |
|
368 |
|
|
369 |
def test_challenge_identifier_app_no_forget_headers(self): |
|
370 |
logger = DummyLogger() |
|
371 |
credentials = {'login':'chris', 'password':'password'} |
|
372 |
identifier = DummyIdentifier(credentials) |
|
373 |
identity = {'login':'chris', |
|
374 |
'password':'password', |
|
375 |
'identifier': identifier} |
|
376 |
environ = self._makeEnviron() |
|
377 |
environ['repoze.who.identity'] = identity |
|
378 |
app = DummyApp() |
|
379 |
challenger = DummyChallenger(app) |
|
380 |
plugins = [ ('challenge', challenger) ] |
|
381 |
api = self._makeOne(environ=environ, |
|
382 |
challengers=plugins, |
|
383 |
request_classifier=lambda environ: 'match', |
|
384 |
logger=logger, |
|
385 |
) |
|
386 |
result = api.challenge('401 Unauthorized', []) |
|
387 |
self.assertEqual(result, app) |
|
388 |
self.assertEqual(environ['challenged'], app) |
|
389 |
self.assertEqual(identifier.forgotten, identity) |
|
390 |
self.assertEqual(len(logger._info), 2) |
|
391 |
self.assertEqual(logger._info[0], 'request classification: match') |
|
392 |
self.failUnless(logger._info[1].startswith('challenger plugin ')) |
|
393 |
self.failUnless(logger._info[1].endswith( |
|
394 |
'"challenge" returned an app')) |
|
395 |
self.assertEqual(len(logger._debug), 2) |
|
396 |
self.failUnless(logger._debug[0].startswith( |
|
397 |
'challengers registered: [')) |
|
398 |
self.failUnless(logger._debug[1].startswith( |
|
399 |
'challengers matched for ' |
|
400 |
'classification "match": [')) |
|
401 |
|
|
402 |
def test_challenge_identifier_no_app_forget_headers(self): |
|
403 |
FORGET_HEADERS = [('X-testing-forget', 'Oubliez!')] |
|
404 |
logger = DummyLogger() |
|
405 |
credentials = {'login':'chris', 'password':'password'} |
|
406 |
identifier = DummyIdentifier(credentials, |
|
407 |
forget_headers=FORGET_HEADERS) |
|
408 |
identity = {'login':'chris', |
|
409 |
'password':'password', |
|
410 |
'identifier': identifier} |
|
411 |
environ = self._makeEnviron() |
|
412 |
environ['repoze.who.identity'] = identity |
|
413 |
app = DummyApp() |
|
414 |
challenger = DummyChallenger(app) |
|
415 |
plugins = [ ('challenge', challenger) ] |
|
416 |
api = self._makeOne(environ=environ, |
|
417 |
challengers=plugins, |
|
418 |
request_classifier=lambda environ: 'match', |
|
419 |
logger=logger, |
|
420 |
) |
|
421 |
result = api.challenge('401 Unauthorized', []) |
|
422 |
self.assertEqual(result, app) |
|
423 |
self.assertEqual(environ['challenged'], app) |
|
424 |
self.assertEqual(challenger._challenged_with[3], FORGET_HEADERS) |
|
425 |
self.assertEqual(len(logger._info), 3) |
|
426 |
self.assertEqual(logger._info[0], 'request classification: match') |
|
427 |
self.failUnless(logger._info[1].startswith( |
|
428 |
'forgetting via headers from')) |
|
429 |
self.failUnless(logger._info[1].endswith(repr(FORGET_HEADERS))) |
|
430 |
self.failUnless(logger._info[2].startswith('challenger plugin ')) |
|
431 |
self.failUnless(logger._info[2].endswith( |
|
432 |
'"challenge" returned an app')) |
|
433 |
self.assertEqual(len(logger._debug), 2) |
|
434 |
self.failUnless(logger._debug[0].startswith( |
|
435 |
'challengers registered: [')) |
|
436 |
self.failUnless(logger._debug[1].startswith( |
|
437 |
'challengers matched for ' |
|
438 |
'classification "match": [')) |
|
439 |
|
|
440 |
def test_multi_challenge_firstwins(self): |
|
441 |
credentials = {'login':'chris', 'password':'password'} |
|
442 |
identifier = DummyIdentifier(credentials) |
|
443 |
identity = {'login':'chris', |
|
444 |
'password':'password', |
|
445 |
'identifier': identifier} |
|
446 |
environ = self._makeEnviron() |
|
447 |
environ['repoze.who.identity'] = identity |
|
448 |
app1 = DummyApp() |
|
449 |
app2 = DummyApp() |
|
450 |
challenger1 = DummyChallenger(app1) |
|
451 |
challenger2 = DummyChallenger(app2) |
|
452 |
plugins = [ ('challenge1', challenger1), ('challenge2', challenger2) ] |
|
453 |
api = self._makeOne(environ=environ, challengers=plugins, |
|
454 |
request_classifier=lambda environ: 'match') |
|
455 |
result = api.challenge('401 Unauthorized', []) |
|
456 |
self.assertEqual(result, app1) |
|
457 |
self.assertEqual(environ['challenged'], app1) |
|
458 |
self.assertEqual(identifier.forgotten, identity) |
|
459 |
|
|
460 |
def test_multi_challenge_skipnomatch_findimplicit(self): |
|
461 |
from repoze.who.interfaces import IChallenger |
|
462 |
credentials = {'login':'chris', 'password':'password'} |
|
463 |
identifier = DummyIdentifier(credentials) |
|
464 |
identity = {'login':'chris', |
|
465 |
'password':'password', |
|
466 |
'identifier': identifier} |
|
467 |
environ = self._makeEnviron() |
|
468 |
environ['repoze.who.identity'] = identity |
|
469 |
app1 = DummyApp() |
|
470 |
app2 = DummyApp() |
|
471 |
challenger1 = DummyChallenger(app1) |
|
472 |
challenger1.classifications = {IChallenger:['nomatch']} |
|
473 |
challenger2 = DummyChallenger(app2) |
|
474 |
challenger2.classifications = {IChallenger:None} |
|
475 |
plugins = [ ('challenge1', challenger1), ('challenge2', challenger2) ] |
|
476 |
api = self._makeOne(environ=environ, challengers=plugins, |
|
477 |
request_classifier=lambda environ: 'match') |
|
478 |
result = api.challenge('401 Unauthorized', []) |
|
479 |
self.assertEqual(result, app2) |
|
480 |
self.assertEqual(environ['challenged'], app2) |
|
481 |
self.assertEqual(identifier.forgotten, identity) |
|
482 |
|
|
483 |
def test_multi_challenge_skipnomatch_findexplicit(self): |
|
484 |
from repoze.who.interfaces import IChallenger |
|
485 |
credentials = {'login':'chris', 'password':'password'} |
|
486 |
identifier = DummyIdentifier(credentials) |
|
487 |
identity = {'login':'chris', |
|
488 |
'password':'password', |
|
489 |
'identifier': identifier} |
|
490 |
environ = self._makeEnviron() |
|
491 |
environ['repoze.who.identity'] = identity |
|
492 |
app1 = DummyApp() |
|
493 |
app2 = DummyApp() |
|
494 |
challenger1 = DummyChallenger(app1) |
|
495 |
challenger1.classifications = {IChallenger:['nomatch']} |
|
496 |
challenger2 = DummyChallenger(app2) |
|
497 |
challenger2.classifications = {IChallenger:['match']} |
|
498 |
plugins = [ ('challenge1', challenger1), ('challenge2', challenger2) ] |
|
499 |
api = self._makeOne(environ=environ, challengers=plugins, |
|
500 |
request_classifier=lambda environ: 'match') |
|
501 |
result = api.challenge('401 Unauthorized', []) |
|
502 |
self.assertEqual(result, app2) |
|
503 |
self.assertEqual(environ['challenged'], app2) |
|
504 |
self.assertEqual(identifier.forgotten, identity) |
|
505 |
|
fdd86d
|
506 |
def test_remember_identifier_plugin_returns_none(self): |
TS |
507 |
class _Identifier: |
|
508 |
def identify(self, environ): |
|
509 |
return None |
|
510 |
def remember(self, environ, identity): |
|
511 |
return () |
|
512 |
def forget(self, environ, identity): |
|
513 |
return () |
|
514 |
identity = {'identifier': _Identifier()} |
|
515 |
api = self._makeOne() |
|
516 |
headers = api.remember(identity=identity) |
|
517 |
self.assertEqual(tuple(headers), ()) |
|
518 |
|
52bc23
|
519 |
def test_remember_no_identity_passed_or_in_environ(self): |
TS |
520 |
logger = DummyLogger() |
|
521 |
environ = self._makeEnviron() |
|
522 |
api = self._makeOne(environ=environ) |
|
523 |
self.assertEqual(len(api.remember()), 0) |
|
524 |
self.assertEqual(len(logger._info), 0) |
|
525 |
self.assertEqual(len(logger._debug), 0) |
|
526 |
|
|
527 |
def test_remember_no_identity_passed_but_in_environ(self): |
|
528 |
HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
|
529 |
logger = DummyLogger() |
|
530 |
class _Identifier: |
|
531 |
def remember(self, environ, identity): |
|
532 |
return HEADERS |
|
533 |
environ = self._makeEnviron() |
|
534 |
environ['repoze.who.identity'] = {'identifier': _Identifier()} |
|
535 |
api = self._makeOne(environ=environ, logger=logger) |
|
536 |
self.assertEqual(api.remember(), HEADERS) |
|
537 |
self.assertEqual(len(logger._info), 2) |
|
538 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
539 |
self.failUnless(logger._info[1].startswith( |
|
540 |
'remembering via headers from')) |
|
541 |
self.failUnless(logger._info[1].endswith(repr(HEADERS))) |
|
542 |
self.assertEqual(len(logger._debug), 0) |
|
543 |
|
|
544 |
def test_remember_w_identity_passed_no_identifier(self): |
|
545 |
logger = DummyLogger() |
|
546 |
environ = self._makeEnviron() |
|
547 |
api = self._makeOne(environ=environ, logger=logger) |
|
548 |
identity = {} |
|
549 |
self.assertEqual(len(api.remember(identity)), 0) |
|
550 |
self.assertEqual(len(logger._info), 1) |
|
551 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
552 |
self.assertEqual(len(logger._debug), 0) |
|
553 |
|
|
554 |
def test_remember_w_identity_passed_w_identifier(self): |
|
555 |
HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
|
556 |
logger = DummyLogger() |
|
557 |
class _Identifier: |
|
558 |
def remember(self, environ, identity): |
|
559 |
return HEADERS |
|
560 |
environ = self._makeEnviron() |
|
561 |
api = self._makeOne(environ=environ, logger=logger) |
|
562 |
identity = {'identifier': _Identifier()} |
|
563 |
self.assertEqual(api.remember(identity), HEADERS) |
|
564 |
self.assertEqual(len(logger._info), 2) |
|
565 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
566 |
self.failUnless(logger._info[1].startswith( |
|
567 |
'remembering via headers from')) |
|
568 |
self.failUnless(logger._info[1].endswith(repr(HEADERS))) |
|
569 |
self.assertEqual(len(logger._debug), 0) |
fdd86d
|
570 |
|
TS |
571 |
def test_forget_identifier_plugin_returns_none(self): |
|
572 |
class _Identifier: |
|
573 |
def identify(self, environ): |
|
574 |
return None |
|
575 |
def remember(self, environ, identity): |
|
576 |
return () |
|
577 |
def forget(self, environ, identity): |
|
578 |
return () |
|
579 |
identity = {'identifier': _Identifier()} |
|
580 |
api = self._makeOne() |
|
581 |
headers = api.forget(identity=identity) |
|
582 |
self.assertEqual(tuple(headers), ()) |
52bc23
|
583 |
|
TS |
584 |
def test_forget_no_identity_passed_or_in_environ(self): |
|
585 |
logger = DummyLogger() |
|
586 |
environ = self._makeEnviron() |
|
587 |
api = self._makeOne(environ=environ, logger=logger) |
|
588 |
self.assertEqual(len(api.forget()), 0) |
|
589 |
self.assertEqual(len(logger._info), 1) |
|
590 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
591 |
self.assertEqual(len(logger._debug), 0) |
|
592 |
|
|
593 |
def test_forget_no_identity_passed_but_in_environ(self): |
|
594 |
HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
|
595 |
logger = DummyLogger() |
|
596 |
class _Identifier: |
|
597 |
def forget(self, environ, identity): |
|
598 |
return HEADERS |
|
599 |
environ = self._makeEnviron() |
|
600 |
environ['repoze.who.identity'] = {'identifier': _Identifier()} |
|
601 |
api = self._makeOne(environ=environ, logger=logger) |
|
602 |
self.assertEqual(api.forget(), HEADERS) |
|
603 |
self.assertEqual(len(logger._info), 2) |
|
604 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
605 |
self.failUnless(logger._info[1].startswith( |
|
606 |
'forgetting via headers from')) |
|
607 |
self.failUnless(logger._info[1].endswith(repr(HEADERS))) |
|
608 |
self.assertEqual(len(logger._debug), 0) |
|
609 |
|
|
610 |
def test_forget_w_identity_passed_no_identifier(self): |
|
611 |
environ = self._makeEnviron() |
|
612 |
logger = DummyLogger() |
|
613 |
api = self._makeOne(environ=environ, logger=logger) |
|
614 |
identity = {} |
|
615 |
self.assertEqual(len(api.forget(identity)), 0) |
|
616 |
self.assertEqual(len(logger._info), 1) |
|
617 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
618 |
self.assertEqual(len(logger._debug), 0) |
|
619 |
|
|
620 |
def test_forget_w_identity_passed_w_identifier(self): |
|
621 |
HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
|
622 |
logger = DummyLogger() |
|
623 |
class _Identifier: |
|
624 |
def forget(self, environ, identity): |
|
625 |
return HEADERS |
|
626 |
environ = self._makeEnviron() |
|
627 |
api = self._makeOne(environ=environ, logger=logger) |
|
628 |
identity = {'identifier': _Identifier()} |
|
629 |
self.assertEqual(api.forget(identity), HEADERS) |
|
630 |
self.assertEqual(len(logger._info), 2) |
|
631 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
632 |
self.failUnless(logger._info[1].startswith( |
|
633 |
'forgetting via headers from')) |
|
634 |
self.failUnless(logger._info[1].endswith(repr(HEADERS))) |
|
635 |
self.assertEqual(len(logger._debug), 0) |
993216
|
636 |
|
9a8e60
|
637 |
def test_login_w_identifier_name_hit(self): |
TS |
638 |
REMEMBER_HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
|
639 |
FORGET_HEADERS = [('Spam', 'Blah')] |
|
640 |
class _Identifier: |
|
641 |
def identify(self, environ): |
|
642 |
pass |
|
643 |
def remember(self, environ, identity): |
fdd86d
|
644 |
return REMEMBER_HEADERS[1:] |
9a8e60
|
645 |
def forget(self, environ, identity): |
TS |
646 |
return FORGET_HEADERS |
|
647 |
class _BogusIdentifier: |
|
648 |
def identify(self, environ): |
|
649 |
pass |
|
650 |
def remember(self, environ, identity): |
fdd86d
|
651 |
return REMEMBER_HEADERS[:1] |
9a8e60
|
652 |
def forget(self, environ, identity): |
TS |
653 |
pass |
|
654 |
authenticator = DummyAuthenticator('chrisid') |
|
655 |
environ = self._makeEnviron() |
|
656 |
identifiers = [('bogus', _BogusIdentifier()), |
|
657 |
('valid', _Identifier()), |
|
658 |
] |
|
659 |
api = self._makeOne(identifiers=identifiers, |
|
660 |
authenticators=[('authentic', authenticator)], |
|
661 |
environ=environ) |
|
662 |
identity, headers = api.login({'login': 'chrisid'}, 'valid') |
|
663 |
self.assertEqual(identity['repoze.who.userid'], 'chrisid') |
fdd86d
|
664 |
self.assertEqual(headers, REMEMBER_HEADERS[1:]) |
cfe26c
|
665 |
|
9a8e60
|
666 |
def test_login_wo_identifier_name_hit(self): |
TS |
667 |
REMEMBER_HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
|
668 |
FORGET_HEADERS = [('Spam', 'Blah')] |
|
669 |
class _Identifier: |
|
670 |
def identify(self, environ): |
|
671 |
pass |
|
672 |
def remember(self, environ, identity): |
fdd86d
|
673 |
return REMEMBER_HEADERS[1:] |
9a8e60
|
674 |
def forget(self, environ, identity): |
TS |
675 |
return FORGET_HEADERS |
|
676 |
class _BogusIdentifier: |
|
677 |
def identify(self, environ): |
|
678 |
pass |
|
679 |
def remember(self, environ, identity): |
fdd86d
|
680 |
return REMEMBER_HEADERS[:1] |
9a8e60
|
681 |
def forget(self, environ, identity): |
TS |
682 |
pass |
|
683 |
authenticator = DummyAuthenticator('chrisid') |
|
684 |
environ = self._makeEnviron() |
fdd86d
|
685 |
identifiers = [('bogus', _BogusIdentifier()), |
TS |
686 |
('valid', _Identifier()), |
9a8e60
|
687 |
] |
TS |
688 |
api = self._makeOne(identifiers=identifiers, |
|
689 |
authenticators=[('authentic', authenticator)], |
|
690 |
environ=environ) |
|
691 |
identity, headers = api.login({'login': 'chrisid'}) |
fdd86d
|
692 |
self.assertEqual(identity['repoze.who.userid'], 'chrisid') |
9a8e60
|
693 |
self.assertEqual(headers, REMEMBER_HEADERS) |
TS |
694 |
|
|
695 |
def test_login_w_identifier_name_miss(self): |
|
696 |
REMEMBER_HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
|
697 |
FORGET_HEADERS = [('Spam', 'Blah')] |
|
698 |
class _Identifier: |
|
699 |
def identify(self, environ): |
|
700 |
pass |
|
701 |
def remember(self, environ, identity): |
|
702 |
return REMEMBER_HEADERS |
|
703 |
def forget(self, environ, identity): |
|
704 |
return FORGET_HEADERS |
|
705 |
class _BogusIdentifier: |
|
706 |
def identify(self, environ): |
|
707 |
pass |
|
708 |
def remember(self, environ, identity): |
fdd86d
|
709 |
return () |
9a8e60
|
710 |
def forget(self, environ, identity): |
fdd86d
|
711 |
return () |
9a8e60
|
712 |
authenticator = DummyFailAuthenticator() |
TS |
713 |
environ = self._makeEnviron() |
|
714 |
identifiers = [('bogus', _BogusIdentifier()), |
|
715 |
('valid', _Identifier()), |
|
716 |
] |
|
717 |
api = self._makeOne(identifiers=identifiers, |
|
718 |
authenticators=[('authentic', authenticator)], |
|
719 |
environ=environ) |
|
720 |
identity, headers = api.login({'login': 'notchrisid'}, 'valid') |
|
721 |
self.assertEqual(identity, None) |
|
722 |
self.assertEqual(headers, FORGET_HEADERS) |
|
723 |
|
fdd86d
|
724 |
def test_logout_wo_identifier_name_miss(self): |
924f24
|
725 |
FORGET_HEADERS = [('Spam', 'Blah')] |
TS |
726 |
class _Identifier: |
|
727 |
def identify(self, environ): |
|
728 |
pass |
|
729 |
def remember(self, environ, identity): |
fdd86d
|
730 |
return () |
924f24
|
731 |
def forget(self, environ, identity): |
fdd86d
|
732 |
return FORGET_HEADERS[:1] |
924f24
|
733 |
class _BogusIdentifier: |
TS |
734 |
def identify(self, environ): |
|
735 |
pass |
|
736 |
def remember(self, environ, identity): |
fdd86d
|
737 |
return () |
924f24
|
738 |
def forget(self, environ, identity): |
fdd86d
|
739 |
return FORGET_HEADERS[1:] |
924f24
|
740 |
environ = self._makeEnviron() |
TS |
741 |
identifiers = [('valid', _Identifier()), |
|
742 |
('bogus', _BogusIdentifier()), |
|
743 |
] |
|
744 |
api = self._makeOne(identifiers=identifiers, |
|
745 |
environ=environ) |
|
746 |
headers = api.logout() |
|
747 |
self.assertEqual(headers, FORGET_HEADERS) |
|
748 |
|
|
749 |
def test_logout_w_identifier_name(self): |
|
750 |
FORGET_HEADERS = [('Spam', 'Blah')] |
|
751 |
class _Identifier: |
|
752 |
def identify(self, environ): |
|
753 |
pass |
|
754 |
def remember(self, environ, identity): |
fdd86d
|
755 |
return () |
924f24
|
756 |
def forget(self, environ, identity): |
TS |
757 |
return FORGET_HEADERS |
|
758 |
class _BogusIdentifier: |
|
759 |
def identify(self, environ): |
|
760 |
pass |
|
761 |
def remember(self, environ, identity): |
fdd86d
|
762 |
return () |
924f24
|
763 |
def forget(self, environ, identity): |
fdd86d
|
764 |
return () |
924f24
|
765 |
environ = self._makeEnviron() |
TS |
766 |
identifiers = [('bogus', _BogusIdentifier()), |
|
767 |
('valid', _Identifier()), |
|
768 |
] |
|
769 |
api = self._makeOne(identifiers=identifiers, |
|
770 |
environ=environ) |
|
771 |
headers = api.logout('valid') |
|
772 |
self.assertEqual(headers, FORGET_HEADERS) |
|
773 |
|
|
774 |
def test_logout_wo_identifier_name(self): |
9a8e60
|
775 |
REMEMBER_HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')] |
TS |
776 |
FORGET_HEADERS = [('Spam', 'Blah')] |
|
777 |
class _Identifier: |
|
778 |
def identify(self, environ): |
|
779 |
pass |
|
780 |
def remember(self, environ, identity): |
|
781 |
return REMEMBER_HEADERS |
|
782 |
def forget(self, environ, identity): |
|
783 |
return FORGET_HEADERS |
|
784 |
class _BogusIdentifier: |
|
785 |
def identify(self, environ): |
|
786 |
pass |
|
787 |
def remember(self, environ, identity): |
fdd86d
|
788 |
return () |
9a8e60
|
789 |
def forget(self, environ, identity): |
fdd86d
|
790 |
return () |
9a8e60
|
791 |
authenticator = DummyFailAuthenticator() |
TS |
792 |
environ = self._makeEnviron() |
|
793 |
identifiers = [('valid', _Identifier()), |
|
794 |
('bogus', _BogusIdentifier()), |
|
795 |
] |
|
796 |
api = self._makeOne(identifiers=identifiers, |
|
797 |
authenticators=[('authentic', authenticator)], |
|
798 |
environ=environ) |
e24a75
|
799 |
headers = api.logout() |
9a8e60
|
800 |
self.assertEqual(headers, FORGET_HEADERS) |
TS |
801 |
|
e24a75
|
802 |
def test_logout_removes_repoze_who_identity(self): |
CM |
803 |
class _Identifier: |
|
804 |
def identify(self, environ): |
|
805 |
pass |
|
806 |
def forget(self, environ, identity): |
fdd86d
|
807 |
return () |
e24a75
|
808 |
def remember(self, environ, identity): |
fdd86d
|
809 |
return () |
e24a75
|
810 |
authenticator = DummyFailAuthenticator() |
CM |
811 |
environ = self._makeEnviron() |
|
812 |
environ['repoze.who.identity'] = 'identity' |
|
813 |
identifiers = [('valid', _Identifier())] |
|
814 |
api = self._makeOne(identifiers=identifiers, |
|
815 |
authenticators=[('authentic', authenticator)], |
|
816 |
environ=environ) |
|
817 |
api.logout() |
|
818 |
self.failIf('repoze.who.identity' in environ) |
|
819 |
|
b482a1
|
820 |
def test__identify_success(self): |
993216
|
821 |
environ = self._makeEnviron() |
TS |
822 |
credentials = {'login':'chris', 'password':'password'} |
|
823 |
identifier = DummyIdentifier(credentials) |
|
824 |
identifiers = [ ('i', identifier) ] |
b482a1
|
825 |
api = self._makeOne(environ=environ, identifiers=identifiers) |
TS |
826 |
results = api._identify() |
993216
|
827 |
self.assertEqual(len(results), 1) |
TS |
828 |
new_identifier, identity = results[0] |
|
829 |
self.assertEqual(new_identifier, identifier) |
|
830 |
self.assertEqual(identity['login'], 'chris') |
|
831 |
self.assertEqual(identity['password'], 'password') |
|
832 |
|
b482a1
|
833 |
def test__identify_success_empty_identity(self): |
993216
|
834 |
environ = self._makeEnviron() |
TS |
835 |
identifier = DummyIdentifier({}) |
|
836 |
identifiers = [ ('i', identifier) ] |
b482a1
|
837 |
api = self._makeOne(environ=environ, identifiers=identifiers) |
TS |
838 |
results = api._identify() |
993216
|
839 |
self.assertEqual(len(results), 1) |
TS |
840 |
new_identifier, identity = results[0] |
|
841 |
self.assertEqual(new_identifier, identifier) |
|
842 |
self.assertEqual(identity, {}) |
|
843 |
|
b482a1
|
844 |
def test__identify_fail(self): |
52bc23
|
845 |
logger = DummyLogger() |
993216
|
846 |
environ = self._makeEnviron() |
TS |
847 |
plugin = DummyNoResultsIdentifier() |
|
848 |
plugins = [ ('dummy', plugin) ] |
52bc23
|
849 |
api = self._makeOne(environ=environ, |
TS |
850 |
identifiers=plugins, |
|
851 |
logger=logger) |
b482a1
|
852 |
results = api._identify() |
993216
|
853 |
self.assertEqual(len(results), 0) |
52bc23
|
854 |
self.assertEqual(len(logger._info), 1) |
TS |
855 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
856 |
self.assertEqual(len(logger._debug), 4) |
|
857 |
self.failUnless(logger._debug[0].startswith( |
|
858 |
'identifier plugins registered: [')) |
|
859 |
self.failUnless(logger._debug[1].startswith( |
|
860 |
'identifier plugins matched for ' |
|
861 |
'classification "browser": [')) |
|
862 |
self.failUnless(logger._debug[2].startswith( |
|
863 |
'no identity returned from <')) |
|
864 |
self.failUnless(logger._debug[2].endswith('> (None)')) |
|
865 |
self.assertEqual(logger._debug[3], 'identities found: []') |
993216
|
866 |
|
b482a1
|
867 |
def test__identify_success_skip_noresults(self): |
993216
|
868 |
environ = self._makeEnviron() |
TS |
869 |
api = self._makeOne() |
|
870 |
plugin1 = DummyNoResultsIdentifier() |
|
871 |
credentials = {'login':'chris', 'password':'password'} |
|
872 |
plugin2 = DummyIdentifier(credentials) |
|
873 |
plugins = [ ('identifier1', plugin1), ('identifier2', plugin2) ] |
b482a1
|
874 |
api = self._makeOne(environ=environ, identifiers=plugins) |
TS |
875 |
results = api._identify() |
993216
|
876 |
self.assertEqual(len(results), 1) |
TS |
877 |
new_identifier, identity = results[0] |
|
878 |
self.assertEqual(new_identifier, plugin2) |
|
879 |
self.assertEqual(identity['login'], 'chris') |
|
880 |
self.assertEqual(identity['password'], 'password') |
|
881 |
|
b482a1
|
882 |
def test__identify_success_multiresults(self): |
993216
|
883 |
environ = self._makeEnviron() |
TS |
884 |
api = self._makeOne() |
|
885 |
plugin1 = DummyIdentifier({'login':'fred','password':'fred'}) |
|
886 |
plugin2 = DummyIdentifier({'login':'bob','password':'bob'}) |
|
887 |
plugins = [ ('identifier1', plugin1), ('identifier2', plugin2) ] |
b482a1
|
888 |
api = self._makeOne(environ=environ, identifiers=plugins) |
TS |
889 |
results = api._identify() |
993216
|
890 |
self.assertEqual(len(results), 2) |
TS |
891 |
new_identifier, identity = results[0] |
|
892 |
self.assertEqual(new_identifier, plugin1) |
|
893 |
self.assertEqual(identity['login'], 'fred') |
|
894 |
self.assertEqual(identity['password'], 'fred') |
|
895 |
new_identifier, identity = results[1] |
|
896 |
self.assertEqual(new_identifier, plugin2) |
|
897 |
self.assertEqual(identity['login'], 'bob') |
|
898 |
self.assertEqual(identity['password'], 'bob') |
|
899 |
|
b482a1
|
900 |
def test__identify_find_implicit_classifier(self): |
993216
|
901 |
environ = self._makeEnviron() |
TS |
902 |
api = self._makeOne() |
|
903 |
plugin1 = DummyIdentifier({'login':'fred','password':'fred'}) |
|
904 |
from repoze.who.interfaces import IIdentifier |
|
905 |
plugin1.classifications = {IIdentifier:['nomatch']} |
|
906 |
plugin2 = DummyIdentifier({'login':'bob','password':'bob'}) |
|
907 |
plugins = [ ('identifier1', plugin1), ('identifier2', plugin2) ] |
b482a1
|
908 |
api = self._makeOne(environ=environ, identifiers=plugins, |
TS |
909 |
request_classifier=lambda environ: 'match') |
|
910 |
results = api._identify() |
993216
|
911 |
self.assertEqual(len(results), 1) |
TS |
912 |
plugin, creds = results[0] |
|
913 |
self.assertEqual(creds['login'], 'bob') |
|
914 |
self.assertEqual(creds['password'], 'bob') |
|
915 |
self.assertEqual(plugin, plugin2) |
|
916 |
|
b482a1
|
917 |
def test__identify_find_explicit_classifier(self): |
993216
|
918 |
environ = self._makeEnviron() |
TS |
919 |
from repoze.who.interfaces import IIdentifier |
|
920 |
plugin1 = DummyIdentifier({'login':'fred','password':'fred'}) |
|
921 |
plugin1.classifications = {IIdentifier:['nomatch']} |
|
922 |
plugin2 = DummyIdentifier({'login':'bob','password':'bob'}) |
|
923 |
plugin2.classifications = {IIdentifier:['match']} |
|
924 |
plugins= [ ('identifier1', plugin1), ('identifier2', plugin2) ] |
b482a1
|
925 |
api = self._makeOne(environ=environ, identifiers=plugins, |
TS |
926 |
request_classifier=lambda environ: 'match') |
|
927 |
results = api._identify() |
993216
|
928 |
self.assertEqual(len(results), 1) |
TS |
929 |
plugin, creds = results[0] |
|
930 |
self.assertEqual(creds['login'], 'bob') |
|
931 |
self.assertEqual(creds['password'], 'bob') |
|
932 |
self.assertEqual(plugin, plugin2) |
|
933 |
|
b482a1
|
934 |
def test__authenticate_success(self): |
993216
|
935 |
environ = self._makeEnviron() |
TS |
936 |
plugin1 = DummyAuthenticator('a') |
|
937 |
plugins = [ ('identifier1', plugin1) ] |
b482a1
|
938 |
api = self._makeOne(environ=environ, authenticators=plugins) |
993216
|
939 |
identities = [ (None, {'login':'chris', 'password':'password'}) ] |
b482a1
|
940 |
results = api._authenticate(identities) |
993216
|
941 |
self.assertEqual(len(results), 1) |
TS |
942 |
result = results[0] |
|
943 |
rank, authenticator, identifier, creds, userid = result |
|
944 |
self.assertEqual(rank, (0,0)) |
|
945 |
self.assertEqual(authenticator, plugin1) |
|
946 |
self.assertEqual(identifier, None) |
|
947 |
self.assertEqual(creds['login'], 'chris') |
|
948 |
self.assertEqual(creds['password'], 'password') |
|
949 |
self.assertEqual(userid, 'a') |
|
950 |
|
b482a1
|
951 |
def test__authenticate_fail(self): |
52bc23
|
952 |
logger = DummyLogger() |
993216
|
953 |
environ = self._makeEnviron() |
52bc23
|
954 |
# no authenticators |
TS |
955 |
api = self._makeOne(environ=environ, logger=logger) |
993216
|
956 |
identities = [ (None, {'login':'chris', 'password':'password'}) ] |
b482a1
|
957 |
result = api._authenticate(identities) |
993216
|
958 |
self.assertEqual(len(result), 0) |
52bc23
|
959 |
self.assertEqual(len(logger._info), 1) |
TS |
960 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
961 |
self.assertEqual(len(logger._debug), 3) |
|
962 |
self.assertEqual(logger._debug[0], 'authenticator plugins ' |
|
963 |
'registered: []') |
|
964 |
self.assertEqual(logger._debug[1], 'authenticator plugins matched ' |
|
965 |
'for classification "browser": []') |
|
966 |
self.assertEqual(logger._debug[2], 'identities authenticated: []') |
993216
|
967 |
|
b482a1
|
968 |
def test__authenticate_success_skip_fail(self): |
52bc23
|
969 |
logger = DummyLogger() |
993216
|
970 |
environ = self._makeEnviron() |
TS |
971 |
plugin1 = DummyFailAuthenticator() |
|
972 |
plugin2 = DummyAuthenticator() |
|
973 |
plugins = [ ('dummy1', plugin1), ('dummy2', plugin2) ] |
52bc23
|
974 |
api = self._makeOne(authenticators=plugins, logger=logger) |
993216
|
975 |
creds = {'login':'chris', 'password':'password'} |
TS |
976 |
identities = [ (None, {'login':'chris', 'password':'password'}) ] |
b482a1
|
977 |
results = api._authenticate(identities) |
993216
|
978 |
self.assertEqual(len(results), 1) |
TS |
979 |
result = results[0] |
|
980 |
rank, authenticator, identifier, creds, userid = result |
|
981 |
self.assertEqual(rank, (1,0)) |
|
982 |
self.assertEqual(authenticator, plugin2) |
|
983 |
self.assertEqual(identifier, None) |
|
984 |
self.assertEqual(creds['login'], 'chris') |
|
985 |
self.assertEqual(creds['password'], 'password') |
|
986 |
self.assertEqual(userid, 'chris') |
|
987 |
|
52bc23
|
988 |
self.assertEqual(len(logger._info), 1) |
TS |
989 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
990 |
self.assertEqual(len(logger._debug), 5) |
|
991 |
self.failUnless(logger._debug[0].startswith( |
|
992 |
'authenticator plugins registered: [')) |
|
993 |
self.failUnless(logger._debug[1].startswith( |
|
994 |
'authenticator plugins matched for ' |
|
995 |
'classification "browser": [')) |
|
996 |
self.failUnless(logger._debug[2].startswith('no userid returned from')) |
|
997 |
self.failUnless(logger._debug[3].startswith('userid returned from')) |
|
998 |
self.failUnless(logger._debug[3].endswith('"chris"')) |
|
999 |
self.failUnless(logger._debug[4].startswith( |
|
1000 |
'identities authenticated: [((1, 0),')) |
|
1001 |
|
b482a1
|
1002 |
def test__authenticate_success_multiresult(self): |
52bc23
|
1003 |
logger = DummyLogger() |
993216
|
1004 |
environ = self._makeEnviron() |
TS |
1005 |
plugin1 = DummyAuthenticator('chris_id1') |
|
1006 |
plugin2 = DummyAuthenticator('chris_id2') |
|
1007 |
plugins = [ ('dummy1',plugin1), ('dummy2',plugin2) ] |
52bc23
|
1008 |
api = self._makeOne(environ=environ, |
TS |
1009 |
authenticators=plugins, logger=logger) |
993216
|
1010 |
creds = {'login':'chris', 'password':'password'} |
TS |
1011 |
identities = [ (None, {'login':'chris', 'password':'password'}) ] |
b482a1
|
1012 |
results = api._authenticate(identities) |
993216
|
1013 |
self.assertEqual(len(results), 2) |
TS |
1014 |
result = results[0] |
|
1015 |
rank, authenticator, identifier, creds, userid = result |
|
1016 |
self.assertEqual(rank, (0,0,)) |
|
1017 |
self.assertEqual(authenticator, plugin1) |
|
1018 |
self.assertEqual(identifier, None) |
|
1019 |
self.assertEqual(creds['login'], 'chris') |
|
1020 |
self.assertEqual(creds['password'], 'password') |
|
1021 |
self.assertEqual(userid, 'chris_id1') |
|
1022 |
result = results[1] |
|
1023 |
rank, authenticator, identifier, creds, userid = result |
|
1024 |
self.assertEqual(rank, (1,0)) |
|
1025 |
self.assertEqual(authenticator, plugin2) |
|
1026 |
self.assertEqual(identifier, None) |
|
1027 |
self.assertEqual(creds['login'], 'chris') |
|
1028 |
self.assertEqual(creds['password'], 'password') |
|
1029 |
self.assertEqual(userid, 'chris_id2') |
52bc23
|
1030 |
|
TS |
1031 |
self.assertEqual(len(logger._info), 1) |
|
1032 |
self.assertEqual(logger._info[0], 'request classification: browser') |
|
1033 |
self.assertEqual(len(logger._debug), 5) |
|
1034 |
self.failUnless(logger._debug[0].startswith( |
|
1035 |
'authenticator plugins registered: [')) |
|
1036 |
self.failUnless(logger._debug[1].startswith( |
|
1037 |
'authenticator plugins matched for ' |
|
1038 |
'classification "browser": [')) |
|
1039 |
self.failUnless(logger._debug[2].startswith('userid returned from')) |
|
1040 |
self.failUnless(logger._debug[2].endswith('"chris_id1"')) |
|
1041 |
self.failUnless(logger._debug[3].startswith('userid returned from')) |
|
1042 |
self.failUnless(logger._debug[3].endswith('"chris_id2"')) |
|
1043 |
self.failUnless(logger._debug[4].startswith( |
|
1044 |
'identities authenticated: [((0, 0),') |
|
1045 |
) |
993216
|
1046 |
|
b482a1
|
1047 |
def test__authenticate_find_implicit_classifier(self): |
993216
|
1048 |
from repoze.who.interfaces import IAuthenticator |
b482a1
|
1049 |
environ = self._makeEnviron() |
TS |
1050 |
plugin1 = DummyAuthenticator('chris_id1') |
993216
|
1051 |
plugin1.classifications = {IAuthenticator:['nomatch']} |
TS |
1052 |
plugin2 = DummyAuthenticator('chris_id2') |
|
1053 |
plugins = [ ('auth1', plugin1), ('auth2', plugin2) ] |
b482a1
|
1054 |
api = self._makeOne(environ=environ, authenticators=plugins, |
TS |
1055 |
request_classifier=lambda environ: 'match') |
993216
|
1056 |
identities = [ (None, {'login':'chris', 'password':'password'}) ] |
b482a1
|
1057 |
results = api._authenticate(identities) |
993216
|
1058 |
self.assertEqual(len(results), 1) |
TS |
1059 |
result = results[0] |
|
1060 |
rank, authenticator, identifier, creds, userid = result |
|
1061 |
self.assertEqual(rank, (0,0)) |
|
1062 |
self.assertEqual(authenticator, plugin2) |
|
1063 |
self.assertEqual(identifier, None) |
|
1064 |
self.assertEqual(creds['login'], 'chris') |
|
1065 |
self.assertEqual(creds['password'], 'password') |
|
1066 |
self.assertEqual(userid, 'chris_id2') |
|
1067 |
|
b482a1
|
1068 |
def test__authenticate_find_explicit_classifier(self): |
993216
|
1069 |
from repoze.who.interfaces import IAuthenticator |
b482a1
|
1070 |
environ = self._makeEnviron() |
993216
|
1071 |
plugin1 = DummyAuthenticator('chris_id1') |
TS |
1072 |
plugin1.classifications = {IAuthenticator:['nomatch']} |
|
1073 |
plugin2 = DummyAuthenticator('chris_id2') |
|
1074 |
plugin2.classifications = {IAuthenticator:['match']} |
|
1075 |
plugins = [ ('auth1', plugin1), ('auth2', plugin2) ] |
b482a1
|
1076 |
api = self._makeOne(environ=environ, authenticators=plugins, |
TS |
1077 |
request_classifier=lambda environ: 'match') |
993216
|
1078 |
identities = [ (None, {'login':'chris', 'password':'password'}) ] |
b482a1
|
1079 |
results = api._authenticate(identities) |
993216
|
1080 |
self.assertEqual(len(results), 1) |
TS |
1081 |
result = results[0] |
|
1082 |
rank, authenticator, identifier, creds, userid = result |
|
1083 |
self.assertEqual(rank, (0, 0)) |
|
1084 |
self.assertEqual(authenticator, plugin2) |
|
1085 |
self.assertEqual(identifier, None) |
|
1086 |
self.assertEqual(creds['login'], 'chris') |
|
1087 |
self.assertEqual(creds['password'], 'password') |
|
1088 |
self.assertEqual(userid, 'chris_id2') |
|
1089 |
|
b482a1
|
1090 |
def test__authenticate_user_null_but_not_none(self): |
993216
|
1091 |
environ = self._makeEnviron() |
TS |
1092 |
plugin1 = DummyAuthenticator(0) |
|
1093 |
plugins = [ ('identifier1', plugin1) ] |
b482a1
|
1094 |
api = self._makeOne(environ=environ, authenticators=plugins) |
993216
|
1095 |
identities = [ (None, {'login':'chris', 'password':'password'}) ] |
b482a1
|
1096 |
results = api._authenticate(identities) |
993216
|
1097 |
self.assertEqual(len(results), 1) |
TS |
1098 |
result = results[0] |
|
1099 |
rank, authenticator, identifier, creds, userid = result |
|
1100 |
self.assertEqual(rank, (0,0)) |
|
1101 |
self.assertEqual(authenticator, plugin1) |
|
1102 |
self.assertEqual(identifier, None) |
|
1103 |
self.assertEqual(creds['login'], 'chris') |
|
1104 |
self.assertEqual(creds['password'], 'password') |
|
1105 |
self.assertEqual(userid, 0) |
|
1106 |
|
b482a1
|
1107 |
def test__add_metadata(self): |
993216
|
1108 |
environ = self._makeEnviron() |
TS |
1109 |
plugin1 = DummyMDProvider({'foo':'bar'}) |
|
1110 |
plugin2 = DummyMDProvider({'fuz':'baz'}) |
|
1111 |
plugins = [ ('meta1', plugin1), ('meta2', plugin2) ] |
b482a1
|
1112 |
api = self._makeOne(environ=environ, mdproviders=plugins) |
993216
|
1113 |
classification = '' |
TS |
1114 |
identity = {} |
b482a1
|
1115 |
results = api._add_metadata(identity) |
993216
|
1116 |
self.assertEqual(identity['foo'], 'bar') |
TS |
1117 |
self.assertEqual(identity['fuz'], 'baz') |
|
1118 |
|
b482a1
|
1119 |
def test__add_metadata_w_classification(self): |
993216
|
1120 |
environ = self._makeEnviron() |
TS |
1121 |
plugin1 = DummyMDProvider({'foo':'bar'}) |
|
1122 |
plugin2 = DummyMDProvider({'fuz':'baz'}) |
|
1123 |
from repoze.who.interfaces import IMetadataProvider |
|
1124 |
plugin2.classifications = {IMetadataProvider:['foo']} |
|
1125 |
plugins = [ ('meta1', plugin1), ('meta2', plugin2) ] |
b482a1
|
1126 |
api = self._makeOne(environ=environ, mdproviders=plugins) |
993216
|
1127 |
classification = 'monkey' |
TS |
1128 |
identity = {} |
b482a1
|
1129 |
api._add_metadata(identity) |
993216
|
1130 |
self.assertEqual(identity['foo'], 'bar') |
TS |
1131 |
self.assertEqual(identity.get('fuz'), None) |
|
1132 |
|
|
1133 |
|
9c1e6f
|
1134 |
class TestIdentityDict(_Base): |
b482a1
|
1135 |
|
TS |
1136 |
def _getTargetClass(self): |
|
1137 |
from repoze.who.api import Identity |
|
1138 |
return Identity |
|
1139 |
|
|
1140 |
def _makeOne(self, **kw): |
|
1141 |
klass = self._getTargetClass() |
|
1142 |
return klass(**kw) |
|
1143 |
|
|
1144 |
def test_str(self): |
|
1145 |
identity = self._makeOne(foo=1) |
|
1146 |
self.failUnless(str(identity).startswith('<repoze.who identity')) |
|
1147 |
self.assertEqual(identity['foo'], 1) |
|
1148 |
|
|
1149 |
def test_repr(self): |
|
1150 |
identity = self._makeOne(foo=1) |
|
1151 |
self.failUnless(str(identity).startswith('<repoze.who identity')) |
|
1152 |
self.assertEqual(identity['foo'], 1) |
|
1153 |
|
993216
|
1154 |
|
TS |
1155 |
|
|
1156 |
class DummyIdentifier: |
|
1157 |
forgotten = False |
|
1158 |
remembered = False |
|
1159 |
|
|
1160 |
def __init__(self, credentials=None, remember_headers=None, |
|
1161 |
forget_headers=None, replace_app=None): |
|
1162 |
self.credentials = credentials |
|
1163 |
self.remember_headers = remember_headers |
|
1164 |
self.forget_headers = forget_headers |
|
1165 |
self.replace_app = replace_app |
|
1166 |
|
|
1167 |
def identify(self, environ): |
|
1168 |
if self.replace_app: |
|
1169 |
environ['repoze.who.application'] = self.replace_app |
|
1170 |
return self.credentials |
|
1171 |
|
|
1172 |
def forget(self, environ, identity): |
|
1173 |
self.forgotten = identity |
|
1174 |
return self.forget_headers |
|
1175 |
|
|
1176 |
def remember(self, environ, identity): |
|
1177 |
self.remembered = identity |
|
1178 |
return self.remember_headers |
|
1179 |
|
|
1180 |
|
|
1181 |
class DummyNoResultsIdentifier: |
|
1182 |
|
|
1183 |
def identify(self, environ): |
|
1184 |
return None |
|
1185 |
|
|
1186 |
def remember(self, *arg, **kw): |
|
1187 |
pass |
|
1188 |
|
|
1189 |
def forget(self, *arg, **kw): |
|
1190 |
pass |
|
1191 |
|
|
1192 |
|
|
1193 |
class DummyAuthenticator: |
|
1194 |
def __init__(self, userid=None): |
|
1195 |
self.userid = userid |
|
1196 |
|
|
1197 |
def authenticate(self, environ, credentials): |
|
1198 |
if self.userid is None: |
|
1199 |
return credentials['login'] |
|
1200 |
return self.userid |
|
1201 |
|
|
1202 |
|
|
1203 |
class DummyFailAuthenticator: |
|
1204 |
def authenticate(self, environ, credentials): |
|
1205 |
return None |
|
1206 |
|
|
1207 |
|
|
1208 |
class DummyChallenger: |
52bc23
|
1209 |
_challenged_with = None |
993216
|
1210 |
def __init__(self, app=None): |
TS |
1211 |
self.app = app |
|
1212 |
|
|
1213 |
def challenge(self, environ, status, app_headers, forget_headers): |
|
1214 |
environ['challenged'] = self.app |
52bc23
|
1215 |
self._challenged_with = (environ, status, app_headers, forget_headers) |
993216
|
1216 |
return self.app |
TS |
1217 |
|
|
1218 |
|
|
1219 |
class DummyMDProvider: |
|
1220 |
def __init__(self, metadata=None): |
|
1221 |
self._metadata = metadata |
|
1222 |
|
|
1223 |
def add_metadata(self, environ, identity): |
|
1224 |
return identity.update(self._metadata) |
|
1225 |
|
|
1226 |
|
|
1227 |
class DummyMultiPlugin: |
|
1228 |
pass |
|
1229 |
|
|
1230 |
|
|
1231 |
class DummyRequestClassifier: |
|
1232 |
def __call__(self, environ): |
|
1233 |
return 'browser' |
|
1234 |
|
|
1235 |
|
|
1236 |
class DummyChallengeDecider: |
|
1237 |
def __call__(self, environ, status, headers): |
|
1238 |
if status.startswith('401 '): |
|
1239 |
return True |
|
1240 |
|
|
1241 |
|
52bc23
|
1242 |
class DummyLogger: |
TS |
1243 |
_info = _debug = () |
|
1244 |
def info(self, msg): |
|
1245 |
self._info += (msg,) |
|
1246 |
def debug(self, msg): |
|
1247 |
self._debug += (msg,) |
|
1248 |
|
993216
|
1249 |
class DummyApp: |
TS |
1250 |
environ = None |
|
1251 |
def __call__(self, environ, start_response): |
|
1252 |
self.environ = environ |
|
1253 |
return [] |