summaryrefslogtreecommitdiff
path: root/repoze/bfg/router.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-05-24 23:12:59 +0000
committerChris McDonough <chrism@agendaless.com>2009-05-24 23:12:59 +0000
commit86ed4016ea6a681d4f579ace62cea032a679544d (patch)
tree697f67bbcb9e55e45db5d9aae52f0c3280e9b1e2 /repoze/bfg/router.py
parentab5959d3d4e4603a61b3559096da30d2adfdcf4b (diff)
downloadpyramid-86ed4016ea6a681d4f579ace62cea032a679544d.tar.gz
pyramid-86ed4016ea6a681d4f579ace62cea032a679544d.tar.bz2
pyramid-86ed4016ea6a681d4f579ace62cea032a679544d.zip
Features
-------- - It is now possible to write a custom security policy that returns a customized ``Forbidden`` WSGI application when BFG cannot authorize an invocation of a view. To this end, ISecurityPolicy objects must now have a ``forbidden`` method. This method should return a WSGI application. The returned WSGI application should generate a response which is appropriate when access to a view resource was forbidden by the security policy (e.g. perhaps a login page). ``repoze.bfg`` is willing to operate with a custom security policy that does not have a ``forbidden`` method, but it will issue a warning; eventually security policies without a ``forbidden`` method will cease to work under ``repoze.bfg``. Note that the ``forbidden`` WSGI application returned by the security policy is not used if a developer has registered an IForbiddenAppFactory (see the "Hooks" narrative chapter); the explicitly registered IForbiddenAppFactory will be preferred over the (more general) security policy forbidden app factory. - All default security policies now have a ``forbidden`` callable attached to them. This particular callable returns a WSGI application which generates a ``401 Unauthorized`` response for backwards compatibility (had backwards compatibility not been an issue, this callable would have returned a WSGI app that generated a ``403 Forbidden`` response). Backwards Incompatibilities --------------------------- - Custom NotFound and Forbidden (nee' Unauthorized) WSGI applications (registered a a utility for INotFoundAppFactory and IUnauthorizedAppFactory) could rely on an environment key named ``message`` describing the circumstance of the response. This key has been renamed to ``repoze.bfg.message`` (as per the WSGI spec, which requires environment extensions to contain dots). Deprecations ------------ - The ``repoze.bfg.interfaces.IUnauthorizedAppFactory`` interface has been renamed to ``repoze.bfg.interfaces.IForbiddenAppFactory``.
Diffstat (limited to 'repoze/bfg/router.py')
-rw-r--r--repoze/bfg/router.py46
1 files changed, 33 insertions, 13 deletions
diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py
index 81bc6e4ef..885a08184 100644
--- a/repoze/bfg/router.py
+++ b/repoze/bfg/router.py
@@ -17,7 +17,7 @@ from repoze.bfg.interfaces import IRouter
from repoze.bfg.interfaces import IRoutesMapper
from repoze.bfg.interfaces import ISecurityPolicy
from repoze.bfg.interfaces import ISettings
-from repoze.bfg.interfaces import IUnauthorizedAppFactory
+from repoze.bfg.interfaces import IForbiddenAppFactory
from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import IViewPermission
@@ -50,22 +50,40 @@ class Router(object):
def __init__(self, registry):
self.registry = registry
+ self.logger = registry.queryUtility(ILogger, 'repoze.bfg.debug')
self.request_factory = registry.queryUtility(IRequestFactory)
- self.security_policy = registry.queryUtility(ISecurityPolicy)
- self.notfound_app_factory = registry.queryUtility(
- INotFoundAppFactory,
- default=NotFound)
- self.unauth_app_factory = registry.queryUtility(
- IUnauthorizedAppFactory,
- default=Unauthorized)
+ security_policy = registry.queryUtility(ISecurityPolicy)
+
+ self.forbidden_app_factory = registry.queryUtility(IForbiddenAppFactory)
+ if security_policy is not None:
+ if hasattr(security_policy, 'forbidden'):
+ security_policy_forbidden = security_policy.forbidden
+ else:
+ security_policy_forbidden = Unauthorized
+ warning = ('You are running with a security policy (%s) which '
+ 'does not have a "forbidden" method; in BFG 0.8.2+ '
+ 'the ISecurityPolicy interface in the '
+ 'repoze.bfg.interfaces module defines this method '
+ 'as required; your application will not work under '
+ 'a future release of BFG if you continue using a '
+ 'security policy without a "forbidden" method.' %
+ security_policy)
+ self.logger and self.logger.warn(warning)
+ # allow a specifically-registered IForbiddenAppFactory to
+ # override the security policy's forbidden
+ self.forbidden_app_factory = (self.forbidden_app_factory or
+ security_policy_forbidden)
+
+ self.security_policy = security_policy
+ self.notfound_app_factory = registry.queryUtility(INotFoundAppFactory,
+ default=NotFound)
settings = registry.queryUtility(ISettings)
if settings is not None:
self.debug_authorization = settings.debug_authorization
self.debug_notfound = settings.debug_notfound
- self.logger = registry.queryUtility(ILogger, 'repoze.bfg.debug')
self.root_factory = registry.getUtility(IRootFactory)
self.root_policy = self.root_factory # b/w compat
self.traverser_warned = {}
@@ -144,14 +162,16 @@ class Router(object):
'context %r): %s' % (
request.url, view_name, context, permitted)
)
+
if not permitted:
if debug_authorization:
msg = str(permitted)
else:
msg = 'Unauthorized: failed security policy check'
- environ['message'] = msg
- unauth_app = self.unauth_app_factory()
- return unauth_app(environ, start_response)
+
+ environ['repoze.bfg.message'] = msg
+
+ return self.forbidden_app_factory()(environ, start_response)
response = registry.queryMultiAdapter(
(context, request), IView, name=view_name)
@@ -168,7 +188,7 @@ class Router(object):
logger and logger.debug(msg)
else:
msg = request.url
- environ['message'] = msg
+ environ['repoze.bfg.message'] = msg
notfound_app = self.notfound_app_factory()
return notfound_app(environ, start_response)