summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-05-25 01:56:39 +0000
committerChris McDonough <chrism@agendaless.com>2009-05-25 01:56:39 +0000
commit2cca10bbe326cca7b9b2573a972d751fcc1de403 (patch)
tree62a6685e1bcec3ba634d060051b62a8747a7eaa6
parent70764fae4bf153a24974183af36fbb462db1799b (diff)
downloadpyramid-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.py9
-rw-r--r--repoze/bfg/security.py79
-rw-r--r--repoze/bfg/tests/test_router.py5
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