summaryrefslogtreecommitdiff
path: root/docs/tutorials/wiki2
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2020-01-07 23:48:51 -0600
committerMichael Merickel <michael@merickel.org>2020-01-09 23:43:19 -0600
commit7adc44fa2b4bfa5b4230d8646e734ba262ec1ce2 (patch)
treed3859ecceb465c41433197e0deaebe9b712a982e /docs/tutorials/wiki2
parent68c1929bbfec92f3fff1985226d88f41b02e5a4f (diff)
downloadpyramid-7adc44fa2b4bfa5b4230d8646e734ba262ec1ce2.tar.gz
pyramid-7adc44fa2b4bfa5b4230d8646e734ba262ec1ce2.tar.bz2
pyramid-7adc44fa2b4bfa5b4230d8646e734ba262ec1ce2.zip
demonstrate an identity_cache
Diffstat (limited to 'docs/tutorials/wiki2')
-rw-r--r--docs/tutorials/wiki2/authentication.rst23
-rw-r--r--docs/tutorials/wiki2/authorization.rst2
-rw-r--r--docs/tutorials/wiki2/src/authentication/tutorial/security.py7
-rw-r--r--docs/tutorials/wiki2/src/authorization/tutorial/security.py7
-rw-r--r--docs/tutorials/wiki2/src/tests/tutorial/security.py7
5 files changed, 38 insertions, 8 deletions
diff --git a/docs/tutorials/wiki2/authentication.rst b/docs/tutorials/wiki2/authentication.rst
index a4937d93e..381868e71 100644
--- a/docs/tutorials/wiki2/authentication.rst
+++ b/docs/tutorials/wiki2/authentication.rst
@@ -51,15 +51,30 @@ It also handles authorization, which we'll cover in the next chapter (if you're
Identifying the current user is done in a couple steps:
-1. The ``MySecurityPolicy.authenticated_identity`` method asks the cookie helper to pull the identity from the request.
+1. :app:`Pyramid` invokes a method on the policy requesting identity, userid, or permission to perform an operation.
+
+1. The policy starts by calling :meth:`pyramid.request.RequestLocalCache.get_or_create` to load the identity.
+
+1. The ``MySecurityPolicy.load_identity`` method asks the cookie helper to pull the identity from the request.
This value is ``None`` if the cookie is missing or the content cannot be verified.
-2. We then translate the identity into a ``tutorial.models.User`` object by looking for a record in the database.
-This is a good spot to confirm that the user is actually allowed to access our application.
-For example, maybe they were marked deleted or banned and we should return ``None`` instead of the ``user`` object.
+1. The policy then translates the identity into a ``tutorial.models.User`` object by looking for a record in the database.
+ This is a good spot to confirm that the user is actually allowed to access our application.
+ For example, maybe they were marked deleted or banned and we should return ``None`` instead of the ``user`` object.
+
+1. The result is stored in the ``identity_cache`` which ensures that subsequent invocations return the same identity object for the request.
Finally, :attr:`pyramid.request.Request.authenticated_identity` contains either ``None`` or a ``tutorial.models.User`` instance and that value is aliased to ``request.user`` for convenience in our application.
+Note the usage of the ``identity_cache`` is optional, but it has several advantages in most scenarios:
+
+- It improves performance as the identity is necessary for many operations during the lifetime of a request.
+
+- It provides consistency across method invocations to ensure the identity does not change while processing the request.
+
+It is up to individual security policies and applications to determine the best approach with respect to caching.
+Applications is long-running requests may want to avoid caching the identity, or tracking some extra metadata to re-verify it periodically against the authentication source.
+
Configure the app
~~~~~~~~~~~~~~~~~
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst
index e8f95f8cf..001bde935 100644
--- a/docs/tutorials/wiki2/authorization.rst
+++ b/docs/tutorials/wiki2/authorization.rst
@@ -40,7 +40,7 @@ Open the file ``tutorial/security.py`` and edit it as follows:
.. literalinclude:: src/authorization/tutorial/security.py
:linenos:
- :emphasize-lines: 2,4-7,15,37-48
+ :emphasize-lines: 2,5-8,17,42-53
:language: python
Only the highlighted lines need to be added.
diff --git a/docs/tutorials/wiki2/src/authentication/tutorial/security.py b/docs/tutorials/wiki2/src/authentication/tutorial/security.py
index 48149d6e5..1027ddd0a 100644
--- a/docs/tutorials/wiki2/src/authentication/tutorial/security.py
+++ b/docs/tutorials/wiki2/src/authentication/tutorial/security.py
@@ -1,5 +1,6 @@
from pyramid.authentication import AuthTktCookieHelper
from pyramid.csrf import CookieCSRFStoragePolicy
+from pyramid.request import RequestLocalCache
from . import models
@@ -7,8 +8,9 @@ from . import models
class MySecurityPolicy:
def __init__(self, secret):
self.authtkt = AuthTktCookieHelper(secret)
+ self.identity_cache = RequestLocalCache(self.load_identity)
- def authenticated_identity(self, request):
+ def load_identity(self, request):
identity = self.authtkt.identify(request)
if identity is None:
return None
@@ -17,6 +19,9 @@ class MySecurityPolicy:
user = request.dbsession.query(models.User).get(userid)
return user
+ def authenticated_identity(self, request):
+ return self.identity_cache.get_or_create(request)
+
def authenticated_userid(self, request):
user = self.authenticated_identity(request)
if user is not None:
diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security.py b/docs/tutorials/wiki2/src/authorization/tutorial/security.py
index 448183c95..7a99fb9e9 100644
--- a/docs/tutorials/wiki2/src/authorization/tutorial/security.py
+++ b/docs/tutorials/wiki2/src/authorization/tutorial/security.py
@@ -1,6 +1,7 @@
from pyramid.authentication import AuthTktCookieHelper
from pyramid.authorization import ACLHelper
from pyramid.csrf import CookieCSRFStoragePolicy
+from pyramid.request import RequestLocalCache
from pyramid.security import (
Authenticated,
Everyone,
@@ -12,9 +13,10 @@ from . import models
class MySecurityPolicy:
def __init__(self, secret):
self.authtkt = AuthTktCookieHelper(secret)
+ self.identity_cache = RequestLocalCache(self.load_identity)
self.acl = ACLHelper()
- def authenticated_identity(self, request):
+ def load_identity(self, request):
identity = self.authtkt.identify(request)
if identity is None:
return None
@@ -23,6 +25,9 @@ class MySecurityPolicy:
user = request.dbsession.query(models.User).get(userid)
return user
+ def authenticated_identity(self, request):
+ return self.identity_cache.get_or_create(request)
+
def authenticated_userid(self, request):
user = self.authenticated_identity(request)
if user is not None:
diff --git a/docs/tutorials/wiki2/src/tests/tutorial/security.py b/docs/tutorials/wiki2/src/tests/tutorial/security.py
index 448183c95..7a99fb9e9 100644
--- a/docs/tutorials/wiki2/src/tests/tutorial/security.py
+++ b/docs/tutorials/wiki2/src/tests/tutorial/security.py
@@ -1,6 +1,7 @@
from pyramid.authentication import AuthTktCookieHelper
from pyramid.authorization import ACLHelper
from pyramid.csrf import CookieCSRFStoragePolicy
+from pyramid.request import RequestLocalCache
from pyramid.security import (
Authenticated,
Everyone,
@@ -12,9 +13,10 @@ from . import models
class MySecurityPolicy:
def __init__(self, secret):
self.authtkt = AuthTktCookieHelper(secret)
+ self.identity_cache = RequestLocalCache(self.load_identity)
self.acl = ACLHelper()
- def authenticated_identity(self, request):
+ def load_identity(self, request):
identity = self.authtkt.identify(request)
if identity is None:
return None
@@ -23,6 +25,9 @@ class MySecurityPolicy:
user = request.dbsession.query(models.User).get(userid)
return user
+ def authenticated_identity(self, request):
+ return self.identity_cache.get_or_create(request)
+
def authenticated_userid(self, request):
user = self.authenticated_identity(request)
if user is not None: