summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.rst4
-rw-r--r--docs/narr/security.rst16
-rw-r--r--docs/quick_tutorial/authentication.rst30
-rw-r--r--docs/quick_tutorial/authentication/tutorial/__init__.py18
-rw-r--r--docs/quick_tutorial/authentication/tutorial/security.py24
-rw-r--r--docs/quick_tutorial/authorization.rst15
-rw-r--r--docs/quick_tutorial/authorization/tutorial/__init__.py18
-rw-r--r--docs/quick_tutorial/authorization/tutorial/security.py38
-rw-r--r--src/pyramid/authentication.py163
-rw-r--r--src/pyramid/config/testing.py4
-rw-r--r--src/pyramid/interfaces.py10
-rw-r--r--src/pyramid/security.py4
-rw-r--r--src/pyramid/testing.py2
-rw-r--r--tests/pkgs/securityapp/__init__.py2
-rw-r--r--tests/test_security.py4
-rw-r--r--tests/test_testing.py4
16 files changed, 271 insertions, 85 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 383906e00..9f16b06ea 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -156,6 +156,10 @@ Backward Incompatibilities
``require_csrf`` view option to enable automatic CSRF checking.
See https://github.com/Pylons/pyramid/pull/3521
+- Changed the default ``hashalg`` on
+ ``pyramid.authentication.AuthTktCookieHelper`` to ``sha512``.
+ See https://github.com/Pylons/pyramid/pull/3557
+
Documentation Changes
---------------------
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index ac64cba0a..72c2721f6 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -69,7 +69,7 @@ A simple security policy might look like the following:
from pyramid.security import Allowed, Denied
class SessionSecurityPolicy:
- def identify(self, request):
+ def authenticated_identity(self, request):
""" Return app-specific user object. """
userid = request.session.get('userid')
if userid is None:
@@ -78,14 +78,14 @@ A simple security policy might look like the following:
def authenticated_userid(self, request):
""" Return a string ID for the user. """
- identity = self.identify(request)
+ identity = self.authenticated_identity(request)
if identity is None:
return None
return string(identity.id)
def permits(self, request, context, permission):
""" Allow access to everything if signed in. """
- identity = self.identify(request)
+ identity = self.authenticated_identity(request)
if identity is not None:
return Allowed('User is signed in.')
else:
@@ -144,7 +144,7 @@ For example, our above security policy can leverage these helpers like so:
def __init__(self):
self.helper = SessionAuthenticationHelper()
- def identify(self, request):
+ def authenticated_identity(self, request):
""" Return app-specific user object. """
userid = self.helper.authenticated_userid(request)
if userid is None:
@@ -153,14 +153,14 @@ For example, our above security policy can leverage these helpers like so:
def authenticated_userid(self, request):
""" Return a string ID for the user. """
- identity = self.identify(request)
+ identity = self.authenticated_identity(request)
if identity is None:
return None
return str(identity.id)
def permits(self, request, context, permission):
""" Allow access to everything if signed in. """
- identity = self.identify(request)
+ identity = self.authenticated_identity(request)
if identity is not None:
return Allowed('User is signed in.')
else:
@@ -249,7 +249,7 @@ might look like so:
class SecurityPolicy:
def permits(self, request, context, permission):
- identity = self.identify(request)
+ identity = self.authenticated_identity(request)
if identity is None:
return Denied('User is not signed in.')
@@ -698,7 +698,7 @@ A "secret" is required by various components of Pyramid. For example, the
helper below might be used for a security policy and uses a secret value
``seekrit``::
- helper = AuthTktCookieHelper('seekrit', hashalg='sha512')
+ helper = AuthTktCookieHelper('seekrit')
A :term:`session factory` also requires a secret::
diff --git a/docs/quick_tutorial/authentication.rst b/docs/quick_tutorial/authentication.rst
index cd038ea36..12eb738e2 100644
--- a/docs/quick_tutorial/authentication.rst
+++ b/docs/quick_tutorial/authentication.rst
@@ -55,16 +55,15 @@ Steps
:language: ini
:linenos:
-#. Get authentication (and for now, authorization policies) and login route
- into the :term:`configurator` in ``authentication/tutorial/__init__.py``:
+#. Create an ``authentication/tutorial/security.py`` module that can find our
+ user information by providing a :term:`security policy`:
- .. literalinclude:: authentication/tutorial/__init__.py
+ .. literalinclude:: authentication/tutorial/security.py
:linenos:
-#. Create an ``authentication/tutorial/security.py`` module that can find our
- user information by providing an *authentication policy callback*:
+#. Register the ``SecurityPolicy`` with the :term:`configurator` in ``authentication/tutorial/__init__.py``:
- .. literalinclude:: authentication/tutorial/security.py
+ .. literalinclude:: authentication/tutorial/__init__.py
:linenos:
#. Update the views in ``authentication/tutorial/views.py``:
@@ -111,14 +110,12 @@ are you) and authorization (what are you allowed to do) are not just pluggable,
but decoupled. To learn one step at a time, we provide a system that identifies
users and lets them log out.
-In this example we chose to use the bundled :ref:`AuthTktAuthenticationPolicy
-<authentication_module>` policy. We enabled it in our configuration and
-provided a ticket-signing secret in our INI file.
+In this example we chose to use the bundled :class:`pyramid.authentication.AuthTktCookieHelper` helper to store the user's logged-in state in a cookie.
+We enabled it in our configuration and provided a ticket-signing secret in our INI file.
Our view class grew a login view. When you reached it via a ``GET`` request, it
returned a login form. When reached via ``POST``, it processed the submitted
-username and password against the "groupfinder" callable that we registered in
-the configuration.
+username and password against the ``USERS`` data store.
The function ``hash_password`` uses a one-way hashing algorithm with a salt on
the user's password via ``bcrypt``, instead of storing the password in plain
@@ -134,6 +131,9 @@ submitted password and the user's password stored in the database. If the
hashed values are equivalent, then the user is authenticated, else
authentication fails.
+Assuming the password was validated, we invoke :func:`pyramid.security.remember` to generate a cookie that is set in the response.
+Subsequent requests return that cookie and identify the user.
+
In our template, we fetched the ``logged_in`` value from the view class. We use
this to calculate the logged-in user, if any. In the template we can then
choose to show a login link to anonymous visitors or a logout link to logged-in
@@ -143,13 +143,9 @@ users.
Extra credit
============
-#. What is the difference between a user and a principal?
-
-#. Can I use a database behind my ``groupfinder`` to look up principals?
+#. Can I use a database instead of ``USERS`` to authenticate users?
#. Once I am logged in, does any user-centric information get jammed onto each
request? Use ``import pdb; pdb.set_trace()`` to answer this.
-.. seealso:: See also :ref:`security_chapter`,
- :ref:`AuthTktAuthenticationPolicy <authentication_module>`, `bcrypt
- <https://pypi.org/project/bcrypt/>`_
+.. seealso:: See also :ref:`security_chapter`, :class:`pyramid.authentication.AuthTktCookieHelper`, `bcrypt <https://pypi.org/project/bcrypt/>`_
diff --git a/docs/quick_tutorial/authentication/tutorial/__init__.py b/docs/quick_tutorial/authentication/tutorial/__init__.py
index efc09e760..ec8a66a23 100644
--- a/docs/quick_tutorial/authentication/tutorial/__init__.py
+++ b/docs/quick_tutorial/authentication/tutorial/__init__.py
@@ -1,25 +1,21 @@
-from pyramid.authentication import AuthTktAuthenticationPolicy
-from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.config import Configurator
-from .security import groupfinder
+from .security import SecurityPolicy
def main(global_config, **settings):
config = Configurator(settings=settings)
config.include('pyramid_chameleon')
- # Security policies
- authn_policy = AuthTktAuthenticationPolicy(
- settings['tutorial.secret'], callback=groupfinder,
- hashalg='sha512')
- authz_policy = ACLAuthorizationPolicy()
- config.set_authentication_policy(authn_policy)
- config.set_authorization_policy(authz_policy)
+ config.set_security_policy(
+ SecurityPolicy(
+ secret=settings['tutorial.secret'],
+ ),
+ )
config.add_route('home', '/')
config.add_route('hello', '/howdy')
config.add_route('login', '/login')
config.add_route('logout', '/logout')
config.scan('.views')
- return config.make_wsgi_app() \ No newline at end of file
+ return config.make_wsgi_app()
diff --git a/docs/quick_tutorial/authentication/tutorial/security.py b/docs/quick_tutorial/authentication/tutorial/security.py
index e585e2642..8324000ed 100644
--- a/docs/quick_tutorial/authentication/tutorial/security.py
+++ b/docs/quick_tutorial/authentication/tutorial/security.py
@@ -1,4 +1,5 @@
import bcrypt
+from pyramid.authentication import AuthTktCookieHelper
def hash_password(pw):
@@ -12,9 +13,24 @@ def check_password(pw, hashed_pw):
USERS = {'editor': hash_password('editor'),
'viewer': hash_password('viewer')}
-GROUPS = {'editor': ['group:editors']}
-def groupfinder(userid, request):
- if userid in USERS:
- return GROUPS.get(userid, []) \ No newline at end of file
+class SecurityPolicy:
+ def __init__(self, secret):
+ self.authtkt = AuthTktCookieHelper(secret=secret)
+
+ def authenticated_identity(self, request):
+ identity = self.authtkt.identify(request)
+ if identity is not None and identity['userid'] in USERS:
+ return identity
+
+ def authenticated_userid(self, request):
+ identity = self.authenticated_identity(request)
+ if identity is not None:
+ return identity['userid']
+
+ def remember(self, request, userid, **kw):
+ return self.authtkt.remember(request, userid, **kw)
+
+ def forget(self, request, **kw):
+ return self.authtkt.forget(request, **kw)
diff --git a/docs/quick_tutorial/authorization.rst b/docs/quick_tutorial/authorization.rst
index e80f88c51..b1ef86a17 100644
--- a/docs/quick_tutorial/authorization.rst
+++ b/docs/quick_tutorial/authorization.rst
@@ -55,6 +55,11 @@ Steps
.. literalinclude:: authorization/tutorial/resources.py
:linenos:
+#. Define a ``GROUPS`` data store and the ``permits`` method of our ``SecurityPolicy``:
+
+ .. literalinclude:: authorization/tutorial/security.py
+ :linenos:
+
#. Change ``authorization/tutorial/views.py`` to require the ``edit``
permission on the ``hello`` view and implement the forbidden view:
@@ -87,8 +92,10 @@ This simple tutorial step can be boiled down to the following:
- This ACL says that the ``edit`` permission is available on ``Root`` to the
``group:editors`` *principal*.
-- The registered ``groupfinder`` answers whether a particular user (``editor``)
- has a particular group (``group:editors``).
+- The ``SecurityPolicy.effective_principals`` method answers whether a particular user (``editor``) is a member of a particular group (``group:editors``).
+
+- The ``SecurityPolicy.permits`` method is invoked when Pyramid wants to know whether the user is allowed to do something.
+ To do this, it uses the :class:`pyramid.authorization.ACLHelper` to inspect the ACL on the ``context`` and determine if the request is allowed or denied the specific permission.
In summary, ``hello`` wants ``edit`` permission, ``Root`` says
``group:editors`` has ``edit`` permission.
@@ -105,6 +112,10 @@ Pyramid that the ``login`` view should be used by decorating the view with
Extra credit
============
+#. What is the difference between a user and a principal?
+
+#. Can I use a database instead of the ``GROUPS`` data store to look up principals?
+
#. Do I have to put a ``renderer`` in my ``@forbidden_view_config`` decorator?
#. Perhaps you would like the experience of not having enough permissions
diff --git a/docs/quick_tutorial/authorization/tutorial/__init__.py b/docs/quick_tutorial/authorization/tutorial/__init__.py
index 8f7ab8277..255bb35ac 100644
--- a/docs/quick_tutorial/authorization/tutorial/__init__.py
+++ b/docs/quick_tutorial/authorization/tutorial/__init__.py
@@ -1,8 +1,6 @@
-from pyramid.authentication import AuthTktAuthenticationPolicy
-from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.config import Configurator
-from .security import groupfinder
+from .security import SecurityPolicy
def main(global_config, **settings):
@@ -10,17 +8,15 @@ def main(global_config, **settings):
root_factory='.resources.Root')
config.include('pyramid_chameleon')
- # Security policies
- authn_policy = AuthTktAuthenticationPolicy(
- settings['tutorial.secret'], callback=groupfinder,
- hashalg='sha512')
- authz_policy = ACLAuthorizationPolicy()
- config.set_authentication_policy(authn_policy)
- config.set_authorization_policy(authz_policy)
+ config.set_security_policy(
+ SecurityPolicy(
+ secret=settings['tutorial.secret'],
+ ),
+ )
config.add_route('home', '/')
config.add_route('hello', '/howdy')
config.add_route('login', '/login')
config.add_route('logout', '/logout')
config.scan('.views')
- return config.make_wsgi_app() \ No newline at end of file
+ return config.make_wsgi_app()
diff --git a/docs/quick_tutorial/authorization/tutorial/security.py b/docs/quick_tutorial/authorization/tutorial/security.py
index e585e2642..5b3e04a5f 100644
--- a/docs/quick_tutorial/authorization/tutorial/security.py
+++ b/docs/quick_tutorial/authorization/tutorial/security.py
@@ -1,4 +1,7 @@
import bcrypt
+from pyramid.authentication import AuthTktCookieHelper
+from pyramid.authorization import ACLHelper
+from pyramid.security import Authenticated, Everyone
def hash_password(pw):
@@ -15,6 +18,35 @@ USERS = {'editor': hash_password('editor'),
GROUPS = {'editor': ['group:editors']}
-def groupfinder(userid, request):
- if userid in USERS:
- return GROUPS.get(userid, []) \ No newline at end of file
+class SecurityPolicy:
+ def __init__(self, secret):
+ self.authtkt = AuthTktCookieHelper(secret=secret)
+ self.acl = ACLHelper()
+
+ def authenticated_identity(self, request):
+ identity = self.authtkt.identify(request)
+ if identity is not None and identity['userid'] in USERS:
+ return identity
+
+ def authenticated_userid(self, request):
+ identity = self.authenticated_identity(request)
+ if identity is not None:
+ return identity['userid']
+
+ def remember(self, request, userid, **kw):
+ return self.authtkt.remember(request, userid, **kw)
+
+ def forget(self, request, **kw):
+ return self.authtkt.forget(request, **kw)
+
+ def permits(self, request, context, permission):
+ principals = self.effective_principals(request)
+ return self.acl.permits(context, principals, permission)
+
+ def effective_principals(self, request):
+ principals = [Everyone]
+ userid = self.authenticated_userid(request)
+ if userid is not None:
+ principals += [Authenticated, 'u:' + userid]
+ principals += GROUPS.get(userid, [])
+ return principals
diff --git a/src/pyramid/authentication.py b/src/pyramid/authentication.py
index 0ccc646c3..2d194e309 100644
--- a/src/pyramid/authentication.py
+++ b/src/pyramid/authentication.py
@@ -428,9 +428,148 @@ class RemoteUserAuthenticationPolicy(CallbackAuthenticationPolicy):
@implementer(IAuthenticationPolicy)
class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy):
"""A :app:`Pyramid` :term:`authentication policy` which
- obtains data from a Pyramid "auth ticket" cookie. See
- :class:`.AuthTktCookieHelper` for documentation of the constructor
- arguments.
+ obtains data from a Pyramid "auth ticket" cookie.
+
+ Constructor Arguments
+
+ ``secret``
+
+ The secret (a string) used for auth_tkt cookie signing. This value
+ should be unique across all values provided to Pyramid for various
+ subsystem secrets (see :ref:`admonishment_against_secret_sharing`).
+ Required.
+
+ ``callback``
+
+ Default: ``None``. A callback passed the userid and the
+ request, expected to return ``None`` if the userid doesn't
+ exist or a sequence of principal identifiers (possibly empty) if
+ the user does exist. If ``callback`` is ``None``, the userid
+ will be assumed to exist with no principals. Optional.
+
+ ``cookie_name``
+
+ Default: ``auth_tkt``. The cookie name used
+ (string). Optional.
+
+ ``secure``
+
+ Default: ``False``. Only send the cookie back over a secure
+ conn. Optional.
+
+ ``include_ip``
+
+ Default: ``False``. Make the requesting IP address part of
+ the authentication data in the cookie. Optional.
+
+ For IPv6 this option is not recommended. The ``mod_auth_tkt``
+ specification does not specify how to handle IPv6 addresses, so using
+ this option in combination with IPv6 addresses may cause an
+ incompatible cookie. It ties the authentication ticket to that
+ individual's IPv6 address.
+
+ ``timeout``
+
+ Default: ``None``. Maximum number of seconds which a newly
+ issued ticket will be considered valid. After this amount of
+ time, the ticket will expire (effectively logging the user
+ out). If this value is ``None``, the ticket never expires.
+ Optional.
+
+ ``reissue_time``
+
+ Default: ``None``. If this parameter is set, it represents the number
+ of seconds that must pass before an authentication token cookie is
+ automatically reissued as the result of a request which requires
+ authentication. The duration is measured as the number of seconds
+ since the last auth_tkt cookie was issued and 'now'. If this value is
+ ``0``, a new ticket cookie will be reissued on every request which
+ requires authentication.
+
+ A good rule of thumb: if you want auto-expired cookies based on
+ inactivity: set the ``timeout`` value to 1200 (20 mins) and set the
+ ``reissue_time`` value to perhaps a tenth of the ``timeout`` value
+ (120 or 2 mins). It's nonsensical to set the ``timeout`` value lower
+ than the ``reissue_time`` value, as the ticket will never be reissued
+ if so. However, such a configuration is not explicitly prevented.
+
+ Optional.
+
+ ``max_age``
+
+ Default: ``None``. The max age of the auth_tkt cookie, in
+ seconds. This differs from ``timeout`` inasmuch as ``timeout``
+ represents the lifetime of the ticket contained in the cookie,
+ while this value represents the lifetime of the cookie itself.
+ When this value is set, the cookie's ``Max-Age`` and
+ ``Expires`` settings will be set, allowing the auth_tkt cookie
+ to last between browser sessions. It is typically nonsensical
+ to set this to a value that is lower than ``timeout`` or
+ ``reissue_time``, although it is not explicitly prevented.
+ Optional.
+
+ ``path``
+
+ Default: ``/``. The path for which the auth_tkt cookie is valid.
+ May be desirable if the application only serves part of a domain.
+ Optional.
+
+ ``http_only``
+
+ Default: ``False``. Hide cookie from JavaScript by setting the
+ HttpOnly flag. Not honored by all browsers.
+ Optional.
+
+ ``wild_domain``
+
+ Default: ``True``. An auth_tkt cookie will be generated for the
+ wildcard domain. If your site is hosted as ``example.com`` this
+ will make the cookie available for sites underneath ``example.com``
+ such as ``www.example.com``.
+ Optional.
+
+ ``parent_domain``
+
+ Default: ``False``. An auth_tkt cookie will be generated for the
+ parent domain of the current site. For example if your site is
+ hosted under ``www.example.com`` a cookie will be generated for
+ ``.example.com``. This can be useful if you have multiple sites
+ sharing the same domain. This option supercedes the ``wild_domain``
+ option.
+ Optional.
+
+ ``domain``
+
+ Default: ``None``. If provided the auth_tkt cookie will only be
+ set for this domain. This option is not compatible with ``wild_domain``
+ and ``parent_domain``.
+ Optional.
+
+ ``hashalg``
+
+ Default: ``sha512`` (the literal string).
+
+ Any hash algorithm supported by Python's ``hashlib.new()`` function
+ can be used as the ``hashalg``.
+
+ Cookies generated by different instances of AuthTktAuthenticationPolicy
+ using different ``hashalg`` options are not compatible. Switching the
+ ``hashalg`` will imply that all existing users with a valid cookie will
+ be required to re-login.
+
+ Optional.
+
+ ``debug``
+
+ Default: ``False``. If ``debug`` is ``True``, log messages to the
+ Pyramid debug logger about the results of various authentication
+ steps. The output from debugging is useful for reporting to maillist
+ or IRC channels when asking for support.
+
+ ``samesite``
+
+ Default: ``'Lax'``. The 'samesite' option of the session cookie. Set
+ the value to ``None`` to turn off the samesite option.
.. versionchanged:: 1.4
@@ -694,14 +833,6 @@ class AuthTktCookieHelper(object):
subsystem secrets (see :ref:`admonishment_against_secret_sharing`).
Required.
- ``callback``
-
- Default: ``None``. A callback passed the userid and the
- request, expected to return ``None`` if the userid doesn't
- exist or a sequence of principal identifiers (possibly empty) if
- the user does exist. If ``callback`` is ``None``, the userid
- will be assumed to exist with no principals. Optional.
-
``cookie_name``
Default: ``auth_tkt``. The cookie name used
@@ -819,12 +950,16 @@ class AuthTktCookieHelper(object):
Default: ``False``. If ``debug`` is ``True``, log messages to the
Pyramid debug logger about the results of various authentication
steps. The output from debugging is useful for reporting to maillist
- or IRC channels when asking for support.
+ or IRC channels when asking for support. Optional.
``samesite``
Default: ``'Lax'``. The 'samesite' option of the session cookie. Set
- the value to ``None`` to turn off the samesite option.
+ the value to ``None`` to turn off the samesite option. Optional.
+
+ .. versionchanged:: 2.0
+
+ The default ``hashalg`` was changed from ``md5`` to ``sha512``.
"""
@@ -858,7 +993,7 @@ class AuthTktCookieHelper(object):
http_only=False,
path="/",
wild_domain=True,
- hashalg='md5',
+ hashalg='sha512',
parent_domain=False,
domain=None,
samesite='Lax',
diff --git a/src/pyramid/config/testing.py b/src/pyramid/config/testing.py
index db1aefb24..ea3f92d17 100644
--- a/src/pyramid/config/testing.py
+++ b/src/pyramid/config/testing.py
@@ -32,8 +32,8 @@ class TestingConfiguratorMixin(object):
:attr:`pyramid.request.Request.authenticated_userid` will have this
value as well.
:type userid: str
- :param identity: If provided, the policy's ``identify`` method will
- return this value. As a result,
+ :param identity: If provided, the policy's ``authenticated_identity``
+ method will return this value. As a result,
:attr:`pyramid.request.Request.authenticated_identity`` will have
this value.
:type identity: object
diff --git a/src/pyramid/interfaces.py b/src/pyramid/interfaces.py
index c4160cc2b..1f089216f 100644
--- a/src/pyramid/interfaces.py
+++ b/src/pyramid/interfaces.py
@@ -483,16 +483,16 @@ class IViewMapperFactory(Interface):
class ISecurityPolicy(Interface):
+ def authenticated_identity(request):
+ """ Return the :term:`identity` of the current user. The object can be
+ of any shape, such as a simple ID string or an ORM object.
+ """
+
def authenticated_userid(request):
""" Return a :term:`userid` string identifying the trusted and
verified user, or ``None`` if unauthenticated.
"""
- def identify(request):
- """ Return the :term:`identity` of the current user. The object can be
- of any shape, such as a simple ID string or an ORM object.
- """
-
def permits(request, context, permission):
""" Return an instance of :class:`pyramid.security.Allowed` if a user
of the given identity is allowed the ``permission`` in the current
diff --git a/src/pyramid/security.py b/src/pyramid/security.py
index 5e803aa0a..c0d01e0a7 100644
--- a/src/pyramid/security.py
+++ b/src/pyramid/security.py
@@ -300,7 +300,7 @@ class SecurityAPIMixin:
policy = _get_security_policy(self)
if policy is None:
return None
- return policy.identify(self)
+ return policy.authenticated_identity(self)
@property
def authenticated_userid(self):
@@ -431,7 +431,7 @@ class LegacySecurityPolicy:
def _get_authz_policy(self, request):
return request.registry.getUtility(IAuthorizationPolicy)
- def identify(self, request):
+ def authenticated_identity(self, request):
return self.authenticated_userid(request)
def authenticated_userid(self, request):
diff --git a/src/pyramid/testing.py b/src/pyramid/testing.py
index a03f2678e..af02872dd 100644
--- a/src/pyramid/testing.py
+++ b/src/pyramid/testing.py
@@ -51,7 +51,7 @@ class DummySecurityPolicy(object):
self.remember_result = remember_result
self.forget_result = forget_result
- def identify(self, request):
+ def authenticated_identity(self, request):
return self.identity
def authenticated_userid(self, request):
diff --git a/tests/pkgs/securityapp/__init__.py b/tests/pkgs/securityapp/__init__.py
index 6c9025e7d..facc37878 100644
--- a/tests/pkgs/securityapp/__init__.py
+++ b/tests/pkgs/securityapp/__init__.py
@@ -3,7 +3,7 @@ from pyramid.security import Allowed, Denied
class SecurityPolicy:
- def identify(self, request):
+ def authenticated_identity(self, request):
raise NotImplementedError() # pragma: no cover
def authenticated_userid(self, request):
diff --git a/tests/test_security.py b/tests/test_security.py
index fa3d165ea..db5861562 100644
--- a/tests/test_security.py
+++ b/tests/test_security.py
@@ -479,7 +479,7 @@ class TestLegacySecurityPolicy(unittest.TestCase):
policy = LegacySecurityPolicy()
_registerAuthenticationPolicy(request.registry, 'userid')
- self.assertEqual(policy.identify(request), 'userid')
+ self.assertEqual(policy.authenticated_identity(request), 'userid')
def test_remember(self):
from pyramid.security import LegacySecurityPolicy
@@ -532,7 +532,7 @@ class DummySecurityPolicy:
def __init__(self, result):
self.result = result
- def identify(self, request):
+ def authenticated_identity(self, request):
return self.result
def authenticated_userid(self, request):
diff --git a/tests/test_testing.py b/tests/test_testing.py
index a5746b59d..dbda76454 100644
--- a/tests/test_testing.py
+++ b/tests/test_testing.py
@@ -27,9 +27,9 @@ class TestDummySecurityPolicy(unittest.TestCase):
klass = self._getTargetClass()
return klass(userid, identity, permissive)
- def test_identify(self):
+ def test_authenticated_identity(self):
policy = self._makeOne('user', 'identity')
- self.assertEqual(policy.identify(None), 'identity')
+ self.assertEqual(policy.authenticated_identity(None), 'identity')
def test_authenticated_userid(self):
policy = self._makeOne('user')