Tres Seaver
2011-04-06 fdd86db07eb7b993aa50db71bec7342d72931bda
All identifiers play on remember / forget.

Unless the application limits by passing an identifier_name.
2 files modified
137 ■■■■■ changed files
repoze/who/api.py 52 ●●●●● patch | view | raw | blame | history
repoze/who/tests/test_api.py 85 ●●●●● patch | view | raw | blame | history
repoze/who/api.py
@@ -235,31 +235,49 @@
    def login(self, credentials, identifier_name=None):
        """ See IAPI.
        """
        authenticated = identity = plugin = None
        headers = []
        # Filter identifiers using 'identifier_name', if provided.
        if identifier_name is not None:
            identifier = self.name_registry[identifier_name]
            identifiers = [(name, plugin) for name, plugin in self.identifiers
                                           if name == identifier_name]
        else:
            identifier = self.identifiers[0][1]
        # Pretend that the given identifier extracted the identity.
        authenticated = self._authenticate([(identifier, credentials)])
        if authenticated:
            # and therefore can remember it
            rank, plugin, identifier, identity, userid = authenticated[0]
            headers = identifier.remember(self.environ, identity)
            return identity, headers
        else:
            # or forget it
            headers = identifier.forget(self.environ, None)
            return None, headers
            identifiers = self.identifiers
        # First pass:  for each identifier, pretend that it was the source
        # of the credentials, and try to authenticate.
        for name, identifier in identifiers:
            authenticated = self._authenticate([(identifier, credentials)])
            if authenticated: # and therefore can remember it
                rank, plugin, identifier, identity, userid = authenticated[0]
                break
        # Second pass to allow identifiers which passed on auth to participate
        # in remember / forget.
        for name, identifier in identifiers:
            if identity is not None:
                headers.extend(identifier.remember(self.environ, identity))
            else:
                headers.extend(identifier.forget(self.environ, None))
        return identity, headers
    def logout(self, identifier_name=None):
        """ See IAPI.
        """
        authenticated = None
        headers = []
        # Filter identifiers using 'identifier_name', if provided.
        if identifier_name is not None:
            identifier = self.name_registry[identifier_name]
            identifiers = [(name, plugin) for name, plugin in self.identifiers
                                           if name == identifier_name]
        else:
            identifier = self.identifiers[0][1]
        # Pretend that the given identifier extracted the identity.
        headers = identifier.forget(self.environ, None)
            identifiers = self.identifiers
        for name, identifier in identifiers:
            headers.extend(identifier.forget(self.environ, None))
        # we need to remove the identity for hybrid middleware/api usages to
        # work correctly: middleware calls ``remember`` unconditionally "on
repoze/who/tests/test_api.py
@@ -492,6 +492,19 @@
        self.assertEqual(environ['challenged'], app2)
        self.assertEqual(identifier.forgotten, identity)
    def test_remember_identifier_plugin_returns_none(self):
        class _Identifier:
            def identify(self, environ):
                return None
            def remember(self, environ, identity):
                return ()
            def forget(self, environ, identity):
                return ()
        identity = {'identifier': _Identifier()}
        api = self._makeOne()
        headers = api.remember(identity=identity)
        self.assertEqual(tuple(headers), ())
    def test_remember_no_identity_passed_or_in_environ(self):
        logger = DummyLogger()
        environ = self._makeEnviron()
@@ -543,6 +556,19 @@
                                        'remembering via headers from'))
        self.failUnless(logger._info[1].endswith(repr(HEADERS)))
        self.assertEqual(len(logger._debug), 0)
    def test_forget_identifier_plugin_returns_none(self):
        class _Identifier:
            def identify(self, environ):
                return None
            def remember(self, environ, identity):
                return ()
            def forget(self, environ, identity):
                return ()
        identity = {'identifier': _Identifier()}
        api = self._makeOne()
        headers = api.forget(identity=identity)
        self.assertEqual(tuple(headers), ())
    def test_forget_no_identity_passed_or_in_environ(self):
        logger = DummyLogger()
