summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉric Araujo <merwok@netwok.org>2020-07-01 18:33:12 -0400
committerÉric Araujo <merwok@netwok.org>2020-07-02 13:09:45 -0400
commit70a23ba6e872ae03988caa322f8dd2b03770515c (patch)
tree06ffd4c5c36b4cb5b3723cb6e3a25d2fbec0572b
parentbaa59284e1ee26284ecb68d957d5607e40ed786f (diff)
downloadpyramid-70a23ba6e872ae03988caa322f8dd2b03770515c.tar.gz
pyramid-70a23ba6e872ae03988caa322f8dd2b03770515c.tar.bz2
pyramid-70a23ba6e872ae03988caa322f8dd2b03770515c.zip
add tests and docs
-rw-r--r--CHANGES.rst5
-rw-r--r--docs/narr/viewconfig.rst8
-rw-r--r--src/pyramid/config/routes.py7
-rw-r--r--src/pyramid/config/views.py6
-rw-r--r--src/pyramid/interfaces.py9
-rw-r--r--src/pyramid/security.py2
-rw-r--r--tests/test_config/test_predicates.py23
-rw-r--r--tests/test_config/test_routes.py12
-rw-r--r--tests/test_config/test_views.py40
-rw-r--r--tests/test_security.py23
10 files changed, 122 insertions, 13 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 6b6e1ebbb..753997bf4 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -22,10 +22,13 @@ Features
- ``pyramid.config.Configurator.set_security_policy``.
- ``pyramid.interfaces.ISecurityPolicy``
- ``pyramid.request.Request.authenticated_identity``.
+ - ``pyramid.request.Request.is_authenticated``
- ``pyramid.authentication.SessionAuthenticationHelper``
- ``pyramid.authorization.ACLHelper``
+ - ``is_authenticated=True/False`` predicate for route and view configs
- See https://github.com/Pylons/pyramid/pull/3465
+ See https://github.com/Pylons/pyramid/pull/3465 and
+ https://github.com/Pylons/pyramid/pull/3598
- Changed the default ``serializer`` on
``pyramid.session.SignedCookieSessionFactory`` to use
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst
index c60b7b50d..2dd5bfb9e 100644
--- a/docs/narr/viewconfig.rst
+++ b/docs/narr/viewconfig.rst
@@ -496,7 +496,11 @@ configured view.
``is_authenticated``
- XXX doc doc
+ This value, if specified, must be either ``True`` or ``False``. If it is
+ specified and is ``True``, the request must be for an authenticated user,
+ as determined by the :term:`security policy` in use. If it is specified and
+ ``False``, the associated view callable will be invoked only if the request
+ does not have an authenticated user.
.. versionadded:: 2.0
@@ -511,7 +515,7 @@ configured view.
.. versionadded:: 1.4a4
- .. deprecated:: TODO add
+ .. deprecated:: 2.0
``custom_predicates``
If ``custom_predicates`` is specified, it must be a sequence of references to
diff --git a/src/pyramid/config/routes.py b/src/pyramid/config/routes.py
index 0fbfcca0c..feb28c7a7 100644
--- a/src/pyramid/config/routes.py
+++ b/src/pyramid/config/routes.py
@@ -270,7 +270,12 @@ class RoutesConfiguratorMixin:
is_authenticated
- XXX doc doc
+ This value, if specified, should be either ``True`` or ``False``.
+ If it is specified and is ``True``, the route will only match if
+ the request has an authenticated user, as determined by the
+ :term:`security policy` in use. If it is specified and ``False``,
+ the route will only match if the request does not have an
+ authenticated user.
.. versionadded:: 2.0
diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py
index 87f2cbcd7..4a5723a14 100644
--- a/src/pyramid/config/views.py
+++ b/src/pyramid/config/views.py
@@ -714,7 +714,11 @@ class ViewsConfiguratorMixin:
is_authenticated
- XXX doc doc
+ This value, if specified, should be either ``True`` or ``False``.
+ If it is specified and is ``True``, the request must be for an
+ authenticated user, as determined by the :term:`security policy` in
+ use. If it is specified and ``False``, the associated view callable
+ will match only if the request does not have an authenticated user.
..versionadded:: 2.0
diff --git a/src/pyramid/interfaces.py b/src/pyramid/interfaces.py
index 85539c2f2..b8c8d06a9 100644
--- a/src/pyramid/interfaces.py
+++ b/src/pyramid/interfaces.py
@@ -114,11 +114,13 @@ class IResponse(Interface):
serves up only the given start:stop range. """
authenticated_identity = Attribute(
- """XXX Doc doc"""
+ """An object representing the authenticated user, as determined by
+ the security policy in use, or ``None`` for unauthenticated requests.
+ The object's class and meaning is defined by the security policy."""
)
authenticated_userid = Attribute(
- """XXX Doc doc"""
+ """A string to identify the authenticated user or ``None``."""
)
body = Attribute(
@@ -242,7 +244,8 @@ class IResponse(Interface):
headers = Attribute(""" The headers in a dictionary-like object """)
is_authenticated = Attribute(
- """XXX doc doc"""
+ """A boolean indicating whether the request has an authenticated
+ user, as determined by the security policy in use."""
)
last_modified = Attribute(
diff --git a/src/pyramid/security.py b/src/pyramid/security.py
index 356286407..2a1ef24bd 100644
--- a/src/pyramid/security.py
+++ b/src/pyramid/security.py
@@ -246,7 +246,7 @@ class SecurityAPIMixin:
@property
def is_authenticated(self):
- """Return True if a user is authenticated for this request."""
+ """Return ``True`` if a user is authenticated for this request."""
return self.authenticated_identity is not None
def has_permission(self, permission, context=None):
diff --git a/tests/test_config/test_predicates.py b/tests/test_config/test_predicates.py
index 6797e71bc..7e2f32786 100644
--- a/tests/test_config/test_predicates.py
+++ b/tests/test_config/test_predicates.py
@@ -454,13 +454,28 @@ class TestPredicateList(unittest.TestCase):
self.assertFalse(predicates[0](Dummy(), request))
def test_is_authenticated_true_matches(self):
- ...
+ _, predicates, _ = self._callFUT(is_authenticated=True)
+ request = DummyRequest()
+ request.is_authenticated = True
+ self.assertTrue(predicates[0](Dummy(), request))
+
def test_is_authenticated_true_fails(self):
- ...
+ _, predicates, _ = self._callFUT(is_authenticated=True)
+ request = DummyRequest()
+ request.is_authenticated = False
+ self.assertFalse(predicates[0](Dummy(), request))
+
def test_is_authenticated_false_matches(self):
- ...
+ _, predicates, _ = self._callFUT(is_authenticated=False)
+ request = DummyRequest()
+ request.is_authenticated = False
+ self.assertTrue(predicates[0](Dummy(), request))
+
def test_is_authenticated_false_fails(self):
- ...
+ _, predicates, _ = self._callFUT(is_authenticated=False)
+ request = DummyRequest()
+ request.is_authenticated = True
+ self.assertFalse(predicates[0](Dummy(), request))
def test_unknown_predicate(self):
from pyramid.exceptions import ConfigurationError
diff --git a/tests/test_config/test_routes.py b/tests/test_config/test_routes.py
index 8227784ec..605f61857 100644
--- a/tests/test_config/test_routes.py
+++ b/tests/test_config/test_routes.py
@@ -184,6 +184,18 @@ class RoutesConfiguratorMixinTests(unittest.TestCase):
request.params = {}
self.assertEqual(predicate(None, request), False)
+ def test_add_route_with_is_authenticated(self):
+ config = self._makeOne(autocommit=True)
+ config.add_route('name', 'path', is_authenticated=True)
+ route = self._assertRoute(config, 'name', 'path', 1)
+ predicate = route.predicates[0]
+ request = self._makeRequest(config)
+ request.is_authenticated = True
+ self.assertEqual(predicate(None, request), True)
+ request = self._makeRequest(config)
+ request.is_authenticated = False
+ self.assertEqual(predicate(None, request), False)
+
def test_add_route_with_custom_predicates(self):
import warnings
diff --git a/tests/test_config/test_views.py b/tests/test_config/test_views.py
index 2a55ad45d..09714d82e 100644
--- a/tests/test_config/test_views.py
+++ b/tests/test_config/test_views.py
@@ -1742,6 +1742,46 @@ class TestViewsConfigurationMixin(unittest.TestCase):
request.is_xhr = False
self._assertNotFound(wrapper, None, request)
+ def test_add_view_with_is_authenticated_true_matches(self):
+ from pyramid.renderers import null_renderer as nr
+
+ view = lambda *arg: 'OK'
+ config = self._makeOne(autocommit=True)
+ config.add_view(view=view, is_authenticated=True, renderer=nr)
+ wrapper = self._getViewCallable(config)
+ request = self._makeRequest(config)
+ request.is_authenticated = True
+ self.assertEqual(wrapper(None, request), 'OK')
+
+ def test_add_view_with_is_authenticated_true_no_match(self):
+ view = lambda *arg: 'OK'
+ config = self._makeOne(autocommit=True)
+ config.add_view(view=view, is_authenticated=True)
+ wrapper = self._getViewCallable(config)
+ request = self._makeRequest(config)
+ request.is_authenticated = False
+ self._assertNotFound(wrapper, None, request)
+
+ def test_add_view_with_is_authenticated_false_matches(self):
+ from pyramid.renderers import null_renderer as nr
+
+ view = lambda *arg: 'OK'
+ config = self._makeOne(autocommit=True)
+ config.add_view(view=view, is_authenticated=False, renderer=nr)
+ wrapper = self._getViewCallable(config)
+ request = self._makeRequest(config)
+ request.is_authenticated = False
+ self.assertEqual(wrapper(None, request), 'OK')
+
+ def test_add_view_with_is_authenticated_false_no_match(self):
+ view = lambda *arg: 'OK'
+ config = self._makeOne(autocommit=True)
+ config.add_view(view=view, is_authenticated=False)
+ wrapper = self._getViewCallable(config)
+ request = self._makeRequest(config)
+ request.is_authenticated = True
+ self._assertNotFound(wrapper, None, request)
+
def test_add_view_with_header_badregex(self):
view = lambda *arg: 'OK'
config = self._makeOne()
diff --git a/tests/test_security.py b/tests/test_security.py
index bf2908100..72598f570 100644
--- a/tests/test_security.py
+++ b/tests/test_security.py
@@ -393,6 +393,29 @@ class TestUnAuthenticatedUserId(unittest.TestCase):
self.assertEqual(request.unauthenticated_userid, 'wat')
+class TestIsAuthenticated(unittest.TestCase):
+ def setUp(self):
+ testing.setUp()
+
+ def tearDown(self):
+ testing.tearDown()
+
+ def test_no_security_policy(self):
+ request = _makeRequest()
+ self.assertIs(request.is_authenticated, False)
+
+ def test_with_security_policy(self):
+ request = _makeRequest()
+ _registerSecurityPolicy(request.registry, '123')
+ self.assertIs(request.is_authenticated, True)
+
+ def test_with_legacy_security_policy(self):
+ request = _makeRequest()
+ _registerAuthenticationPolicy(request.registry, 'yo')
+ _registerLegacySecurityPolicy(request.registry)
+ self.assertEqual(request.authenticated_userid, 'yo')
+
+
class TestEffectivePrincipals(unittest.TestCase):
def setUp(self):
testing.setUp()