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