Package: zope.app.security
This package provides ZMI browser views for Zope security components.It used to provide a large part of security functionality for Zope 3, but it was
factored out from this package to several little packages to reduce dependencies
and improve reusability.The functionality was splitted into these new packages:zope.authentication - the IAuthentication interface and related utilities.zope.principalregistry - the global principal registry and its zcml directives.zope.app.localpermission - the LocalPermission class that implements
persistent permissions.The rest of functionality that were provided by this package is merged intozope.securityandzope.publisher.Backward-compatibility imports are provided to ensure that older applications
work. See CHANGES.txt for more info.Detailed DocumentationThe Query View for Authentication UtilitiesA regular authentication service will not provide theISourceQueriablesinterface, but it is a queriable itself, since it provides the simplegetPrincipals(name)method:>>> class Principal:
...     def __init__(self, id):
...         self.id = id>>> class MyAuthUtility:
...     data = {'jim': Principal(42), 'don': Principal(0),
...             'stephan': Principal(1)}
...
...     def getPrincipals(self, name):
...         return [principal
...                 for id, principal in self.data.items()
...                 if name in id]Now that we have our queriable, we create the view for it:>>> from zope.app.security.browser.auth import AuthUtilitySearchView
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> view = AuthUtilitySearchView(MyAuthUtility(), request)This allows us to render a search form.>>> print(view.render('test')) # doctest: +NORMALIZE_WHITESPACE
<h4>principals.zcml</h4>
<div class="row">
<div class="label">
Search String
</div>
<div class="field">
<input type="text" name="test.searchstring" />
</div>
</div>
<div class="row">
<div class="field">
<input type="submit" name="test.search" value="Search" />
</div>
</div>If we ask for results:>>> view.results('test')We don’t get any, since we did not provide any. But if we give input:>>> request.form['test.searchstring'] = 'n'we still don’t get any:>>> view.results('test')because we did not press the button. So let’s press the button:>>> request.form['test.search'] = 'Search'so that we now get results (!):>>> ids = list(view.results('test'))
>>> ids.sort()
>>> ids
[0, 1]Login/Logout SnippetThe class LoginLogout:>>> from zope.app.security.browser.auth import LoginLogoutis 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.authentication.interfaces import IUnauthenticatedPrincipal
>>> from zope.principalregistry.principalregistry import UnauthenticatedPrincipal
>>> anonymous = UnauthenticatedPrincipal('anon', '', '')
>>> IUnauthenticatedPrincipal.providedBy(anonymous)
TrueWhen 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)
>>> print(LoginLogout(None, request)())
<a href="@@login.html?nextURL=http%3A//127.0.0.1">[Login]</a>Attempting to login at this point will fail because nothing has
authorized the principal yet:>>> from zope.app.security.browser.auth import HTTPAuthenticationLogin
>>> login = HTTPAuthenticationLogin()
>>> login.request = request
>>> login.context = None
>>> login.failed = lambda: 'Login Failed'
>>> login.login()
'Login Failed'There is a failsafe that will attempt to ask for HTTP Basic authentication:>>> from zope.app.security.browser.auth import HTTPBasicAuthenticationLogin
>>> basic_login = HTTPBasicAuthenticationLogin()
>>> basic_login.request = request
>>> basic_login.failed = lambda: 'Basic Login Failed'
>>> basic_login.login()
'Basic Login Failed'
>>> request._response.getHeader('WWW-Authenticate', literal=True)
'basic realm="Zope"'
>>> request._response.getStatus()
401Of course, an unauthorized principal is confirmed to be logged out:>>> from zope.app.security.browser.auth import HTTPAuthenticationLogout
>>> logout = HTTPAuthenticationLogout(None, request)
>>> logout.logout(nextURL="bye.html")
'bye.html'
>>> logout.confirmation = lambda: 'Good Bye'
>>> logout.logout()
'Good Bye'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 implementer
>>> @implementer(IPrincipal)
... class Bob:
...     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)())
NoneAnd at this time, login will correctly direct us to the next URL, or
to the confirmation page:>>> login = HTTPAuthenticationLogin()
>>> login.request = request
>>> login.context = None
>>> login.login(nextURL='good.html')
>>> login.confirmation = lambda: "You Passed"
>>> login.login()
'You Passed'Likewise for HTTP Basic authentication:>>> login = HTTPBasicAuthenticationLogin()
>>> login.request = request
>>> login.context = None
>>> login.confirmation = lambda: "You Passed"
>>> login.login()
'You Passed'To show a logout prompt, an admin must register a marker adapter that provides
the interface:>>> from zope.authentication.interfaces import ILogoutSupportedThis flags to LoginLogout that the site supports logout. There is a ‘no-op’
adapter that can be registered for this:>>> from zope.authentication.logout import LogoutSupported
>>> from zope.component import provideAdapter
>>> provideAdapter(LogoutSupported, (None,), ILogoutSupported)Now when we use LoginLogout with an unauthenticated principal, we get a logout
prompt:>>> print(LoginLogout(None, request)())
<a href="@@logout.html?nextURL=http%3A//127.0.0.1">[Logout]</a>And we can log this principal out, passing a URL to redirect to:>>> logout = HTTPAuthenticationLogout(None, request)
>>> logout.redirect = lambda: 'You have been redirected.'
>>> logout.logout(nextURL="loggedout.html")
'You have been redirected.'CHANGES6.0 (2023-02-17)Add support for Python 3.10, 3.11.Drop support for Python 2.7, 3.5, 3.6.5.1.0 (2020-10-28)Add support for Python 3.8 and 3.9.Drop support for Python 3.5.Drop security declarations for the deprecatedbinhexstandard library
module from globalmodules.zcml.Note that globalmodules.zcml should be avoided.  It’s better to make
declarations for only what you actually need to use.5.0.0 (2019-07-12)Add support for Python 3.7.Drop support for Python 3.4.Drop security declarations for the deprecatedformatterstandard library
module from globalmodules.zcml.Note that globalmodules.zcml should be avoided.  It’s better to make
declarations for only what you actually need to use.4.0.0 (2017-04-27)Removed use of ‘zope.testing.doctestunit’ in favor of stdlib’s doctest.Removed use ofzope.app.testingin favor ofzope.app.wsgi.Add support for PyPy, Python 3.4, 3.5 and 3.6.3.7.5 (2010-01-08)Move ‘zope.ManageApplication’ permission to zope.app.applicationcontrolFix tests using a newer zope.publisher that requires zope.login.3.7.3 (2009-11-29)provide a clean zope setup and move zope.app.testing to a test dependencyremoved unused dependencies like ZODB3 etc. from install_requires3.7.2 (2009-09-10)Added data attribute to ‘_protections.zcml’ for PersistentList
and PersistentDict to accomodate UserList and UserDict behavior
when they are proxied.3.7.1 (2009-08-15)Changed globalmodules.zcml to avoid making declarations for
deprecated standard modules, to avoid deprecation warnings.Note that globalmodules.zcml should be avoided.  It’s better to make
declarations for only what you actually need to use.3.7.0 (2009-03-14)All interfaces, as well as some authentication-related helper classes and
functions (checkPrincipal, PrincipalSource, PrincipalTerms, etc.) were moved
into the newzope.authenticationpackage. Backward-compatibility imports
are provided.The “global principal registry” along with its zcml directives was moved into
new “zope.principalregistry” package. Backward-compatibility imports are
provided.The IPrincipal -> zope.publisher.interfaces.logginginfo.ILoggingInfo
adapter was moved tozope.publisher. Backward-compatibility import
is provided.The PermissionsVocabulary and PermissionIdsVocabulary has been moved
to thezope.securitypackage. Backward-compatibility imports are
provided.The registration of the “zope.Public” permission as well as some other
common permissions, like “zope.View” have been moved tozope.security.
Its configure.zcml is now included by this package.The “protect” function is now a no-op and is not needed anymore, because
zope.security now knows about i18n messages and __name__ and __parent__
attributes and won’t protect them by default.The addCheckerPublic was moved from zope.app.security.tests to
zope.security.testing. Backward-compatibility import is provided.TheLocalPermissionclass is now moved to newzope.app.localpermissionpackage. This package now only has backward-compatibility imports and
zcml includes.Cleanup dependencies after refactorings. Also, don’t depend on
zope.app.testing for tests anymore.Update package’s description to point about refactorings done.3.6.2 (2009-03-10)TheAllow,DenyandUnsetpermission settings was preferred to
be imported fromzope.securitypolicy.interfacesfor a long time
and now they are completely moved there fromzope.app.security.settingsas well as thePermissionSettingclass. The only thing left for
backward compatibility is the import of Allow/Unset/Deny constants ifzope.securitypolicyis installed to allow unpickling of security
settings.3.6.1 (2009-03-09)Depend on newzope.passwordpackage instead ofzope.app.authenticationto get password managers for the authentication utility, thus remove
dependency onzope.app.authentication.Use template for AuthUtilitySearchView instead of ugly HTML
constructing in the python code.Bug: Theshaandmd5modules has been deprecated in Python 2.6.
Whenever the ZCML of this package was included when using Python 2.6,
a deprecation warning had been raised stating thatmd5andshahave
been deprecated. Provided a simple condition to check whether Python 2.6
or later is installed by checking for the presense ofjsonmodule
thas was added only in Python 2.6 and thus optionally load the security
declaration formd5andsha.Remove deprecated code, thus removing explicit dependency on
zope.deprecation and zope.deferredimport.Cleanup code a bit, replace old __used_for__ statements byadaptscalls.3.6.0 (2009-01-31)Changed mailing list address to zope-dev at zope.org, because
zope3-dev is retired now. Changed “cheeseshop” to “pypi” in
the package homepage.Moved theprotectclassmodule tozope.securityleaving only a
compatibility module here that imports from the new location.Moved the <module> directive implementation tozope.security.Usezope.containerinstead ofzope.app.container;.3.5.3 (2008-12-11)use zope.browser.interfaces.ITerms instead ofzope.app.form.browser.interfaces.3.5.2 (2008-07-31)Bug: It turned out that checking for regex was not much better of an
idea, since it causes deprecation warnings in Python 2.4. Thus let’s
look for a library that was added in Python 2.5.3.5.1 (2008-06-24)Bug: Thegopherlibmodule has been deprecated in Python 2.5. Whenever the
ZCML of this package was included when using Python 2.5, a deprecation
warning had been raised stating thatgopherlibhas been
deprecated. Provided a simple condition to check whether Python 2.5 or later
is installed by checking for the deletedregexmodule and thus optionally
load the security declaration forgopherlib.3.5.0 (2008-02-05)Feature:zope.app.security.principalregistry.PrincipalRegistry.getPrincipalreturnszope.security.management.system_userwhen its id is used for the search
key.3.4.0 (2007-10-27)Initial release independent of the main Zope tree.