Chris McDonough
2010-11-05 e24a75c9e1561950426a68b7d2fb3fe62be632c5
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 []