@@ -604,14 +630,14 @@
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                return REMEMBER_HEADERS
                return REMEMBER_HEADERS[1:]
            def forget(self, environ, identity):
                return FORGET_HEADERS
        class _BogusIdentifier:
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return REMEMBER_HEADERS[:1]
            def forget(self, environ, identity):
                pass
        authenticator = DummyAuthenticator('chrisid')
@@ -624,22 +650,7 @@
                            environ=environ)
        identity, headers = api.login({'login': 'chrisid'}, 'valid')
        self.assertEqual(identity['repoze.who.userid'], 'chrisid')
        self.assertEqual(headers, REMEMBER_HEADERS)
    def test_identifier_plugin_returns_none(self):
        class _Identifier:
            def identify(self, environ):
                return None
            def remember(self, environ, identity):
                return None
            def forget(self, environ, identity):
                return None
        identity = {'identifier': _Identifier()}
        api = self._makeOne()
        headers = api.remember(identity=identity)
        self.assertEqual(tuple(headers), ())
        headers = api.forget(identity=identity)
        self.assertEqual(tuple(headers), ())
        self.assertEqual(headers, REMEMBER_HEADERS[1:])
    def test_login_wo_identifier_name_hit(self):
        REMEMBER_HEADERS = [('Foo', 'Bar'), ('Baz', 'Qux')]
@@ -648,26 +659,26 @@
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                return REMEMBER_HEADERS
                return REMEMBER_HEADERS[1:]
            def forget(self, environ, identity):
                return FORGET_HEADERS
        class _BogusIdentifier:
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return REMEMBER_HEADERS[:1]
            def forget(self, environ, identity):
                pass
        authenticator = DummyAuthenticator('chrisid')
        environ = self._makeEnviron()
        identifiers = [('valid', _Identifier()),
                       ('bogus', _BogusIdentifier()),
        identifiers = [('bogus', _BogusIdentifier()),
                       ('valid', _Identifier()),
                      ]
        api = self._makeOne(identifiers=identifiers,
                            authenticators=[('authentic', authenticator)],
                            environ=environ)
        identity, headers = api.login({'login': 'chrisid'})
        self.failUnless(identity)
        self.assertEqual(identity['repoze.who.userid'], 'chrisid')
        self.assertEqual(headers, REMEMBER_HEADERS)
    def test_login_w_identifier_name_miss(self):
@@ -684,9 +695,9 @@
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return ()
            def forget(self, environ, identity):
                pass
                return ()
        authenticator = DummyFailAuthenticator()
        environ = self._makeEnviron()
        identifiers = [('bogus', _BogusIdentifier()),
@@ -699,22 +710,22 @@
        self.assertEqual(identity, None)
        self.assertEqual(headers, FORGET_HEADERS)
    def test_login_wo_identifier_name_miss(self):
    def test_logout_wo_identifier_name_miss(self):
        FORGET_HEADERS = [('Spam', 'Blah')]
        class _Identifier:
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return ()
            def forget(self, environ, identity):
                return FORGET_HEADERS
                return FORGET_HEADERS[:1]
        class _BogusIdentifier:
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return ()
            def forget(self, environ, identity):
                pass
                return FORGET_HEADERS[1:]
        environ = self._makeEnviron()
        identifiers = [('valid', _Identifier()),
                       ('bogus', _BogusIdentifier()),
@@ -730,16 +741,16 @@
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return ()
            def forget(self, environ, identity):
                return FORGET_HEADERS
        class _BogusIdentifier:
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return ()
            def forget(self, environ, identity):
                pass
                return ()
        environ = self._makeEnviron()
        identifiers = [('bogus', _BogusIdentifier()),
                       ('valid', _Identifier()),
@@ -763,9 +774,9 @@
            def identify(self, environ):
                pass
            def remember(self, environ, identity):
                pass
                return ()
            def forget(self, environ, identity):
                pass
                return ()
        authenticator = DummyFailAuthenticator()
        environ = self._makeEnviron()
        identifiers = [('valid', _Identifier()),
@@ -782,9 +793,9 @@
            def identify(self, environ):
                pass
            def forget(self, environ, identity):
                pass
                return ()
            def remember(self, environ, identity):
                pass
                return ()
        authenticator = DummyFailAuthenticator()
        environ = self._makeEnviron()
        environ['repoze.who.identity'] = 'identity'