summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-08-15 03:01:51 -0400
committerChris McDonough <chrism@plope.com>2011-08-15 03:01:51 -0400
commit1a42bd45ad6dd066078d6d4997d33208b1bd0c63 (patch)
treea6b647e692576e4131f0dd883343233e4d1e033b
parentb2533554bb8816d412615595f4d7947f7779bf47 (diff)
downloadpyramid-1a42bd45ad6dd066078d6d4997d33208b1bd0c63.tar.gz
pyramid-1a42bd45ad6dd066078d6d4997d33208b1bd0c63.tar.bz2
pyramid-1a42bd45ad6dd066078d6d4997d33208b1bd0c63.zip
- New methods of the ``pyramid.config.Configurator`` class:
``set_authentication_policy`` and ``set_authorization_policy``. These are meant to be consumed mostly by add-on authors.
-rw-r--r--CHANGES.txt4
-rw-r--r--TODO.txt8
-rw-r--r--docs/api/config.rst4
-rw-r--r--pyramid/config.py67
-rw-r--r--pyramid/tests/permbugapp/__init__.py4
-rw-r--r--pyramid/tests/test_config.py69
-rw-r--r--pyramid/tests/test_integration.py12
7 files changed, 135 insertions, 33 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 1e7abc153..54a39b614 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -55,6 +55,10 @@ Features
- ``pyramid.testing.DummyRequest`` now implements the
``add_finished_callback`` and ``add_response_callback`` methods.
+- New methods of the ``pyramid.config.Configurator`` class:
+ ``set_authentication_policy`` and ``set_authorization_policy``. These are
+ meant to be consumed mostly by add-on authors.
+
Internal
--------
diff --git a/TODO.txt b/TODO.txt
index 6e908bdee..76e0784f2 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -6,18 +6,14 @@ Should-Have
- Name WSGI app "main" instead of pipeline in scaffold configs?
-- Turn off debugtoolbar redirect catcher in scaffolding (makes tutorials
- weird).
+- Make another release of debug toolbar (has now redirects turned off by
+ default so tutorials aren't weird).
- Mention debug toolbar in tutorials.
- Make it possible to use tween aliases in explicit tween config? If not,
the tween factories of all add-ons must be APIs.
-- Provide a way to set the authentication policy and the authorization policy
- during a config.include (they are related, so just exposing the currently
- underscored-private _set_auth* methods won't cut it).
-
- Merge Michael's route group work.
- Deprecate pyramid.security.view_execution_permitted (it only works for
diff --git a/docs/api/config.rst b/docs/api/config.rst
index 30c541905..de054d7ce 100644
--- a/docs/api/config.rst
+++ b/docs/api/config.rst
@@ -78,6 +78,10 @@
.. automethod:: set_view_mapper
+ .. automethod:: set_authentication_policy
+
+ .. automethod:: set_authorization_policy
+
.. automethod:: add_tween
.. automethod:: testing_securitypolicy
diff --git a/pyramid/config.py b/pyramid/config.py
index fc00e2ffa..950c90f00 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -353,22 +353,61 @@ class Configurator(object):
self.action(IRootFactory, register)
@action_method
+ def set_authentication_policy(self, policy):
+ """ Override the :app:`Pyramid` :term:`authentication policy` in the
+ current configuration. The ``policy`` argument must be an instance
+ of an authentication policy or a :term:`dotted Python name`
+ that points at an instance of an authentication policy.
+ """
+ self._set_authentication_policy(policy)
+ def ensure():
+ if self.autocommit:
+ return
+ if self.registry.queryUtility(IAuthorizationPolicy) is None:
+ raise ConfigurationError(
+ 'Cannot configure an authentication policy without '
+ 'also configuring an authorization policy '
+ '(see the set_authorization_policy method)')
+ self.action(IAuthenticationPolicy, callable=ensure)
+
+ @action_method
def _set_authentication_policy(self, policy):
- """ Add a :app:`Pyramid` :term:`authentication policy` to
- the current configuration."""
policy = self.maybe_dotted(policy)
self.registry.registerUtility(policy, IAuthenticationPolicy)
- self.action(IAuthenticationPolicy)
+
+ @action_method
+ def set_authorization_policy(self, policy):
+ """ Override the :app:`Pyramid` :term:`authorization policy` in the
+ current configuration. The ``policy`` argument must be an instance
+ of an authorization policy or a :term:`dotted Python name` that points
+ at an instance of an authorization policy.
+ """
+ self._set_authorization_policy(policy)
+ def ensure():
+ if self.registry.queryUtility(IAuthenticationPolicy) is None:
+ raise ConfigurationError(
+ 'Cannot configure an authorization policy without also '
+ 'configuring an authentication policy '
+ '(see the set_authentication_policy method)')
+ self.action(IAuthorizationPolicy, callable=ensure)
@action_method
def _set_authorization_policy(self, policy):
- """ Add a :app:`Pyramid` :term:`authorization policy` to
- the current configuration state (also accepts a :term:`dotted
- Python name`."""
policy = self.maybe_dotted(policy)
self.registry.registerUtility(policy, IAuthorizationPolicy)
- self.action(IAuthorizationPolicy, None)
-
+
+ @action_method
+ def _set_security_policies(self, authentication, authorization=None):
+ if (authorization is not None) and (not authentication):
+ raise ConfigurationError(
+ 'If the "authorization" is passed a value, '
+ 'the "authentication" argument must also be '
+ 'passed a value; authorization requires authentication.')
+ if authorization is None:
+ authorization = ACLAuthorizationPolicy() # default
+ self._set_authentication_policy(authentication)
+ self._set_authorization_policy(authorization)
+
def _make_spec(self, path_or_spec):
package, filename = resolve_asset_spec(path_or_spec,
self.package_name)
@@ -414,18 +453,6 @@ class Configurator(object):
return deriver(view)
- @action_method
- def _set_security_policies(self, authentication, authorization=None):
- if (authorization is not None) and (not authentication):
- raise ConfigurationError(
- 'If the "authorization" is passed a value, '
- 'the "authentication" argument must also be '
- 'passed a value; authorization requires authentication.')
- if authorization is None:
- authorization = ACLAuthorizationPolicy() # default
- self._set_authentication_policy(authentication)
- self._set_authorization_policy(authorization)
-
def _fix_registry(self):
""" Fix up a ZCA component registry that is not a
pyramid.registry.Registry by adding analogues of ``has_listeners``,
diff --git a/pyramid/tests/permbugapp/__init__.py b/pyramid/tests/permbugapp/__init__.py
index fe90c716d..10a244f3b 100644
--- a/pyramid/tests/permbugapp/__init__.py
+++ b/pyramid/tests/permbugapp/__init__.py
@@ -16,7 +16,7 @@ def includeme(config):
from pyramid.authorization import ACLAuthorizationPolicy
authn_policy = AuthTktAuthenticationPolicy('seekt1t')
authz_policy = ACLAuthorizationPolicy()
- config._set_authentication_policy(authn_policy)
- config._set_authorization_policy(authz_policy)
+ config.set_authentication_policy(authn_policy)
+ config.set_authorization_policy(authz_policy)
config.add_view(test, name='test')
config.add_view(x_view, name='x', permission='private')
diff --git a/pyramid/tests/test_config.py b/pyramid/tests/test_config.py
index 921f5ec84..b222a398a 100644
--- a/pyramid/tests/test_config.py
+++ b/pyramid/tests/test_config.py
@@ -2730,21 +2730,80 @@ pyramid.tests.test_config.dummy_include2""",
config.end()
self.assertTrue('div' in result.body)
- def test__set_authentication_policy(self):
+ def test_set_authentication_policy_no_authz_policy(self):
+ from zope.configuration.config import ConfigurationExecutionError
+ config = self._makeOne()
+ policy = object()
+ config.set_authentication_policy(policy)
+ self.assertRaises(ConfigurationExecutionError, config.commit)
+
+ def test_set_authentication_policy_no_authz_policy_autocommit(self):
from pyramid.interfaces import IAuthenticationPolicy
config = self._makeOne(autocommit=True)
policy = object()
- config._set_authentication_policy(policy)
+ config.set_authentication_policy(policy)
self.assertEqual(
config.registry.getUtility(IAuthenticationPolicy), policy)
- def test__set_authorization_policy(self):
+ def test_set_authentication_policy_with_authz_policy(self):
+ from pyramid.interfaces import IAuthenticationPolicy
+ from pyramid.interfaces import IAuthorizationPolicy
+ config = self._makeOne()
+ authn_policy = object()
+ authz_policy = object()
+ config.registry.registerUtility(authz_policy, IAuthorizationPolicy)
+ config.set_authentication_policy(authn_policy)
+ config.commit()
+ self.assertEqual(
+ config.registry.getUtility(IAuthenticationPolicy), authn_policy)
+
+ def test_set_authentication_policy_with_authz_policy_autocommit(self):
+ from pyramid.interfaces import IAuthenticationPolicy
from pyramid.interfaces import IAuthorizationPolicy
config = self._makeOne(autocommit=True)
+ authn_policy = object()
+ authz_policy = object()
+ config.registry.registerUtility(authz_policy, IAuthorizationPolicy)
+ config.set_authentication_policy(authn_policy)
+ config.commit()
+ self.assertEqual(
+ config.registry.getUtility(IAuthenticationPolicy), authn_policy)
+
+ def test_set_authorization_policy_no_authn_policy(self):
+ from zope.configuration.config import ConfigurationExecutionError
+ config = self._makeOne()
+ policy = object()
+ config.set_authorization_policy(policy)
+ self.assertRaises(ConfigurationExecutionError, config.commit)
+
+ def test_set_authorization_policy_no_authn_policy_autocommit(self):
+ from pyramid.exceptions import ConfigurationError
+ config = self._makeOne(autocommit=True)
policy = object()
- config._set_authorization_policy(policy)
+ self.assertRaises(ConfigurationError,
+ config.set_authorization_policy, policy)
+
+ def test_set_authorization_policy_with_authn_policy(self):
+ from pyramid.interfaces import IAuthorizationPolicy
+ from pyramid.interfaces import IAuthenticationPolicy
+ config = self._makeOne()
+ authn_policy = object()
+ authz_policy = object()
+ config.registry.registerUtility(authn_policy, IAuthenticationPolicy)
+ config.set_authorization_policy(authz_policy)
+ self.assertEqual(
+ config.registry.getUtility(IAuthorizationPolicy), authz_policy)
+
+ def test_set_authorization_policy_with_authn_policy_autocommit(self):
+ from pyramid.interfaces import IAuthorizationPolicy
+ from pyramid.interfaces import IAuthenticationPolicy
+ config = self._makeOne(autocommit=True)
+ authn_policy = object()
+ authz_policy = object()
+ config.registry.registerUtility(authn_policy, IAuthenticationPolicy)
+ config.set_authorization_policy(authz_policy)
self.assertEqual(
- config.registry.getUtility(IAuthorizationPolicy), policy)
+ config.registry.getUtility(IAuthorizationPolicy), authz_policy)
def test_set_locale_negotiator(self):
from pyramid.interfaces import ILocaleNegotiator
diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py
index 1ebf83062..a9fb80d6f 100644
--- a/pyramid/tests/test_integration.py
+++ b/pyramid/tests/test_integration.py
@@ -297,6 +297,18 @@ class TestViewPermissionBug(IntegrationBase):
class TestDefaultViewPermissionBug(IntegrationBase):
# default_view_permission bug as reported by Wiggy at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003602.html
package = 'pyramid.tests.defpermbugapp'
+ def setUp(self):
+ from pyramid.config import Configurator
+ config = Configurator(root_factory=self.root_factory,
+ package=self.package)
+ config.begin()
+ config.include(self.package)
+ config.commit()
+ app = config.make_wsgi_app()
+ from webtest import TestApp
+ self.testapp = TestApp(app)
+ self.config = config
+
def test_x(self):
res = self.testapp.get('/x', status=403)
self.assertTrue('failed permission check' in res.body)