diff options
| -rw-r--r-- | docs/api/request.rst | 20 | ||||
| -rw-r--r-- | docs/narr/security.rst | 54 | ||||
| -rw-r--r-- | docs/whatsnew-2.0.rst | 19 | ||||
| -rw-r--r-- | src/pyramid/interfaces.py | 6 |
4 files changed, 38 insertions, 61 deletions
diff --git a/docs/api/request.rst b/docs/api/request.rst index fb4b5caee..50703ff63 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -166,27 +166,17 @@ .. attribute:: authenticated_userid - .. versionchanged:: 2.0 - - ``authenticated_userid`` uses security policy or authn pol - see also :attr:`authenticated_identity` and - :ref:`upgrading_auth` for more information. - A property which returns the :term:`userid` of the currently - authenticated user or ``None`` if there is no :term:`authentication - policy` in effect or there is no currently authenticated user. This - differs from :attr:`~pyramid.request.Request.unauthenticated_userid`, - because the effective authentication policy will have ensured that a - record associated with the :term:`userid` exists in persistent storage; - if it has not, this value will be ``None``. + authenticated user or ``None`` if there is no :term:`security policy` in + effect or there is no currently authenticated user. .. attribute:: unauthenticated_userid .. deprecated:: 2.0 - ``unauthenticated_userid`` has been replaced by - :attr:`authenticated_identity` in the new security system. See - :ref:`upgrading_auth` for more information. + ``unauthenticated_userid`` has been deprecated in version 2.0. Use + :attr:`authenticated_userid` or :attr:`authenticated_identity` + instead. See :ref:`upgrading_auth` for more information. A property which returns a value which represents the *claimed* (not verified) :term:`userid` of the credentials present in the diff --git a/docs/narr/security.rst b/docs/narr/security.rst index a71b9abd9..b01bec903 100644 --- a/docs/narr/security.rst +++ b/docs/narr/security.rst @@ -32,14 +32,11 @@ how it works at a high level: - A :term:`view callable` is located by :term:`view lookup` using the context as well as other attributes of the request. -- If a :term:`security policy` is in effect, it is passed the request and - returns the :term:`identity` of the current user. - - If a :term:`security policy` is in effect and the :term:`view configuration` associated with the view callable that was found has a - :term:`permission` associated with it, the policy is passed the - :term:`context`, the current :term:`identity`, and the :term:`permission` - associated with the view; it will allow or deny access. + :term:`permission` associated with it, the policy is passed :term:`request`, + the :term:`context`, and the :term:`permission` associated with the view; it + will allow or deny access. - If the security policy allows access, the view callable is invoked. @@ -62,7 +59,7 @@ Writing a Security Policy accessible by completely anonymous users. In order to begin protecting views from execution based on security settings, you need to write a security policy. -Security policies are simple classes implementing a +Security policies are simple classes implementing :class:`pyramid.interfaces.ISecurityPolicy`. A simple security policy might look like the following: @@ -72,15 +69,16 @@ A simple security policy might look like the following: from pyramid.security import Allowed, Denied class SessionSecurityPolicy: - def authenticated_userid(self, request): - """ Return the user ID stored in the session. """ - return request.session.get('userid') - def identify(self, request): """ Return app-specific user object. """ - userid = self.authenticated_userid(request) - if userid is not None: - return models.Users.get(id=userid) + userid = request.session.get('userid') + if userid is None: + return None + return load_identity_from_db(request, userid) + + def authenticated_userid(self, request): + """ Return a string ID for the user. """ + return self.identify(request).id def permits(self, request, context, permission): """ Allow access to everything if signed in. """ @@ -143,12 +141,12 @@ For example, our above security policy can leverage these helpers like so: def __init__(self): self.helper = SessionAuthenticationHelper() - def authenticated_userid(self, request): - # XXX add code - ... - def identify(self, request): - return self.helper.identify(request) + userid = self.helper.authenticated_userid(request) + return load_identity_from_db(request, userid) + + def authenticated_userid(self, request): + return self.identify(request).id def permits(self, request, context, permission): """ Allow access to everything if signed in. """ @@ -164,19 +162,11 @@ For example, our above security policy can leverage these helpers like so: def forget(request, **kw): return self.helper.forget(request, **kw) -Helpers are intended to be used with application-specific code, so perhaps your -authentication also queries the database to ensure the identity is valid. - -.. code-block:: python - :linenos: - - def identify(self, request): - # XXX review: use authenticated_userid below or identify? - user_id = self.helper.identify(request) - if validate_user_id(user_id): - return user_id - else: - return None +Helpers are intended to be used with application-specific code. Notice how the +above code takes the userid from the helper and uses it to load the +:term:`identity` from the database. ``authenticated_userid`` pulls the +:term:`userid` from the :term:`identity` in order to guarantee that the user ID +stored in the session exists in the database ("authenticated"). .. index:: single: permissions diff --git a/docs/whatsnew-2.0.rst b/docs/whatsnew-2.0.rst index b5f349166..6b3261284 100644 --- a/docs/whatsnew-2.0.rst +++ b/docs/whatsnew-2.0.rst @@ -40,17 +40,15 @@ The new security policy should implement ``security_policy`` argument of :class:`pyramid.config.Configurator` or :meth:`pyramid.config.Configurator.set_security_policy`. +The policy contains ``authenticated_userid`` and ``remember``, +with the same method signatures as in the legacy authentication policy. It +also contains ``forget``, but now with keyword arguments in the method +signature. + The new security policy adds the concept of an :term:`identity`, which is an object representing the user associated with the current request. The identity can be accessed via :attr:`pyramid.request.Request.authenticated_identity`. -The object can be of any shape, such as a simple ID string or an ORM object, -and should represent an active user. - -As in previous version, the property :attr:`pyramid.request.Request.authenticated_userid` -can be used to get a string identifying the current user, for example -the ID of the user object in a database. The value is obtained from the -security policy. -(:attr:`pyramid.request.Request.unauthenticated_userid` has been deprecated.) +The object can be of any shape, such as a simple ID string or an ORM object. The concept of :term:`principals <principal>` has been removed; the ``permits`` method is passed an identity object. This change gives much more @@ -97,9 +95,8 @@ The new :attr:`pyramid.request.Request.authenticated_identity` property will output the same result as :attr:`pyramid.request.Request.authenticated_userid`. If using a security policy, -:attr:`pyramid.request.Request.unauthenticated_userid` and -:attr:`pyramid.request.Request.authenticated_userid` will both return the -string representation of the :term:`identity`. +:attr:`pyramid.request.Request.authenticated_userid` will return the same value +as :attr:`pyramid.request.Request.authenticated_userid`. :attr:`pyramid.request.Request.effective_principals` will always return a one-element list containing the :data:`pyramid.security.Everyone` principal, as there is no equivalent in the new security policy. diff --git a/src/pyramid/interfaces.py b/src/pyramid/interfaces.py index 11b794e2b..891b851ee 100644 --- a/src/pyramid/interfaces.py +++ b/src/pyramid/interfaces.py @@ -484,9 +484,9 @@ class IViewMapperFactory(Interface): class ISecurityPolicy(Interface): def identify(request): - """ Return an object identifying a trusted and verified user. - - The object may be anything. + """ Return an object identifying a trusted and verified user for the + current request. The object can be of any shape, such as a simple ID + string or an ORM object. """ def authenticated_userid(request, identity): |
