diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-05-25 01:56:39 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-05-25 01:56:39 +0000 |
| commit | 2cca10bbe326cca7b9b2573a972d751fcc1de403 (patch) | |
| tree | 62a6685e1bcec3ba634d060051b62a8747a7eaa6 | |
| parent | 70764fae4bf153a24974183af36fbb462db1799b (diff) | |
| download | pyramid-2cca10bbe326cca7b9b2573a972d751fcc1de403.tar.gz pyramid-2cca10bbe326cca7b9b2573a972d751fcc1de403.tar.bz2 pyramid-2cca10bbe326cca7b9b2573a972d751fcc1de403.zip | |
Make sure the default forbidden response (when a secpol has no ``forbidden``) works properly.
| -rw-r--r-- | repoze/bfg/router.py | 9 | ||||
| -rw-r--r-- | repoze/bfg/security.py | 79 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_router.py | 5 |
3 files changed, 57 insertions, 36 deletions
diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py index fdd5495fe..ac3bd53cd 100644 --- a/repoze/bfg/router.py +++ b/repoze/bfg/router.py @@ -31,13 +31,15 @@ from repoze.bfg.registry import populateRegistry from repoze.bfg.request import HTTP_METHOD_FACTORIES from repoze.bfg.request import Request +from repoze.bfg.security import _forbidden + from repoze.bfg.settings import Settings from repoze.bfg.urldispatch import RoutesRootFactory from repoze.bfg.traversal import _traverse from repoze.bfg.view import _view_execution_permitted -from repoze.bfg.wsgi import Unauthorized + from repoze.bfg.wsgi import NotFound _marker = object() @@ -55,6 +57,7 @@ class Router(object): self.request_factory = registry.queryUtility(IRequestFactory) security_policy = registry.queryUtility(ISecurityPolicy) + self.security_policy = security_policy unauthorized_app_factory = registry.queryUtility( IUnauthorizedAppFactory) @@ -86,7 +89,7 @@ class Router(object): if hasattr(security_policy, 'forbidden'): security_policy_forbidden = security_policy.forbidden else: - security_policy_forbidden = Unauthorized + security_policy_forbidden = _forbidden 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 ' @@ -101,9 +104,9 @@ class Router(object): self.forbidden_resp_factory = (self.forbidden_resp_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 diff --git a/repoze/bfg/security.py b/repoze/bfg/security.py index 14e6bd423..a05a74fbe 100644 --- a/repoze/bfg/security.py +++ b/repoze/bfg/security.py @@ -1,5 +1,5 @@ -from webob import Response from cgi import escape +from webob import Response from zope.component import queryUtility from zope.deprecation import deprecated @@ -80,11 +80,31 @@ def principals_allowed_by_permission(context, permission): return [Everyone] return policy.principals_allowed_by_permission(context, permission) +def _forbidden(context, request): + status = '401 Unauthorized' + try: + msg = escape(request.environ['repoze.bfg.message']) + except KeyError: + msg = '' + html = """ + <html> + <title>%s</title> + <body> + <h1>%s</h1> + <code>%s</code> + </body> + </html> + """ % (status, status, msg) + headers = [('Content-Length', str(len(html))), + ('Content-Type', 'text/html')] + response_factory = queryUtility(IResponseFactory, default=Response) + return response_factory(status = status, + headerlist = headers, + app_iter = [html]) + class ACLSecurityPolicy(object): implements(ISecurityPolicy) - forbidden_status = '401 Unauthorized' # b/c, should be 403 - def __init__(self, get_principals): self.get_principals = get_principals @@ -154,11 +174,7 @@ class ACLSecurityPolicy(object): return [] def forbidden(self, context, request): - body, headerlist = _forbidden_html(request, self.forbidden_status) - response_factory = queryUtility(IResponseFactory, default=Response) - return response_factory(status = self.forbidden_status, - headerlist = headerlist, - app_iter = body) + return _forbidden(context, request) class InheritingACLSecurityPolicy(object): """ A security policy which uses ACLs in the following ways: @@ -205,8 +221,6 @@ class InheritingACLSecurityPolicy(object): """ implements(ISecurityPolicy) - forbidden_status = '401 Unauthorized' # b/c, should be 403 - def __init__(self, get_principals): self.get_principals = get_principals @@ -286,11 +300,7 @@ class InheritingACLSecurityPolicy(object): return allowed def forbidden(self, context, request): - body, headerlist = _forbidden_html(request, self.forbidden_status) - response_factory = queryUtility(IResponseFactory, default=Response) - return response_factory(status = self.forbidden_status, - headerlist = headerlist, - app_iter = body) + return _forbidden(context, request) def get_remoteuser(request): user_id = request.environ.get('REMOTE_USER') @@ -507,6 +517,27 @@ def WhoInheritingACLSecurityPolicy(): """ return InheritingACLSecurityPolicy(get_who_principals) +## class StandaloneInheritingACLSecurityPolicy(InheritingACLSecurityPolicy): +## def __init__(self, get_principals, login_view_name='login_view', +## forbidden_view_name='forbidden_view'): +## self.get_principals = get_principals +## self.login_view_name = login_view_name +## self.forbidden_view_name = forbidden_view_name + +## def forbidden(self, context, request): +## from repoze.bfg.view import render_view_to_response +## from webob import Response + +## userid = self.authenticated_userid(request) + +## if userid is None: +## view_name = self.login_view_name +## else: +## view_name = self.forbidden_view_name + +## return render_view_to_response(context, request, name=view_name, +## secure=False) + class PermitsResult(int): def __new__(cls, s, *args): inst = int.__new__(cls, cls.boolval) @@ -619,21 +650,3 @@ class ViewPermissionFactory(object): class Unauthorized(Exception): pass -def _forbidden_html(request, status): - try: - msg = escape(request.environ['repoze.bfg.message']) - except KeyError: - msg = '' - html = """ - <html> - <title>%s</title> - <body> - <h1>%s</h1> - <code>%s</code> - </body> - </html> - """ % (status, status, msg) - headers = [('Content-Length', str(len(html))), - ('Content-Type', 'text/html')] - return [html], headers - diff --git a/repoze/bfg/tests/test_router.py b/repoze/bfg/tests/test_router.py index 1b76c0b7e..29ebf61d5 100644 --- a/repoze/bfg/tests/test_router.py +++ b/repoze/bfg/tests/test_router.py @@ -138,6 +138,11 @@ class RouterTests(unittest.TestCase): self.assertEqual(len(logger.messages), 1) self.failUnless('which does not have a "forbidden" method' in logger.messages[0]) + class DummyRequest: + environ = {} + req = DummyRequest() + resp = router.forbidden_resp_factory(None, req) + self.assertEqual(resp.status, '401 Unauthorized') def test_secpol_with_iunauthorized_appfactory(self): from repoze.bfg.interfaces import IUnauthorizedAppFactory |
