summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS.txt2
-rw-r--r--docs/api/authentication.rst2
-rw-r--r--pyramid/authentication.py42
-rw-r--r--pyramid/tests/test_authentication.py98
-rw-r--r--pyramid/url.py8
5 files changed, 145 insertions, 7 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index f2195de70..2873ce1b6 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -138,3 +138,5 @@ Contributors
- Juliusz Gonera, 2011/04/17
- Philip Jenvey, 2011/04/24
+
+- Michael Merickel, 2011/5/25
diff --git a/docs/api/authentication.rst b/docs/api/authentication.rst
index bf7f8f8d5..5d4dbd9e3 100644
--- a/docs/api/authentication.rst
+++ b/docs/api/authentication.rst
@@ -14,6 +14,8 @@ Authentication Policies
.. autoclass:: RemoteUserAuthenticationPolicy
+ .. autoclass:: SessionAuthenticationPolicy
+
Helper Classes
~~~~~~~~~~~~~~
diff --git a/pyramid/authentication.py b/pyramid/authentication.py
index a6c74e549..e1384e0b8 100644
--- a/pyramid/authentication.py
+++ b/pyramid/authentication.py
@@ -524,4 +524,44 @@ class AuthTktCookieHelper(object):
cookie_value = ticket.cookie_value()
return self._get_cookies(environ, cookie_value, max_age)
-
+
+class SessionAuthenticationPolicy(CallbackAuthenticationPolicy):
+ """ A :app:`Pyramid` authentication policy which gets its data from
+ the configured session.
+
+ Constructor Arguments
+
+ ``prefix``
+
+ A prefix used when storing the authentication parameters in the
+ session. Defaults to 'auth.'. Optional.
+
+ ``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.
+ """
+ implements(IAuthenticationPolicy)
+
+ def __init__(self, prefix='auth.', callback=None):
+ self.callback = callback
+ self.prefix = prefix or ''
+ self.userid_key = prefix + 'userid'
+
+ def remember(self, request, principal, **kw):
+ """ Store a principal in the session."""
+ request.session[self.userid_key] = principal
+ return []
+
+ def forget(self, request):
+ """ Remove the stored principal from the session."""
+ if self.userid_key in request.session:
+ del request.session[self.userid_key]
+ return []
+
+ def unauthenticated_userid(self, request):
+ return request.session.get(self.userid_key)
+
diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py
index ecd76a71c..8acc2b31c 100644
--- a/pyramid/tests/test_authentication.py
+++ b/pyramid/tests/test_authentication.py
@@ -751,12 +751,106 @@ class TestAuthTktCookieHelper(unittest.TestCase):
'auth_tkt=""; Path=/; Domain=.localhost; Max-Age=0; '
'Expires=Wed, 31-Dec-97 23:59:59 GMT')
+
+class TestSessionAuthenticationPolicy(unittest.TestCase):
+ def _getTargetClass(self):
+ from pyramid.authentication import SessionAuthenticationPolicy
+ return SessionAuthenticationPolicy
+
+ def _makeOne(self, callback=None, prefix=''):
+ return self._getTargetClass()(prefix=prefix, callback=callback)
+
+ def test_class_implements_IAuthenticationPolicy(self):
+ from zope.interface.verify import verifyClass
+ from pyramid.interfaces import IAuthenticationPolicy
+ verifyClass(IAuthenticationPolicy, self._getTargetClass())
+
+ def test_instance_implements_IAuthenticationPolicy(self):
+ from zope.interface.verify import verifyObject
+ from pyramid.interfaces import IAuthenticationPolicy
+ verifyObject(IAuthenticationPolicy, self._makeOne())
+
+ def test_unauthenticated_userid_returns_None(self):
+ request = DummyRequest()
+ policy = self._makeOne()
+ self.assertEqual(policy.unauthenticated_userid(request), None)
+
+ def test_unauthenticated_userid(self):
+ request = DummyRequest(session={'userid':'fred'})
+ policy = self._makeOne()
+ self.assertEqual(policy.unauthenticated_userid(request), 'fred')
+
+ def test_authenticated_userid_no_cookie_identity(self):
+ request = DummyRequest()
+ policy = self._makeOne()
+ self.assertEqual(policy.authenticated_userid(request), None)
+
+ def test_authenticated_userid_callback_returns_None(self):
+ request = DummyRequest(session={'userid':'fred'})
+ def callback(userid, request):
+ return None
+ policy = self._makeOne(callback)
+ self.assertEqual(policy.authenticated_userid(request), None)
+
+ def test_authenticated_userid(self):
+ request = DummyRequest(session={'userid':'fred'})
+ def callback(userid, request):
+ return True
+ policy = self._makeOne(callback)
+ self.assertEqual(policy.authenticated_userid(request), 'fred')
+
+ def test_effective_principals_no_identity(self):
+ from pyramid.security import Everyone
+ request = DummyRequest()
+ policy = self._makeOne()
+ self.assertEqual(policy.effective_principals(request), [Everyone])
+
+ def test_effective_principals_callback_returns_None(self):
+ from pyramid.security import Everyone
+ request = DummyRequest(session={'userid':'fred'})
+ def callback(userid, request):
+ return None
+ policy = self._makeOne(callback)
+ self.assertEqual(policy.effective_principals(request), [Everyone])
+
+ def test_effective_principals(self):
+ from pyramid.security import Everyone
+ from pyramid.security import Authenticated
+ request = DummyRequest(session={'userid':'fred'})
+ def callback(userid, request):
+ return ['group.foo']
+ policy = self._makeOne(callback)
+ self.assertEqual(policy.effective_principals(request),
+ [Everyone, Authenticated, 'fred', 'group.foo'])
+
+ def test_remember(self):
+ request = DummyRequest()
+ policy = self._makeOne()
+ result = policy.remember(request, 'fred')
+ self.assertEqual(request.session.get('userid'), 'fred')
+ self.assertEqual(result, [])
+
+ def test_forget(self):
+ request = DummyRequest(session={'userid':'fred'})
+ policy = self._makeOne()
+ result = policy.forget(request)
+ self.assertEqual(request.session.get('userid'), None)
+ self.assertEqual(result, [])
+
+ def test_forget_no_identity(self):
+ request = DummyRequest()
+ policy = self._makeOne()
+ result = policy.forget(request)
+ self.assertEqual(request.session.get('userid'), None)
+ self.assertEqual(result, [])
+
class DummyContext:
pass
class DummyRequest:
- def __init__(self, environ):
- self.environ = environ
+ def __init__(self, environ=None, session=None):
+ self.environ = environ or {}
+ self.session = session or {}
self.callbacks = []
def add_response_callback(self, callback):
diff --git a/pyramid/url.py b/pyramid/url.py
index 2a6fda89a..a9d7862fd 100644
--- a/pyramid/url.py
+++ b/pyramid/url.py
@@ -20,7 +20,7 @@ def route_url(route_name, request, *elements, **kw):
"""Generates a fully qualified URL for a named :app:`Pyramid`
:term:`route configuration`.
- .. note:: Calling :meth:`pyramid.Request.route_url` can be used to
+ .. note:: Calling :meth:`pyramid.request.Request.route_url` can be used to
achieve the same result as :func:`pyramid.url.route_url`.
Use the route's ``name`` as the first positional argument. Use a
@@ -159,7 +159,7 @@ def route_path(route_name, request, *elements, **kw):
"""Generates a path (aka a 'relative URL', a URL minus the host, scheme,
and port) for a named :app:`Pyramid` :term:`route configuration`.
- .. note:: Calling :meth:`pyramid.Request.route_path` can be used to
+ .. note:: Calling :meth:`pyramid.request.Request.route_path` can be used to
achieve the same result as :func:`pyramid.url.route_path`.
This function accepts the same argument as :func:`pyramid.url.route_url`
@@ -191,7 +191,7 @@ def resource_url(resource, request, *elements, **kw):
overall result of this function is always a UTF-8 encoded string
(never Unicode).
- .. note:: Calling :meth:`pyramid.Request.resource_url` can be used to
+ .. note:: Calling :meth:`pyramid.request.Request.resource_url` can be used to
achieve the same result as :func:`pyramid.url.resource_url`.
Examples::
@@ -325,7 +325,7 @@ def static_url(path, request, **kw):
:meth:`pyramid.config.Configurator.add_static_view`
:term:`configuration declaration` (see :ref:`static_assets_section`).
- .. note:: Calling :meth:`pyramid.Request.static_url` can be used to
+ .. note:: Calling :meth:`pyramid.request.Request.static_url` can be used to
achieve the same result as :func:`pyramid.url.static_url`.
Example::