The class LoginLogout:
>>> from zope.app.security.browser.auth import LoginLogout
is used as a view to generate an HTML snippet suitable for logging in or logging out based on whether or not the current principal is authenticated.
When the current principal is unauthenticated, it provides IUnauthenticatedPrincipal:
>>> from zope.app.security.interfaces import IUnauthenticatedPrincipal >>> from zope.app.security.principalregistry import UnauthenticatedPrincipal >>> anonymous = UnauthenticatedPrincipal('anon', '', '') >>> IUnauthenticatedPrincipal.providedBy(anonymous) True
When LoginLogout is used for a request that has an unauthenticated principal, it provides the user with a link to 'Login':
>>> from zope.publisher.browser import TestRequest >>> request = TestRequest() >>> request.setPrincipal(anonymous) >>> LoginLogout(None, request)() u'<a href="@@login.html?nextURL=http%3A//127.0.0.1">[Login]</a>'
Logout, however, behaves differently. Not all authentication protocols (i.e. credentials extractors/challengers) support 'logout'. Furthermore, we don't know how an admin may have configured Zope's authentication. Our solution is to rely on the admin to tell us explicitly that the site supports logout.
By default, the LoginLogout snippet will not provide a logout link for an unauthenticated principal. To illustrate, we'll first setup a request with an unauthenticated principal:
>>> from zope.security.interfaces import IPrincipal >>> from zope.interface import implements >>> class Bob: ... implements(IPrincipal) ... id = 'bob' ... title = description = '' >>> bob = Bob() >>> IUnauthenticatedPrincipal.providedBy(bob) False >>> request.setPrincipal(bob)
In this case, the default behavior is to return None for the snippet:
>>> print LoginLogout(None, request)() None
To show a logout prompt, an admin must register a marker adapter that provides the interface:
>>> from zope.app.security.interfaces import ILogoutSupported
This flags to LoginLogout that the site supports logout. There is a 'no-op' adapter that can be registered for this:
>>> from zope.app.security import LogoutSupported >>> from zope.app.testing import ztapi >>> ztapi.provideAdapter(None, ILogoutSupported, LogoutSupported)
Now when we use LoginLogout with an unauthenticated principal, we get a logout prompt:
>>> LoginLogout(None, request)() u'<a href="@@logout.html?nextURL=http%3A//127.0.0.1">[Logout]</a>'