From a1a9fb7128c935848b17c0ce6586991098a17f07 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 27 May 2009 04:52:51 +0000 Subject: Merge authchanges branch to trunk. --- repoze/bfg/tests/test_authentication.py | 176 +++++++ repoze/bfg/tests/test_authorization.py | 179 +++++++ repoze/bfg/tests/test_integration.py | 7 +- repoze/bfg/tests/test_registry.py | 64 +-- repoze/bfg/tests/test_router.py | 433 +++++++++++----- repoze/bfg/tests/test_secpols.py | 766 +++++++++++++++++++++++++++ repoze/bfg/tests/test_security.py | 890 +++++++++----------------------- repoze/bfg/tests/test_testing.py | 100 ++-- repoze/bfg/tests/test_threadlocal.py | 46 ++ repoze/bfg/tests/test_view.py | 125 +---- repoze/bfg/tests/test_wsgi.py | 4 +- 11 files changed, 1762 insertions(+), 1028 deletions(-) create mode 100644 repoze/bfg/tests/test_authentication.py create mode 100644 repoze/bfg/tests/test_authorization.py create mode 100644 repoze/bfg/tests/test_secpols.py create mode 100644 repoze/bfg/tests/test_threadlocal.py (limited to 'repoze/bfg/tests') diff --git a/repoze/bfg/tests/test_authentication.py b/repoze/bfg/tests/test_authentication.py new file mode 100644 index 000000000..a23ffeac2 --- /dev/null +++ b/repoze/bfg/tests/test_authentication.py @@ -0,0 +1,176 @@ +import unittest + +class TestRepozeWho1AuthenticationPolicy(unittest.TestCase): + def _getTargetClass(self): + from repoze.bfg.authentication import RepozeWho1AuthenticationPolicy + return RepozeWho1AuthenticationPolicy + + def _makeOne(self): + return self._getTargetClass()() + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from repoze.bfg.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import IAuthenticationPolicy + verifyObject(IAuthenticationPolicy, self._makeOne()) + + def test_authenticated_userid_None(self): + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(context, request), None) + + def test_authenticated_userid(self): + context = DummyContext() + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(context, request), 'fred') + + def test_effective_principals_None(self): + from repoze.bfg.security import Everyone + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(context, request), + [Everyone]) + + def test_effective_principals_userid_only(self): + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + context = DummyContext() + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(context, request), + [Everyone, Authenticated, 'fred']) + + def test_effective_principals_userid_and_groups(self): + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + context = DummyContext() + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred', + 'groups':['quux', 'biz']}}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(context, request), + [Everyone, Authenticated, 'fred', 'quux', 'biz']) + + def test_remember_no_plugins(self): + context = DummyContext() + authtkt = DummyPlugin() + request = DummyRequest({}) + policy = self._makeOne() + result = policy.remember(context, request, 'fred') + self.assertEqual(result, []) + + def test_remember(self): + context = DummyContext() + authtkt = DummyPlugin() + request = DummyRequest( + {'repoze.who.plugins':{'auth_tkt':authtkt}}) + policy = self._makeOne() + result = policy.remember(context, request, 'fred') + self.assertEqual(result[0], request.environ) + self.assertEqual(result[1], {'repoze.who.userid':'fred'}) + + def test_forget_no_plugins(self): + context = DummyContext() + authtkt = DummyPlugin() + request = DummyRequest({}) + policy = self._makeOne() + result = policy.forget(context, request) + self.assertEqual(result, []) + + def test_forget(self): + context = DummyContext() + authtkt = DummyPlugin() + request = DummyRequest( + {'repoze.who.plugins':{'auth_tkt':authtkt}, + 'repoze.who.identity':{'repoze.who.userid':'fred'}, + }) + policy = self._makeOne() + result = policy.forget(context, request) + self.assertEqual(result[0], request.environ) + self.assertEqual(result[1], request.environ['repoze.who.identity']) + +class TestRemoteUserAuthenticationPolicy(unittest.TestCase): + def _getTargetClass(self): + from repoze.bfg.authentication import RemoteUserAuthenticationPolicy + return RemoteUserAuthenticationPolicy + + def _makeOne(self): + return self._getTargetClass()() + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from repoze.bfg.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import IAuthenticationPolicy + verifyObject(IAuthenticationPolicy, self._makeOne()) + + def test_authenticated_userid_None(self): + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(context, request), None) + + def test_authenticated_userid(self): + context = DummyContext() + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(context, request), 'fred') + + def test_effective_principals_None(self): + from repoze.bfg.security import Everyone + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(context, request), + [Everyone]) + + def test_effective_principals(self): + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + context = DummyContext() + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(context, request), + [Everyone, Authenticated, 'fred']) + + def test_remember(self): + context = DummyContext() + authtkt = DummyPlugin() + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + result = policy.remember(context, request, 'fred') + self.assertEqual(result, []) + + def test_forget(self): + context = DummyContext() + authtkt = DummyPlugin() + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + result = policy.forget(context, request) + self.assertEqual(result, []) + +class DummyContext: + pass + +class DummyRequest: + def __init__(self, environ): + self.environ = environ + +class DummyPlugin: + def remember(self, environ, identity): + return environ, identity + + def forget(self, environ, identity): + return environ, identity diff --git a/repoze/bfg/tests/test_authorization.py b/repoze/bfg/tests/test_authorization.py new file mode 100644 index 000000000..8aa9b9abf --- /dev/null +++ b/repoze/bfg/tests/test_authorization.py @@ -0,0 +1,179 @@ +import unittest + +from repoze.bfg.testing import cleanUp + +class TestACLAuthorizationPolicy(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from repoze.bfg.authorization import ACLAuthorizationPolicy + return ACLAuthorizationPolicy + + def _makeOne(self): + return self._getTargetClass()() + + def test_class_implements_IAuthorizationPolicy(self): + from zope.interface.verify import verifyClass + from repoze.bfg.interfaces import IAuthorizationPolicy + verifyClass(IAuthorizationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthorizationPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import IAuthorizationPolicy + verifyObject(IAuthorizationPolicy, self._makeOne()) + + def test_permits_no_acl(self): + context = DummyContext() + policy = self._makeOne() + self.assertEqual(policy.permits(context, [], 'view'), False) + + def test_permits(self): + from repoze.bfg.security import Deny + from repoze.bfg.security import Allow + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + from repoze.bfg.security import ALL_PERMISSIONS + from repoze.bfg.security import DENY_ALL + root = DummyContext() + community = DummyContext(__name__='community', __parent__=root) + blog = DummyContext(__name__='blog', __parent__=community) + root.__acl__ = [ + (Allow, Authenticated, VIEW), + ] + community.__acl__ = [ + (Allow, 'fred', ALL_PERMISSIONS), + (Allow, 'wilma', VIEW), + DENY_ALL, + ] + blog.__acl__ = [ + (Allow, 'barney', MEMBER_PERMS), + (Allow, 'wilma', VIEW), + ] + + policy = self._makeOne() + + result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], + 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, blog) + self.assertEqual(result.ace, (Allow, 'wilma', VIEW)) + + result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], + 'delete') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + + result = policy.permits(blog, [Everyone, Authenticated, 'fred'], 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) + result = policy.permits(blog, [Everyone, Authenticated, 'fred'], + 'doesntevenexistyet') + self.assertEqual(result, True) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) + + result = policy.permits(blog, [Everyone, Authenticated, 'barney'], + 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, blog) + self.assertEqual(result.ace, (Allow, 'barney', MEMBER_PERMS)) + result = policy.permits(blog, [Everyone, Authenticated, 'barney'], + 'administer') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + + result = policy.permits(root, [Everyone, Authenticated, 'someguy'], + 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, root) + self.assertEqual(result.ace, (Allow, Authenticated, VIEW)) + result = policy.permits(blog, + [Everyone, Authenticated, 'someguy'], 'view') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + + result = policy.permits(root, [Everyone], 'view') + self.assertEqual(result, False) + self.assertEqual(result.context, root) + self.assertEqual(result.ace, None) + + context = DummyContext() + result = policy.permits(context, [Everyone], 'view') + self.assertEqual(result, False) + + def test_principals_allowed_by_permission_direct(self): + from repoze.bfg.security import Allow + from repoze.bfg.security import DENY_ALL + context = DummyContext() + acl = [ (Allow, 'chrism', ('read', 'write')), + DENY_ALL, + (Allow, 'other', 'read') ] + context.__acl__ = acl + policy = self._makeOne() + result = sorted( + policy.principals_allowed_by_permission(context, 'read')) + self.assertEqual(result, ['chrism']) + + def test_principals_allowed_by_permission(self): + from repoze.bfg.security import Allow + from repoze.bfg.security import Deny + from repoze.bfg.security import DENY_ALL + from repoze.bfg.security import ALL_PERMISSIONS + root = DummyContext(__name__='', __parent__=None) + community = DummyContext(__name__='community', __parent__=root) + blog = DummyContext(__name__='blog', __parent__=community) + root.__acl__ = [ (Allow, 'chrism', ('read', 'write')), + (Allow, 'other', ('read',)), + (Allow, 'jim', ALL_PERMISSIONS)] + community.__acl__ = [ (Deny, 'flooz', 'read'), + (Allow, 'flooz', 'read'), + (Allow, 'mork', 'read'), + (Deny, 'jim', 'read'), + (Allow, 'someguy', 'manage')] + blog.__acl__ = [ (Allow, 'fred', 'read'), + DENY_ALL] + + policy = self._makeOne() + + result = sorted(policy.principals_allowed_by_permission(blog, 'read')) + self.assertEqual(result, ['fred']) + result = sorted(policy.principals_allowed_by_permission(community, + 'read')) + self.assertEqual(result, ['chrism', 'mork', 'other']) + result = sorted(policy.principals_allowed_by_permission(community, + 'read')) + result = sorted(policy.principals_allowed_by_permission(root, 'read')) + self.assertEqual(result, ['chrism', 'jim', 'other']) + + def test_principals_allowed_by_permission_no_acls(self): + context = DummyContext() + policy = self._makeOne() + result = sorted(policy.principals_allowed_by_permission(context,'read')) + self.assertEqual(result, []) + +class DummyContext: + def __init__(self, *arg, **kw): + self.__dict__.update(kw) + + +VIEW = 'view' +EDIT = 'edit' +CREATE = 'create' +DELETE = 'delete' +MODERATE = 'moderate' +ADMINISTER = 'administer' +COMMENT = 'comment' + +GUEST_PERMS = (VIEW, COMMENT) +MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE) +MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,) +ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,) + diff --git a/repoze/bfg/tests/test_integration.py b/repoze/bfg/tests/test_integration.py index fdb85b87e..3630a2778 100644 --- a/repoze/bfg/tests/test_integration.py +++ b/repoze/bfg/tests/test_integration.py @@ -120,7 +120,7 @@ class TestFixtureApp(unittest.TestCase): def tearDown(self): cleanUp() - def test_registry_actions_can_be_pickled_and_unpickled(self): + def test_execute_actions(self): import repoze.bfg.tests.fixtureapp as package from zope.configuration import config from zope.configuration import xmlconfig @@ -129,11 +129,6 @@ class TestFixtureApp(unittest.TestCase): context.package = package xmlconfig.include(context, 'configure.zcml', package) context.execute_actions(clear=False) - actions = context.actions - import cPickle - dumped = cPickle.dumps(actions, -1) - new = cPickle.loads(dumped) - self.assertEqual(len(actions), len(new)) class TestGrokkedApp(unittest.TestCase): def setUp(self): diff --git a/repoze/bfg/tests/test_registry.py b/repoze/bfg/tests/test_registry.py index 77031806f..d145e7700 100644 --- a/repoze/bfg/tests/test_registry.py +++ b/repoze/bfg/tests/test_registry.py @@ -53,10 +53,10 @@ class TestPopulateRegistry(unittest.TestCase): def test_it(self): from repoze.bfg.tests import fixtureapp dummylock = DummyLock() - dummyregmgr = DummyRegistrationManager() - import repoze.bfg.registry + dummyregmgr = DummyThreadLocalManager({'registry':None}) + import repoze.bfg.threadlocal try: - old = repoze.bfg.registry.setRegistryManager(dummyregmgr) + old = repoze.bfg.threadlocal.setManager(dummyregmgr) from zope.component.registry import Components registry = Components('hello') self._callFUT(registry, @@ -65,49 +65,9 @@ class TestPopulateRegistry(unittest.TestCase): lock=dummylock) self.assertEqual(dummylock.acquired, True) self.assertEqual(dummylock.released, True) - self.assertEqual(dummyregmgr.registry, registry) + self.assertEqual(dummyregmgr.data['registry'], None) finally: - repoze.bfg.registry.setRegistryManager(old) - -class TestThreadLocalRegistryManager(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.registry import ThreadLocalRegistryManager - return ThreadLocalRegistryManager - - def _makeOne(self): - return self._getTargetClass()() - - def test_init(self): - local = self._makeOne() - from zope.component import getGlobalSiteManager - self.assertEqual(local.stack, []) - self.assertEqual(local.get(), getGlobalSiteManager()) - - def test_push_and_pop(self): - local = self._makeOne() - from zope.component import getGlobalSiteManager - local.push(True) - self.assertEqual(local.get(), True) - self.assertEqual(local.pop(), True) - self.assertEqual(local.pop(), None) - self.assertEqual(local.get(), getGlobalSiteManager()) - - def test_set_get_and_clear(self): - local = self._makeOne() - from zope.component import getGlobalSiteManager - local.set(None) - self.assertEqual(local.stack, [None]) - self.assertEqual(local.get(), None) - local.clear() - self.assertEqual(local.get(), getGlobalSiteManager()) - local.clear() - self.assertEqual(local.get(), getGlobalSiteManager()) + repoze.bfg.threadlocal.setManager(old) class GetSiteManagerTests(unittest.TestCase): def _callFUT(self, context=None): @@ -122,16 +82,10 @@ class GetSiteManagerTests(unittest.TestCase): from zope.component.interfaces import ComponentLookupError self.assertRaises(ComponentLookupError, self._callFUT, object) -class DummyRegistrationManager: - def push(self, registry): - self.registry = registry - - def pop(self): - self.popped = True - - def get(self): - return self.registry - +class DummyThreadLocalManager: + def __init__(self, data): + self.data = data + class DummyLock: def acquire(self): self.acquired = True diff --git a/repoze/bfg/tests/test_router.py b/repoze/bfg/tests/test_router.py index db47f832e..9a29967a3 100644 --- a/repoze/bfg/tests/test_router.py +++ b/repoze/bfg/tests/test_router.py @@ -16,14 +16,7 @@ class RouterTests(unittest.TestCase): def _registerLogger(self): from repoze.bfg.interfaces import ILogger - class Logger: - def __init__(self): - self.messages = [] - def info(self, msg): - self.messages.append(msg) - warn = info - debug = info - logger = Logger() + logger = DummyLogger() self.registry.registerUtility(logger, ILogger, name='repoze.bfg.debug') return logger @@ -38,6 +31,12 @@ class RouterTests(unittest.TestCase): settings = Settings(**defaultkw) self.registry.registerUtility(settings, ISettings) + def _registerAuthenticationPolicy(self): + from repoze.bfg.interfaces import IAuthenticationPolicy + policy = DummyAuthenticationPolicy() + self.registry.registerUtility(policy, IAuthenticationPolicy) + return policy + def _registerTraverserFactory(self, context, view_name='', subpath=None, traversed=None, virtual_root=None, virtual_root_path=None, **kw): @@ -74,13 +73,19 @@ class RouterTests(unittest.TestCase): from repoze.bfg.interfaces import IView self.registry.registerAdapter(app, for_, IView, name) - def _registerPermission(self, permission, name, *for_): + def _registerViewPermission(self, view_name, allow=True): + from zope.interface import Interface from repoze.bfg.interfaces import IViewPermission - self.registry.registerAdapter(permission, for_, IViewPermission, name) - - def _registerSecurityPolicy(self, secpol): - from repoze.bfg.interfaces import ISecurityPolicy - self.registry.registerUtility(secpol, ISecurityPolicy) + class Checker(object): + def __call__(self, context, request): + self.context = context + self.request = request + return allow + checker = Checker() + self.registry.registerAdapter(checker, (Interface, Interface), + IViewPermission, + view_name) + return checker def _registerEventListener(self, iface): L = [] @@ -89,9 +94,11 @@ class RouterTests(unittest.TestCase): self.registry.registerHandler(listener, (iface,)) return L - def _registerRootFactory(self, root_factory): + def _registerRootFactory(self, val): + rootfactory = make_rootfactory(val) from repoze.bfg.interfaces import IRootFactory - self.registry.registerUtility(root_factory, IRootFactory) + self.registry.registerUtility(rootfactory, IRootFactory) + return rootfactory def _getTargetClass(self): from repoze.bfg.router import Router @@ -113,21 +120,63 @@ class RouterTests(unittest.TestCase): return environ def test_root_policy(self): - rootfactory = make_rootfactory(None) environ = self._makeEnviron() context = DummyContext() self._registerTraverserFactory(context) - self._registerRootFactory(rootfactory) + rootfactory = self._registerRootFactory(None) router = self._makeOne() self.assertEqual(router.root_policy, rootfactory) + def test_inotfound_appfactory_override(self): + from repoze.bfg.interfaces import INotFoundAppFactory + def app(): + """ """ + self.registry.registerUtility(app, INotFoundAppFactory) + self._registerRootFactory(None) + router = self._makeOne() + self.assertEqual(router.notfound_app_factory, app) + + def test_iforbidden_responsefactory_override(self): + from repoze.bfg.interfaces import IForbiddenResponseFactory + def app(): + """ """ + self.registry.registerUtility(app, IForbiddenResponseFactory) + self._registerRootFactory(None) + router = self._makeOne() + self.assertEqual(router.forbidden_resp_factory, app) + + def test_iforbidden_responsefactory_nooverride(self): + context = DummyContext() + self._registerRootFactory(None) + router = self._makeOne() + from repoze.bfg.router import default_forbidden_view + self.assertEqual(router.forbidden_resp_factory, default_forbidden_view) + + def test_secpol_with_iunauthorized_appfactory(self): + from repoze.bfg.interfaces import IUnauthorizedAppFactory + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context) + rootfactory = self._registerRootFactory(None) + logger = self._registerLogger() + def factory(): + return 'yo' + self.registry.registerUtility(factory, IUnauthorizedAppFactory) + router = self._makeOne() + self.assertEqual(len(logger.messages), 1) + self.failUnless('IForbiddenResponseFactory' in logger.messages[0]) + class DummyRequest: + def get_response(self, app): + return app + req = DummyRequest() + self.assertEqual(router.forbidden_resp_factory(None, req), 'yo') + def test_call_no_view_registered_no_isettings(self): - rootfactory = make_rootfactory(None) environ = self._makeEnviron() context = DummyContext() self._registerTraverserFactory(context) logger = self._registerLogger() - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) @@ -148,8 +197,7 @@ class RouterTests(unittest.TestCase): self._registerTraverserFactory(context) environ = self._makeEnviron() start_response = DummyStartResponse() - rootfactory = make_rootfactory(NotFound()) - self._registerRootFactory(rootfactory) + self._registerRootFactory(NotFound()) router = self._makeOne() result = router(environ, start_response) status = start_response.status @@ -157,13 +205,12 @@ class RouterTests(unittest.TestCase): self.failUnless('http://localhost:8080' in result[0], result) def test_call_no_view_registered_debug_notfound_false(self): - rootfactory = make_rootfactory(None) environ = self._makeEnviron() context = DummyContext() self._registerTraverserFactory(context) logger = self._registerLogger() self._registerSettings(debug_notfound=False) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) @@ -176,13 +223,12 @@ class RouterTests(unittest.TestCase): self.assertEqual(len(logger.messages), 0) def test_call_no_view_registered_debug_notfound_true(self): - rootfactory = make_rootfactory(None) environ = self._makeEnviron() context = DummyContext() self._registerTraverserFactory(context) self._registerSettings(debug_notfound=True) logger = self._registerLogger() - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) @@ -205,19 +251,17 @@ class RouterTests(unittest.TestCase): self.failUnless("subpath: []" in message) def test_call_view_returns_nonresponse(self): - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context) environ = self._makeEnviron() view = make_view('abc') self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() self.assertRaises(ValueError, router, environ, start_response) def test_call_view_registered_nonspecific_default_path(self): - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context) response = DummyResponse() @@ -225,7 +269,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron() self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) @@ -238,7 +282,6 @@ class RouterTests(unittest.TestCase): self.assertEqual(environ['webob.adhoc_attrs']['root'], None) def test_call_deprecation_warning(self): - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context, _deprecation_warning='abc') response = DummyResponse() @@ -246,7 +289,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron() self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() logger = self._registerLogger() router.logger = logger @@ -256,7 +299,6 @@ class RouterTests(unittest.TestCase): self.assertEqual(logger.messages[0], 'abc') def test_call_view_registered_nonspecific_nondefault_path_and_subpath(self): - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context, view_name='foo', subpath=['bar'], @@ -266,7 +308,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron() self._registerView(view, 'foo', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) @@ -279,7 +321,6 @@ class RouterTests(unittest.TestCase): self.assertEqual(environ['webob.adhoc_attrs']['root'], None) def test_call_view_registered_specific_success(self): - rootfactory = make_rootfactory(None) from zope.interface import Interface from zope.interface import directlyProvides class IContext(Interface): @@ -293,7 +334,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron() self._registerView(view, '', IContext, IRequest) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) @@ -306,7 +347,6 @@ class RouterTests(unittest.TestCase): self.assertEqual(environ['webob.adhoc_attrs']['root'], None) def test_call_view_registered_specific_fail(self): - rootfactory = make_rootfactory(None) from zope.interface import Interface from zope.interface import directlyProvides class IContext(Interface): @@ -321,15 +361,14 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron() self._registerView(view, '', IContext, IRequest) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) self.assertEqual(start_response.status, '404 Not Found') self.failUnless('404' in result[0]) - def test_call_view_registered_security_policy_permission_none(self): - rootfactory = make_rootfactory(None) + def test_call_view_permission_none(self): from zope.interface import Interface from zope.interface import directlyProvides class IContext(Interface): @@ -342,16 +381,14 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron() self._registerView(view, '', IContext, IRequest) - secpol = DummySecurityPolicy() - self._registerSecurityPolicy(secpol) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) self.assertEqual(start_response.status, '200 OK') - def test_call_view_registered_security_policy_permission_succeeds(self): - rootfactory = make_rootfactory(None) + def test_call_view_no_authentication_policy_debug_authorization(self): + logger = self._registerLogger() from zope.interface import Interface from zope.interface import directlyProvides class IContext(Interface): @@ -362,21 +399,87 @@ class RouterTests(unittest.TestCase): self._registerTraverserFactory(context, subpath=['']) response = DummyResponse() view = make_view(response) - secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(True) environ = self._makeEnviron() self._registerView(view, '', IContext, IRequest) - self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, '', IContext, IRequest) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() + router.debug_authorization = True start_response = DummyStartResponse() result = router(environ, start_response) self.assertEqual(start_response.status, '200 OK') - self.assertEqual(permissionfactory.checked_with, secpol) + self.assertEqual(len(logger.messages), 1) + self.failUnless('no authentication policy' in logger.messages[0]) + + def test_call_view_no_permission_registered_debug_authorization(self): + self._registerAuthenticationPolicy() + logger = self._registerLogger() + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from repoze.bfg.interfaces import IRequest + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse() + view = make_view(response) + environ = self._makeEnviron() + self._registerView(view, '', IContext, IRequest) + self._registerRootFactory(None) + router = self._makeOne() + router.debug_authorization = True + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(start_response.status, '200 OK') + self.assertEqual(len(logger.messages), 1) + self.failUnless('no permission registered' in logger.messages[0]) + + def test_call_view_no_permission_registered_no_debug(self): + self._registerAuthenticationPolicy() + logger = self._registerLogger() + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from repoze.bfg.interfaces import IRequest + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse() + view = make_view(response) + environ = self._makeEnviron() + self._registerView(view, '', IContext, IRequest) + self._registerRootFactory(None) + router = self._makeOne() + router.debug_authorization = False + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(start_response.status, '200 OK') + self.assertEqual(len(logger.messages), 0) + + def test_call_view_permission_succeeds(self): + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from repoze.bfg.interfaces import IRequest + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + self._registerAuthenticationPolicy() + response = DummyResponse() + view = make_view(response) + environ = self._makeEnviron() + self._registerView(view, '', IContext, IRequest) + checker = self._registerViewPermission('', True) + self._registerRootFactory(None) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(start_response.status, '200 OK') + self.assertEqual(checker.context, context) def test_call_view_permission_fails_nosettings(self): - rootfactory = make_rootfactory(None) from zope.interface import Interface from zope.interface import directlyProvides class IContext(Interface): @@ -385,28 +488,24 @@ class RouterTests(unittest.TestCase): context = DummyContext() directlyProvides(context, IContext) self._registerTraverserFactory(context, subpath=['']) + self._registerAuthenticationPolicy() response = DummyResponse() view = make_view(response) - secpol = DummySecurityPolicy() from repoze.bfg.security import ACLDenied - permissionfactory = make_permission_factory( - ACLDenied('ace', 'acl', 'permission', ['principals'], context) - ) + denied = ACLDenied('ace', 'acl', 'permission', ['principals'], context) environ = self._makeEnviron() self._registerView(view, '', IContext, IRequest) - self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, '', IContext, IRequest) - self._registerRootFactory(rootfactory) + checker = self._registerViewPermission('', denied) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) self.assertEqual(start_response.status, '401 Unauthorized') - message = result[0] - self.failUnless('failed security policy check' in message) - self.assertEqual(permissionfactory.checked_with, secpol) + message = environ['repoze.bfg.message'] + self.assertEqual(message, 'Unauthorized: failed security policy check') + self.assertEqual(checker.context, context) def test_call_view_permission_fails_no_debug_auth(self): - rootfactory = make_rootfactory(None) from zope.interface import Interface from zope.interface import directlyProvides class IContext(Interface): @@ -415,29 +514,25 @@ class RouterTests(unittest.TestCase): context = DummyContext() directlyProvides(context, IContext) self._registerTraverserFactory(context, subpath=['']) + self._registerAuthenticationPolicy() response = DummyResponse() view = make_view(response) - secpol = DummySecurityPolicy() from repoze.bfg.security import ACLDenied - permissionfactory = make_permission_factory( - ACLDenied('ace', 'acl', 'permission', ['principals'], context) - ) + denied = ACLDenied('ace', 'acl', 'permission', ['principals'], context) environ = self._makeEnviron() self._registerView(view, '', IContext, IRequest) - self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, '', IContext, IRequest) + checker = self._registerViewPermission('', denied) self._registerSettings(debug_authorization=False) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) self.assertEqual(start_response.status, '401 Unauthorized') - message = result[0] + message = environ['repoze.bfg.message'] self.failUnless('failed security policy check' in message) - self.assertEqual(permissionfactory.checked_with, secpol) + self.assertEqual(checker.context, context) def test_call_view_permission_fails_with_debug_auth(self): - rootfactory = make_rootfactory(None) from zope.interface import Interface from zope.interface import directlyProvides class IContext(Interface): @@ -445,31 +540,28 @@ class RouterTests(unittest.TestCase): from repoze.bfg.interfaces import IRequest context = DummyContext() directlyProvides(context, IContext) + self._registerAuthenticationPolicy() self._registerTraverserFactory(context, subpath=['']) response = DummyResponse() view = make_view(response) - secpol = DummySecurityPolicy() from repoze.bfg.security import ACLDenied - permissionfactory = make_permission_factory( - ACLDenied('ace', 'acl', 'permission', ['principals'], context) - ) environ = self._makeEnviron() self._registerView(view, '', IContext, IRequest) - self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, '', IContext, IRequest) + allowed = ACLDenied('ace', 'acl', 'permission', ['principals'], context) + checker = self._registerViewPermission('', allowed) self._registerSettings(debug_authorization=True) logger = self._registerLogger() - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) self.assertEqual(start_response.status, '401 Unauthorized') - message = result[0] + message = environ['repoze.bfg.message'] self.failUnless( "ACLDenied permission 'permission' via ACE 'ace' in ACL 'acl' " "on context" in message) self.failUnless("for principals ['principals']" in message) - self.assertEqual(permissionfactory.checked_with, secpol) + self.assertEqual(checker.context, context) self.assertEqual(len(logger.messages), 1) logged = logger.messages[0] self.failUnless( @@ -482,7 +574,6 @@ class RouterTests(unittest.TestCase): "for principals ['principals']" in logged) def test_call_eventsends(self): - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context) response = DummyResponse() @@ -494,7 +585,7 @@ class RouterTests(unittest.TestCase): from repoze.bfg.interfaces import INewResponse request_events = self._registerEventListener(INewRequest) response_events = self._registerEventListener(INewResponse) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() result = router(environ, start_response) @@ -503,12 +594,27 @@ class RouterTests(unittest.TestCase): self.assertEqual(len(response_events), 1) self.assertEqual(response_events[0].response, response) + def test_call_pushes_and_pops_threadlocal_manager(self): + context = DummyContext() + self._registerTraverserFactory(context) + response = DummyResponse() + response.app_iter = ['Hello world'] + view = make_view(response) + environ = self._makeEnviron() + self._registerView(view, '', None, None) + self._registerRootFactory(None) + router = self._makeOne() + start_response = DummyStartResponse() + router.threadlocal_manager = DummyThreadLocalManager() + result = router(environ, start_response) + self.assertEqual(len(router.threadlocal_manager.pushed), 1) + self.assertEqual(len(router.threadlocal_manager.popped), 1) + def test_call_post_method(self): from repoze.bfg.interfaces import INewRequest from repoze.bfg.interfaces import IPOSTRequest from repoze.bfg.interfaces import IPUTRequest from repoze.bfg.interfaces import IRequest - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context) response = DummyResponse() @@ -516,7 +622,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron(REQUEST_METHOD='POST') self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() request_events = self._registerEventListener(INewRequest) @@ -531,7 +637,6 @@ class RouterTests(unittest.TestCase): from repoze.bfg.interfaces import IPUTRequest from repoze.bfg.interfaces import IPOSTRequest from repoze.bfg.interfaces import IRequest - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context) response = DummyResponse() @@ -539,7 +644,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron(REQUEST_METHOD='PUT') self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() request_events = self._registerEventListener(INewRequest) @@ -552,7 +657,6 @@ class RouterTests(unittest.TestCase): def test_call_unknown_method(self): from repoze.bfg.interfaces import INewRequest from repoze.bfg.interfaces import IRequest - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context) response = DummyResponse() @@ -560,7 +664,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron(REQUEST_METHOD='UNKNOWN') self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() request_events = self._registerEventListener(INewRequest) @@ -573,7 +677,6 @@ class RouterTests(unittest.TestCase): from repoze.bfg.interfaces import IRequestFactory from repoze.bfg.testing import DummyRequest self.registry.registerUtility(DummyRequest, IRequestFactory) - rootfactory = make_rootfactory(None) context = DummyContext() self._registerTraverserFactory(context) response = DummyResponse() @@ -581,7 +684,7 @@ class RouterTests(unittest.TestCase): view = make_view(response) environ = self._makeEnviron() self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) + self._registerRootFactory(None) router = self._makeOne() start_response = DummyStartResponse() request_events = self._registerEventListener(INewRequest) @@ -593,54 +696,19 @@ class RouterTests(unittest.TestCase): self.assertEqual(request.view_name, '') self.assertEqual(request.subpath, []) - def test_call_inotfound_appfactory_override(self): - from repoze.bfg.interfaces import INotFoundAppFactory - def app(): - """ """ - self.registry.registerUtility(app, INotFoundAppFactory) - rootfactory = make_rootfactory(None) - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = make_view(response) - environ = self._makeEnviron() - self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) - router = self._makeOne() - self.assertEqual(router.notfound_app_factory, app) - - def test_call_iunauth_appfactory_override(self): - from repoze.bfg.interfaces import IUnauthorizedAppFactory - def app(): - """ """ - self.registry.registerUtility(app, IUnauthorizedAppFactory) - rootfactory = make_rootfactory(None) - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = make_view(response) - environ = self._makeEnviron() - self._registerView(view, '', None, None) - self._registerRootFactory(rootfactory) - router = self._makeOne() - self.assertEqual(router.unauth_app_factory, app) - class MakeAppTests(unittest.TestCase): def setUp(self): cleanUp() import repoze.bfg.router - self.old_registry_manager = repoze.bfg.router.registry_manager + self.old_tl_manager = repoze.bfg.router.manager self.regmgr = DummyRegistryManager() - repoze.bfg.router.registry_manager = self.regmgr + repoze.bfg.router.manager = self.regmgr def tearDown(self): cleanUp() import repoze.bfg.router - repoze.bfg.router.registry_manager = self.old_registry_manager + repoze.bfg.router.threadlocal_manager = self.old_tl_manager - def _callFUT(self, *arg, **kw): from repoze.bfg.router import make_app return make_app(*arg, **kw) @@ -729,6 +797,73 @@ class MakeAppTests(unittest.TestCase): self.assertRaises(ValueError, self._callFUT, None, fixtureapp, options=options) + def test_authorization_policy_no_authentication_policy(self): + from repoze.bfg.interfaces import IAuthorizationPolicy + authzpolicy = DummyContext() + from repoze.bfg.tests import routesapp + app = self._callFUT(None, routesapp, authorization_policy=authzpolicy) + self.failIf(app.registry.queryUtility(IAuthorizationPolicy)) + + def test_authentication_policy_no_authorization_policy(self): + from repoze.bfg.interfaces import IAuthorizationPolicy + from repoze.bfg.interfaces import IAuthenticationPolicy + from repoze.bfg.authorization import ACLAuthorizationPolicy + authnpolicy = DummyContext() + from repoze.bfg.tests import routesapp + app = self._callFUT(None, routesapp, authentication_policy=authnpolicy) + self.assertEqual(app.registry.getUtility(IAuthenticationPolicy), + authnpolicy) + self.assertEqual( + app.registry.getUtility(IAuthorizationPolicy).__class__, + ACLAuthorizationPolicy) + + def test_authentication_policy_and_authorization_policy(self): + from repoze.bfg.interfaces import IAuthorizationPolicy + from repoze.bfg.interfaces import IAuthenticationPolicy + authnpolicy = DummyContext() + authzpolicy = DummyContext() + from repoze.bfg.tests import routesapp + app = self._callFUT(None, routesapp, authentication_policy=authnpolicy, + authorization_policy = authzpolicy) + self.assertEqual(app.registry.getUtility(IAuthenticationPolicy), + authnpolicy) + self.assertEqual(app.registry.getUtility(IAuthorizationPolicy), + authzpolicy) + + def test_secpol_BBB_registrations(self): + from repoze.bfg.interfaces import IAuthorizationPolicy + from repoze.bfg.interfaces import IAuthenticationPolicy + from repoze.bfg.interfaces import ISecurityPolicy + secpol = DummySecurityPolicy() + from zope.component import getGlobalSiteManager + gsm = getGlobalSiteManager() + gsm.registerUtility(secpol, ISecurityPolicy) + from repoze.bfg.tests import routesapp + logger = DummyLogger() + app = self._callFUT(None, routesapp, registry=gsm, debug_logger=logger) + self.failUnless(app.registry.queryUtility(IAuthenticationPolicy)) + self.failUnless(app.registry.queryUtility(IAuthorizationPolicy)) + self.assertEqual(len(logger.messages), 1) + self.failUnless('ISecurityPolicy' in logger.messages[0]) + +class TestDefaultForbiddenView(unittest.TestCase): + def _callFUT(self, context, request): + from repoze.bfg.router import default_forbidden_view + return default_forbidden_view(context, request) + + def test_nomessage(self): + request = DummyRequest({}) + context = DummyContext() + response = self._callFUT(context, request) + self.failUnless('' in response.body) + + def test_withmessage(self): + request = DummyRequest({'repoze.bfg.message':'abc&123'}) + context = DummyContext() + response = self._callFUT(context, request) + self.failUnless('abc&123' in response.body) + + class DummyRegistryManager: def push(self, registry): self.pushed = True @@ -744,18 +879,6 @@ def make_view(response): return response return view -def make_permission_factory(result): - class DummyPermissionFactory: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self, secpol): - self.__class__.checked_with = secpol - return result - - return DummyPermissionFactory - def make_rootfactory(root): def rootpolicy(environ): return root @@ -776,3 +899,29 @@ class DummyResponse: class DummySecurityPolicy: pass +class DummyRequest: + def __init__(self, environ): + self.environ = environ + + +class DummyLogger: + def __init__(self): + self.messages = [] + def info(self, msg): + self.messages.append(msg) + warn = info + debug = info + +class DummyThreadLocalManager: + def __init__(self): + self.pushed = [] + self.popped = [] + + def push(self, val): + self.pushed.append(val) + + def pop(self): + self.popped.append(True) + +class DummyAuthenticationPolicy: + pass diff --git a/repoze/bfg/tests/test_secpols.py b/repoze/bfg/tests/test_secpols.py new file mode 100644 index 000000000..2b0449e89 --- /dev/null +++ b/repoze/bfg/tests/test_secpols.py @@ -0,0 +1,766 @@ +import unittest + +from repoze.bfg.testing import cleanUp + +class TestAPIFunctionsSecpolBBB(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + try: + del globals()['__warningregistry__'] + except KeyError: + pass + + def _testWithWarnings(self, f, *args, **kw): + messages = [] + def showwarning(message, category, filename, lineno, file=None): + messages.append(message) + try: + import warnings + _old_showwarning = warnings.showwarning + warnings.showwarning = showwarning + result = f(*args, **kw) + return result, messages + finally: + warnings.showwarning = _old_showwarning + + def _registerSecurityPolicy(self, secpol): + import zope.component + from repoze.bfg.secpols import registerBBBAuthn + gsm = zope.component.getGlobalSiteManager() + registerBBBAuthn(secpol, gsm) + + def test_has_permission_registered(self): + secpol = DummySecurityPolicy(False) + self._registerSecurityPolicy(secpol) + from repoze.bfg.security import has_permission + self.assertEqual(has_permission('view', None, None), False) + + def test_has_permission_not_registered(self): + from repoze.bfg.security import has_permission + result = has_permission('view', None, None) + self.assertEqual(result, True) + self.assertEqual(result.msg, 'No authentication policy in use.') + + def test_authenticated_userid_registered(self): + secpol = DummySecurityPolicy(False) + self._registerSecurityPolicy(secpol) + from repoze.bfg.security import authenticated_userid + request = DummyRequest({}) + result, warnings = self._testWithWarnings(authenticated_userid, + request) + self.assertEqual(result, 'fred') + self.assertEqual(len(warnings), 1) + + def test_authenticated_userid_not_registered(self): + from repoze.bfg.security import authenticated_userid + request = DummyRequest({}) + result, warnings = self._testWithWarnings(authenticated_userid, + request) + self.assertEqual(result, None) + self.assertEqual(len(warnings), 1) + + def test_authenticated_userid_too_many_args(self): + from repoze.bfg.security import authenticated_userid + self.assertRaises(TypeError, authenticated_userid, None, None, None) + + def test_effective_principals_registered(self): + secpol = DummySecurityPolicy(False) + self._registerSecurityPolicy(secpol) + from repoze.bfg.security import effective_principals + request = DummyRequest({}) + result, warnings = self._testWithWarnings(effective_principals, request) + self.assertEqual(result, ['fred', 'bob']) + self.assertEqual(len(warnings), 1) + + def test_effective_principals_not_registered(self): + from repoze.bfg.security import effective_principals + request = DummyRequest({}) + result, warnings = self._testWithWarnings(effective_principals, request) + self.assertEqual(result, []) + self.assertEqual(len(warnings), 1) + + def test_effective_principals_too_many_args(self): + from repoze.bfg.security import effective_principals + self.assertRaises(TypeError, effective_principals, None, None, None) + + + def test_principals_allowed_by_permission_not_registered(self): + from repoze.bfg.security import principals_allowed_by_permission + from repoze.bfg.security import Everyone + self.assertEqual(principals_allowed_by_permission(None, None), + [Everyone]) + + def test_principals_allowed_by_permission_registered(self): + secpol = DummySecurityPolicy(False) + self._registerSecurityPolicy(secpol) + from repoze.bfg.security import principals_allowed_by_permission + self.assertEqual(principals_allowed_by_permission(None, None), + ['fred', 'bob']) + + +class TestACLSecurityPolicy(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from repoze.bfg.secpols import ACLSecurityPolicy + return ACLSecurityPolicy + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_class_implements_ISecurityPolicy(self): + from zope.interface.verify import verifyClass + from repoze.bfg.interfaces import ISecurityPolicy + verifyClass(ISecurityPolicy, self._getTargetClass()) + + def test_instance_implements_ISecurityPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import ISecurityPolicy + verifyObject(ISecurityPolicy, self._makeOne(lambda *arg: None)) + + def test_permits_no_principals_no_acl_info_on_context(self): + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne(lambda *arg: []) + result = policy.permits(context, request, 'view') + self.assertEqual(result, False) + from repoze.bfg.security import Everyone + self.assertEqual(result.principals, set([Everyone])) + self.assertEqual(result.permission, 'view') + self.assertEqual(result.context, context) + + def test_permits_no_principals_empty_acl_info_on_context(self): + context = DummyContext() + context.__acl__ = [] + request = DummyRequest({}) + policy = self._makeOne(lambda *arg: []) + result = policy.permits(context, request, 'view') + self.assertEqual(result, False) + from repoze.bfg.security import Everyone + self.assertEqual(result.principals, set([Everyone])) + self.assertEqual(result.permission, 'view') + self.assertEqual(result.context, context) + + def test_permits_no_principals_root_has_empty_acl_info(self): + context = DummyContext() + context.__name__ = None + context.__parent__ = None + context.__acl__ = [] + context2 = DummyContext() + context2.__name__ = 'context2' + context2.__parent__ = context + request = DummyRequest({}) + policy = self._makeOne(lambda *arg: []) + result = policy.permits(context, request, 'view') + self.assertEqual(result, False) + from repoze.bfg.security import Everyone + self.assertEqual(result.principals, set([Everyone])) + self.assertEqual(result.permission, 'view') + self.assertEqual(result.context, context) + + def test_permits_no_principals_root_allows_everyone(self): + context = DummyContext() + context.__name__ = None + context.__parent__ = None + from repoze.bfg.security import Allow, Everyone + context.__acl__ = [ (Allow, Everyone, 'view') ] + context2 = DummyContext() + context2.__name__ = 'context2' + context2.__parent__ = context + request = DummyRequest({}) + policy = self._makeOne(lambda *arg: []) + result = policy.permits(context, request, 'view') + self.assertEqual(result, True) + self.assertEqual(result.principals, set([Everyone])) + self.assertEqual(result.permission, 'view') + self.assertEqual(result.context, context) + + def test_permits_deny_implicit(self): + from repoze.bfg.security import Allow, Authenticated, Everyone + context = DummyContext() + context.__acl__ = [ (Allow, 'somebodyelse', 'read') ] + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context, request, 'read') + self.assertEqual(result, False) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'read') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, None) + + def test_permits_deny_explicit(self): + from repoze.bfg.security import Deny, Authenticated, Everyone + context = DummyContext() + context.__acl__ = [ (Deny, 'fred', 'read') ] + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context, request, 'read') + self.assertEqual(result, False) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'read') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, (Deny, 'fred', 'read')) + + def test_permits_deny_twoacl_implicit(self): + from repoze.bfg.security import Allow, Authenticated, Everyone + context = DummyContext() + acl = [(Allow, 'somebody', 'view'), (Allow, 'somebody', 'write')] + context.__acl__ = acl + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context, request, 'read') + self.assertEqual(result, False) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'read') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, None) + + def test_permits_allow_twoacl_multiperm(self): + from repoze.bfg.security import Allow, Deny, Authenticated, Everyone + context = DummyContext() + acl = [ (Allow, 'fred', ('write', 'view') ), (Deny, 'fred', 'view') ] + context.__acl__ = acl + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context, request, 'view') + self.assertEqual(result, True) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'view') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, (Allow, 'fred', ('write', 'view') )) + + def test_permits_deny_twoacl_multiperm(self): + from repoze.bfg.security import Allow, Deny, Authenticated, Everyone + context = DummyContext() + acl = [] + deny = (Deny, 'fred', ('view', 'read')) + allow = (Allow, 'fred', 'view') + context.__acl__ = [deny, allow] + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context, request, 'read') + self.assertEqual(result, False) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'read') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, deny) + + def test_permits_allow_via_location_parent(self): + from repoze.bfg.security import Allow, Authenticated, Everyone + context = DummyContext() + context.__parent__ = None + context.__name__ = None + context.__acl__ = [ (Allow, 'fred', 'read') ] + context2 = DummyContext() + context2.__parent__ = context + context2.__name__ = 'myname' + + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context2, request, 'read') + self.assertEqual(result, True) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'read') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, ('Allow', 'fred', 'read')) + + def test_permits_deny_byorder(self): + from repoze.bfg.security import Allow, Deny, Authenticated, Everyone + context = DummyContext() + acl = [] + deny = (Deny, 'fred', 'read') + allow = (Allow, 'fred', 'view') + context.__acl__ = [deny, allow] + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context, request, 'read') + self.assertEqual(result, False) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'read') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, deny) + + def test_permits_allow_byorder(self): + from repoze.bfg.security import Allow, Deny, Authenticated, Everyone + context = DummyContext() + acl = [] + deny = (Deny, 'fred', ('view', 'read')) + allow = (Allow, 'fred', 'view') + context.__acl__ = [allow, deny] + policy = self._makeOne(lambda *arg: ['fred']) + request = DummyRequest({}) + result = policy.permits(context, request, 'view') + self.assertEqual(result, True) + self.assertEqual(result.principals, + set(['fred', Authenticated, Everyone])) + self.assertEqual(result.permission, 'view') + self.assertEqual(result.context, context) + self.assertEqual(result.ace, allow) + + def test_principals_allowed_by_permission_direct(self): + from repoze.bfg.security import Allow + context = DummyContext() + acl = [ (Allow, 'chrism', ('read', 'write')), + (Allow, 'other', 'read') ] + context.__acl__ = acl + policy = self._makeOne(lambda *arg: None) + result = policy.principals_allowed_by_permission(context, 'read') + self.assertEqual(result, ['chrism', 'other']) + + def test_principals_allowed_by_permission_acquired(self): + from repoze.bfg.security import Allow + context = DummyContext() + acl = [ (Allow, 'chrism', ('read', 'write')), + (Allow, 'other', ('read',)) ] + context.__acl__ = acl + context.__parent__ = None + context.__name__ = 'context' + inter = DummyContext() + inter.__name__ = None + inter.__parent__ = context + policy = self._makeOne(lambda *arg: None) + result = policy.principals_allowed_by_permission(inter, 'read') + self.assertEqual(result, ['chrism', 'other']) + + def test_principals_allowed_by_permission_no_acls(self): + policy = self._makeOne(lambda *arg: None) + result = policy.principals_allowed_by_permission(None, 'read') + self.assertEqual(result, []) + +class TestInheritingACLSecurityPolicy(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from repoze.bfg.secpols import InheritingACLSecurityPolicy + return InheritingACLSecurityPolicy + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_class_implements_ISecurityPolicy(self): + from zope.interface.verify import verifyClass + from repoze.bfg.interfaces import ISecurityPolicy + verifyClass(ISecurityPolicy, self._getTargetClass()) + + def test_instance_implements_ISecurityPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import ISecurityPolicy + verifyObject(ISecurityPolicy, self._makeOne(lambda *arg: None)) + + def test_permits(self): + from repoze.bfg.security import Deny + from repoze.bfg.security import Allow + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + from repoze.bfg.security import ALL_PERMISSIONS + from repoze.bfg.security import DENY_ALL + policy = self._makeOne(lambda *arg: []) + root = DummyContext() + community = DummyContext(__name__='community', __parent__=root) + blog = DummyContext(__name__='blog', __parent__=community) + root.__acl__ = [ + (Allow, Authenticated, VIEW), + ] + community.__acl__ = [ + (Allow, 'fred', ALL_PERMISSIONS), + (Allow, 'wilma', VIEW), + DENY_ALL, + ] + blog.__acl__ = [ + (Allow, 'barney', MEMBER_PERMS), + (Allow, 'wilma', VIEW), + ] + policy = self._makeOne(lambda request: request.principals) + request = DummyRequest({}) + + request.principals = ['wilma'] + result = policy.permits(blog, request, 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, blog) + self.assertEqual(result.ace, (Allow, 'wilma', VIEW)) + result = policy.permits(blog, request, 'delete') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + + request.principals = ['fred'] + result = policy.permits(blog, request, 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) + result = policy.permits(blog, request, 'doesntevenexistyet') + self.assertEqual(result, True) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) + + request.principals = ['barney'] + result = policy.permits(blog, request, 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, blog) + self.assertEqual(result.ace, (Allow, 'barney', MEMBER_PERMS)) + result = policy.permits(blog, request, 'administer') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + + request.principals = ['someguy'] + result = policy.permits(root, request, 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, root) + self.assertEqual(result.ace, (Allow, Authenticated, VIEW)) + result = policy.permits(blog, request, 'view') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + + request.principals = [] + result = policy.permits(root, request, 'view') + self.assertEqual(result, False) + self.assertEqual(result.context, root) + self.assertEqual(result.ace, None) + + request.principals = [] + context = DummyContext() + result = policy.permits(context, request, 'view') + self.assertEqual(result, False) + + def test_principals_allowed_by_permission_direct(self): + from repoze.bfg.security import Allow + from repoze.bfg.security import DENY_ALL + context = DummyContext() + acl = [ (Allow, 'chrism', ('read', 'write')), + DENY_ALL, + (Allow, 'other', 'read') ] + context.__acl__ = acl + policy = self._makeOne(lambda *arg: None) + result = sorted( + policy.principals_allowed_by_permission(context, 'read')) + self.assertEqual(result, ['chrism']) + + def test_principals_allowed_by_permission(self): + from repoze.bfg.security import Allow + from repoze.bfg.security import Deny + from repoze.bfg.security import DENY_ALL + from repoze.bfg.security import ALL_PERMISSIONS + root = DummyContext(__name__='', __parent__=None) + community = DummyContext(__name__='community', __parent__=root) + blog = DummyContext(__name__='blog', __parent__=community) + root.__acl__ = [ (Allow, 'chrism', ('read', 'write')), + (Allow, 'other', ('read',)), + (Allow, 'jim', ALL_PERMISSIONS)] + community.__acl__ = [ (Deny, 'flooz', 'read'), + (Allow, 'flooz', 'read'), + (Allow, 'mork', 'read'), + (Deny, 'jim', 'read'), + (Allow, 'someguy', 'manage')] + blog.__acl__ = [ (Allow, 'fred', 'read'), + DENY_ALL] + + policy = self._makeOne(lambda *arg: None) + result = sorted(policy.principals_allowed_by_permission(blog, 'read')) + self.assertEqual(result, ['fred']) + result = sorted(policy.principals_allowed_by_permission(community, + 'read')) + self.assertEqual(result, ['chrism', 'mork', 'other']) + result = sorted(policy.principals_allowed_by_permission(community, + 'read')) + result = sorted(policy.principals_allowed_by_permission(root, 'read')) + self.assertEqual(result, ['chrism', 'jim', 'other']) + + def test_principals_allowed_by_permission_no_acls(self): + policy = self._makeOne(lambda *arg: None) + context = DummyContext() + result = sorted(policy.principals_allowed_by_permission(context,'read')) + self.assertEqual(result, []) + + def test_effective_principals(self): + context = DummyContext() + request = DummyRequest({}) + request.principals = ['fred'] + policy = self._makeOne(lambda request: request.principals) + result = sorted(policy.effective_principals(request)) + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + self.assertEqual(result, + ['fred', Authenticated, Everyone]) + + def test_no_effective_principals(self): + context = DummyContext() + request = DummyRequest({}) + request.principals = [] + policy = self._makeOne(lambda request: request.principals) + result = sorted(policy.effective_principals(request)) + from repoze.bfg.security import Everyone + self.assertEqual(result, [Everyone]) + + def test_authenticated_userid(self): + context = DummyContext() + request = DummyRequest({}) + request.principals = ['fred'] + policy = self._makeOne(lambda request: request.principals) + result = policy.authenticated_userid(request) + self.assertEqual(result, 'fred') + + def test_no_authenticated_userid(self): + context = DummyContext() + request = DummyRequest({}) + request.principals = [] + policy = self._makeOne(lambda request: request.principals) + result = policy.authenticated_userid(request) + self.assertEqual(result, None) + +class TestRemoteUserACLSecurityPolicy(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from repoze.bfg.secpols import RemoteUserACLSecurityPolicy + return RemoteUserACLSecurityPolicy + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_instance_implements_ISecurityPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import ISecurityPolicy + verifyObject(ISecurityPolicy, self._makeOne()) + + def test_authenticated_userid(self): + context = DummyContext() + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + result = policy.authenticated_userid(request) + self.assertEqual(result, 'fred') + + def test_authenticated_userid_no_remote_user(self): + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + result = policy.authenticated_userid(request) + self.assertEqual(result, None) + + def test_effective_principals(self): + context = DummyContext() + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + result = policy.effective_principals(request) + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + self.assertEqual(result, [Everyone, Authenticated, 'fred']) + + def test_effective_principals_no_remote_user(self): + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + result = policy.effective_principals(request) + from repoze.bfg.security import Everyone + self.assertEqual(result, [Everyone]) + +class TestRemoteUserInheritingACLSecurityPolicy(TestRemoteUserACLSecurityPolicy): + def _getTargetClass(self): + from repoze.bfg.secpols import RemoteUserInheritingACLSecurityPolicy + return RemoteUserInheritingACLSecurityPolicy + +class TestWhoACLSecurityPolicy(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from repoze.bfg.secpols import WhoACLSecurityPolicy + return WhoACLSecurityPolicy + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_instance_implements_ISecurityPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import ISecurityPolicy + verifyObject(ISecurityPolicy, self._makeOne()) + + def test_authenticated_userid(self): + context = DummyContext() + identity = {'repoze.who.identity':{'repoze.who.userid':'fred'}} + request = DummyRequest(identity) + policy = self._makeOne() + result = policy.authenticated_userid(request) + self.assertEqual(result, 'fred') + + def test_authenticated_userid_no_who_ident(self): + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + result = policy.authenticated_userid(request) + self.assertEqual(result, None) + + def test_effective_principals(self): + context = DummyContext() + identity = {'repoze.who.identity':{'repoze.who.userid':'fred'}} + request = DummyRequest(identity) + policy = self._makeOne() + result = policy.effective_principals(request) + from repoze.bfg.security import Everyone + from repoze.bfg.security import Authenticated + self.assertEqual(result, [Everyone, Authenticated, 'fred']) + + def test_effective_principals_no_who_ident(self): + context = DummyContext() + request = DummyRequest({}) + policy = self._makeOne() + result = policy.effective_principals(request) + from repoze.bfg.security import Everyone + self.assertEqual(result, [Everyone]) + +class TestWhoInheritingACLSecurityPolicy(TestWhoACLSecurityPolicy): + def _getTargetClass(self): + from repoze.bfg.secpols import WhoInheritingACLSecurityPolicy + return WhoInheritingACLSecurityPolicy + +class TestSecurityPolicyToAuthenticationPolicyAdapter(unittest.TestCase): + def _getTargetClass(self): + from repoze.bfg.secpols import \ + SecurityPolicyToAuthenticationPolicyAdapter + return SecurityPolicyToAuthenticationPolicyAdapter + + def _makeOne(self, secpol): + return self._getTargetClass()(secpol) + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from repoze.bfg.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import IAuthenticationPolicy + verifyObject(IAuthenticationPolicy, self._makeOne(None)) + + def test_authenticated_userid(self): + secpol = DummySecurityPolicy(None) + adapter = self._makeOne(secpol) + result = adapter.authenticated_userid(None, None) + self.assertEqual(result, 'fred') + + def test_effective_principals(self): + secpol = DummySecurityPolicy(None) + adapter = self._makeOne(secpol) + result = adapter.effective_principals(None, None) + self.assertEqual(result, ['fred', 'bob']) + + def test_remember(self): + secpol = DummySecurityPolicy(None) + adapter = self._makeOne(secpol) + result = adapter.remember(None, None, None) + self.assertEqual(result, []) + + def test_forget(self): + secpol = DummySecurityPolicy(None) + adapter = self._makeOne(secpol) + result = adapter.forget(None, None) + self.assertEqual(result, []) + +class TestSecurityPolicyToAuthorizationPolicyAdapter(unittest.TestCase): + def _getTargetClass(self): + from repoze.bfg.secpols import \ + SecurityPolicyToAuthorizationPolicyAdapter + return SecurityPolicyToAuthorizationPolicyAdapter + + def _makeOne(self, secpol): + return self._getTargetClass()(secpol) + + def test_class_implements_IAuthorizationPolicy(self): + from zope.interface.verify import verifyClass + from repoze.bfg.interfaces import IAuthorizationPolicy + verifyClass(IAuthorizationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthorizationPolicy(self): + from zope.interface.verify import verifyObject + from repoze.bfg.interfaces import IAuthorizationPolicy + verifyObject(IAuthorizationPolicy, self._makeOne(None)) + + def test_permits(self): + from repoze.bfg.threadlocal import manager + manager.push({'request':1}) + try: + secpol = DummySecurityPolicy(None) + adapter = self._makeOne(secpol) + result = adapter.permits(None, None, None) + self.assertEqual(result, None) + self.assertEqual(secpol.checked, (None, 1, None)) + finally: + manager.pop() + + def test_principals_allowed_by_permission(self): + secpol = DummySecurityPolicy(None) + adapter = self._makeOne(secpol) + result = adapter.principals_allowed_by_permission(None, None) + self.assertEqual(result, ['fred', 'bob']) + + + +class DummyContext: + def __init__(self, *arg, **kw): + self.__dict__.update(kw) + +class DummyRequest: + def __init__(self, environ): + self.environ = environ + + +VIEW = 'view' +EDIT = 'edit' +CREATE = 'create' +DELETE = 'delete' +MODERATE = 'moderate' +ADMINISTER = 'administer' +COMMENT = 'comment' + +GUEST_PERMS = (VIEW, COMMENT) +MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE) +MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,) +ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,) + +class DummySecurityPolicy: + def __init__(self, result): + self.result = result + + def permits(self, *args): + self.checked = args + return self.result + + def authenticated_userid(self, request): + return 'fred' + + def effective_principals(self, request): + return ['fred', 'bob'] + + def principals_allowed_by_permission(self, context, permission): + return ['fred', 'bob'] + diff --git a/repoze/bfg/tests/test_security.py b/repoze/bfg/tests/test_security.py index 03a466e7c..3f18d3a4a 100644 --- a/repoze/bfg/tests/test_security.py +++ b/repoze/bfg/tests/test_security.py @@ -2,433 +2,6 @@ import unittest from repoze.bfg.testing import cleanUp -class TestACLSecurityPolicy(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.security import ACLSecurityPolicy - return ACLSecurityPolicy - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_class_implements_ISecurityPolicy(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import ISecurityPolicy - verifyClass(ISecurityPolicy, self._getTargetClass()) - - def test_instance_implements_ISecurityPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ISecurityPolicy - verifyObject(ISecurityPolicy, self._makeOne(lambda *arg: None)) - - def test_permits_no_principals_no_acl_info_on_context(self): - context = DummyContext() - request = DummyRequest({}) - policy = self._makeOne(lambda *arg: []) - result = policy.permits(context, request, 'view') - self.assertEqual(result, False) - from repoze.bfg.security import Everyone - self.assertEqual(result.principals, set([Everyone])) - self.assertEqual(result.permission, 'view') - self.assertEqual(result.context, context) - - def test_permits_no_principals_empty_acl_info_on_context(self): - context = DummyContext() - context.__acl__ = [] - request = DummyRequest({}) - policy = self._makeOne(lambda *arg: []) - result = policy.permits(context, request, 'view') - self.assertEqual(result, False) - from repoze.bfg.security import Everyone - self.assertEqual(result.principals, set([Everyone])) - self.assertEqual(result.permission, 'view') - self.assertEqual(result.context, context) - - def test_permits_no_principals_root_has_empty_acl_info(self): - context = DummyContext() - context.__name__ = None - context.__parent__ = None - context.__acl__ = [] - context2 = DummyContext() - context2.__name__ = 'context2' - context2.__parent__ = context - request = DummyRequest({}) - policy = self._makeOne(lambda *arg: []) - result = policy.permits(context, request, 'view') - self.assertEqual(result, False) - from repoze.bfg.security import Everyone - self.assertEqual(result.principals, set([Everyone])) - self.assertEqual(result.permission, 'view') - self.assertEqual(result.context, context) - - def test_permits_no_principals_root_allows_everyone(self): - context = DummyContext() - context.__name__ = None - context.__parent__ = None - from repoze.bfg.security import Allow, Everyone - context.__acl__ = [ (Allow, Everyone, 'view') ] - context2 = DummyContext() - context2.__name__ = 'context2' - context2.__parent__ = context - request = DummyRequest({}) - policy = self._makeOne(lambda *arg: []) - result = policy.permits(context, request, 'view') - self.assertEqual(result, True) - self.assertEqual(result.principals, set([Everyone])) - self.assertEqual(result.permission, 'view') - self.assertEqual(result.context, context) - - def test_permits_deny_implicit(self): - from repoze.bfg.security import Allow, Authenticated, Everyone - context = DummyContext() - context.__acl__ = [ (Allow, 'somebodyelse', 'read') ] - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context, request, 'read') - self.assertEqual(result, False) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'read') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, None) - - def test_permits_deny_explicit(self): - from repoze.bfg.security import Deny, Authenticated, Everyone - context = DummyContext() - context.__acl__ = [ (Deny, 'fred', 'read') ] - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context, request, 'read') - self.assertEqual(result, False) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'read') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, (Deny, 'fred', 'read')) - - def test_permits_deny_twoacl_implicit(self): - from repoze.bfg.security import Allow, Authenticated, Everyone - context = DummyContext() - acl = [(Allow, 'somebody', 'view'), (Allow, 'somebody', 'write')] - context.__acl__ = acl - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context, request, 'read') - self.assertEqual(result, False) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'read') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, None) - - def test_permits_allow_twoacl_multiperm(self): - from repoze.bfg.security import Allow, Deny, Authenticated, Everyone - context = DummyContext() - acl = [ (Allow, 'fred', ('write', 'view') ), (Deny, 'fred', 'view') ] - context.__acl__ = acl - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context, request, 'view') - self.assertEqual(result, True) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'view') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, (Allow, 'fred', ('write', 'view') )) - - def test_permits_deny_twoacl_multiperm(self): - from repoze.bfg.security import Allow, Deny, Authenticated, Everyone - context = DummyContext() - acl = [] - deny = (Deny, 'fred', ('view', 'read')) - allow = (Allow, 'fred', 'view') - context.__acl__ = [deny, allow] - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context, request, 'read') - self.assertEqual(result, False) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'read') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, deny) - - def test_permits_allow_via_location_parent(self): - from repoze.bfg.security import Allow, Authenticated, Everyone - context = DummyContext() - context.__parent__ = None - context.__name__ = None - context.__acl__ = [ (Allow, 'fred', 'read') ] - context2 = DummyContext() - context2.__parent__ = context - context2.__name__ = 'myname' - - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context2, request, 'read') - self.assertEqual(result, True) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'read') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, ('Allow', 'fred', 'read')) - - def test_permits_deny_byorder(self): - from repoze.bfg.security import Allow, Deny, Authenticated, Everyone - context = DummyContext() - acl = [] - deny = (Deny, 'fred', 'read') - allow = (Allow, 'fred', 'view') - context.__acl__ = [deny, allow] - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context, request, 'read') - self.assertEqual(result, False) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'read') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, deny) - - def test_permits_allow_byorder(self): - from repoze.bfg.security import Allow, Deny, Authenticated, Everyone - context = DummyContext() - acl = [] - deny = (Deny, 'fred', ('view', 'read')) - allow = (Allow, 'fred', 'view') - context.__acl__ = [allow, deny] - policy = self._makeOne(lambda *arg: ['fred']) - request = DummyRequest({}) - result = policy.permits(context, request, 'view') - self.assertEqual(result, True) - self.assertEqual(result.principals, - set(['fred', Authenticated, Everyone])) - self.assertEqual(result.permission, 'view') - self.assertEqual(result.context, context) - self.assertEqual(result.ace, allow) - - def test_principals_allowed_by_permission_direct(self): - from repoze.bfg.security import Allow - context = DummyContext() - acl = [ (Allow, 'chrism', ('read', 'write')), - (Allow, 'other', 'read') ] - context.__acl__ = acl - policy = self._makeOne(lambda *arg: None) - result = policy.principals_allowed_by_permission(context, 'read') - self.assertEqual(result, ['chrism', 'other']) - - def test_principals_allowed_by_permission_acquired(self): - from repoze.bfg.security import Allow - context = DummyContext() - acl = [ (Allow, 'chrism', ('read', 'write')), - (Allow, 'other', ('read',)) ] - context.__acl__ = acl - context.__parent__ = None - context.__name__ = 'context' - inter = DummyContext() - inter.__name__ = None - inter.__parent__ = context - policy = self._makeOne(lambda *arg: None) - result = policy.principals_allowed_by_permission(inter, 'read') - self.assertEqual(result, ['chrism', 'other']) - - def test_principals_allowed_by_permission_no_acls(self): - policy = self._makeOne(lambda *arg: None) - result = policy.principals_allowed_by_permission(None, 'read') - self.assertEqual(result, []) - -class TestInheritingACLSecurityPolicy(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.security import InheritingACLSecurityPolicy - return InheritingACLSecurityPolicy - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_class_implements_ISecurityPolicy(self): - from zope.interface.verify import verifyClass - from repoze.bfg.interfaces import ISecurityPolicy - verifyClass(ISecurityPolicy, self._getTargetClass()) - - def test_instance_implements_ISecurityPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ISecurityPolicy - verifyObject(ISecurityPolicy, self._makeOne(lambda *arg: None)) - - def test_permits(self): - from repoze.bfg.security import Deny - from repoze.bfg.security import Allow - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - from repoze.bfg.security import ALL_PERMISSIONS - from repoze.bfg.security import DENY_ALL - policy = self._makeOne(lambda *arg: []) - root = DummyContext() - community = DummyContext(__name__='community', __parent__=root) - blog = DummyContext(__name__='blog', __parent__=community) - root.__acl__ = [ - (Allow, Authenticated, VIEW), - ] - community.__acl__ = [ - (Allow, 'fred', ALL_PERMISSIONS), - (Allow, 'wilma', VIEW), - DENY_ALL, - ] - blog.__acl__ = [ - (Allow, 'barney', MEMBER_PERMS), - (Allow, 'wilma', VIEW), - ] - policy = self._makeOne(lambda request: request.principals) - request = DummyRequest({}) - - request.principals = ['wilma'] - result = policy.permits(blog, request, 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, blog) - self.assertEqual(result.ace, (Allow, 'wilma', VIEW)) - result = policy.permits(blog, request, 'delete') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - - request.principals = ['fred'] - result = policy.permits(blog, request, 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) - result = policy.permits(blog, request, 'doesntevenexistyet') - self.assertEqual(result, True) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) - - request.principals = ['barney'] - result = policy.permits(blog, request, 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, blog) - self.assertEqual(result.ace, (Allow, 'barney', MEMBER_PERMS)) - result = policy.permits(blog, request, 'administer') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - - request.principals = ['someguy'] - result = policy.permits(root, request, 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, root) - self.assertEqual(result.ace, (Allow, Authenticated, VIEW)) - result = policy.permits(blog, request, 'view') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - - request.principals = [] - result = policy.permits(root, request, 'view') - self.assertEqual(result, False) - self.assertEqual(result.context, root) - self.assertEqual(result.ace, None) - - request.principals = [] - context = DummyContext() - result = policy.permits(context, request, 'view') - self.assertEqual(result, False) - - def test_principals_allowed_by_permission_direct(self): - from repoze.bfg.security import Allow - from repoze.bfg.security import DENY_ALL - context = DummyContext() - acl = [ (Allow, 'chrism', ('read', 'write')), - DENY_ALL, - (Allow, 'other', 'read') ] - context.__acl__ = acl - policy = self._makeOne(lambda *arg: None) - result = sorted( - policy.principals_allowed_by_permission(context, 'read')) - self.assertEqual(result, ['chrism']) - - def test_principals_allowed_by_permission(self): - from repoze.bfg.security import Allow - from repoze.bfg.security import Deny - from repoze.bfg.security import DENY_ALL - from repoze.bfg.security import ALL_PERMISSIONS - root = DummyContext(__name__='', __parent__=None) - community = DummyContext(__name__='community', __parent__=root) - blog = DummyContext(__name__='blog', __parent__=community) - root.__acl__ = [ (Allow, 'chrism', ('read', 'write')), - (Allow, 'other', ('read',)), - (Allow, 'jim', ALL_PERMISSIONS)] - community.__acl__ = [ (Deny, 'flooz', 'read'), - (Allow, 'flooz', 'read'), - (Allow, 'mork', 'read'), - (Deny, 'jim', 'read'), - (Allow, 'someguy', 'manage')] - blog.__acl__ = [ (Allow, 'fred', 'read'), - DENY_ALL] - - policy = self._makeOne(lambda *arg: None) - result = sorted(policy.principals_allowed_by_permission(blog, 'read')) - self.assertEqual(result, ['fred']) - result = sorted(policy.principals_allowed_by_permission(community, - 'read')) - self.assertEqual(result, ['chrism', 'mork', 'other']) - result = sorted(policy.principals_allowed_by_permission(community, - 'read')) - result = sorted(policy.principals_allowed_by_permission(root, 'read')) - self.assertEqual(result, ['chrism', 'jim', 'other']) - - def test_principals_allowed_by_permission_no_acls(self): - policy = self._makeOne(lambda *arg: None) - context = DummyContext() - result = sorted(policy.principals_allowed_by_permission(context,'read')) - self.assertEqual(result, []) - - def test_effective_principals(self): - context = DummyContext() - request = DummyRequest({}) - request.principals = ['fred'] - policy = self._makeOne(lambda request: request.principals) - result = sorted(policy.effective_principals(request)) - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - self.assertEqual(result, - ['fred', Authenticated, Everyone]) - - def test_no_effective_principals(self): - context = DummyContext() - request = DummyRequest({}) - request.principals = [] - policy = self._makeOne(lambda request: request.principals) - result = sorted(policy.effective_principals(request)) - from repoze.bfg.security import Everyone - self.assertEqual(result, [Everyone]) - - def test_authenticated_userid(self): - context = DummyContext() - request = DummyRequest({}) - request.principals = ['fred'] - policy = self._makeOne(lambda request: request.principals) - result = policy.authenticated_userid(request) - self.assertEqual(result, 'fred') - - def test_no_authenticated_userid(self): - context = DummyContext() - request = DummyRequest({}) - request.principals = [] - policy = self._makeOne(lambda request: request.principals) - result = policy.authenticated_userid(request) - self.assertEqual(result, None) class TestAllPermissionsList(unittest.TestCase): def setUp(self): @@ -454,211 +27,13 @@ class TestAllPermissionsList(unittest.TestCase): from repoze.bfg.security import ALL_PERMISSIONS self.assertEqual(ALL_PERMISSIONS.__class__, self._getTargetClass()) -class TestRemoteUserACLSecurityPolicy(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from repoze.bfg.security import RemoteUserACLSecurityPolicy - return RemoteUserACLSecurityPolicy - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ISecurityPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ISecurityPolicy - verifyObject(ISecurityPolicy, self._makeOne()) - - def test_authenticated_userid(self): - context = DummyContext() - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - result = policy.authenticated_userid(request) - self.assertEqual(result, 'fred') - - def test_authenticated_userid_no_remote_user(self): - context = DummyContext() - request = DummyRequest({}) - policy = self._makeOne() - result = policy.authenticated_userid(request) - self.assertEqual(result, None) - - def test_effective_principals(self): - context = DummyContext() - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - result = policy.effective_principals(request) - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - self.assertEqual(result, [Everyone, Authenticated, 'fred']) - - def test_effective_principals_no_remote_user(self): - context = DummyContext() - request = DummyRequest({}) - policy = self._makeOne() - result = policy.effective_principals(request) - from repoze.bfg.security import Everyone - self.assertEqual(result, [Everyone]) - -class TestRemoteUserInheritingACLSecurityPolicy(TestRemoteUserACLSecurityPolicy): - def _getTargetClass(self): - from repoze.bfg.security import RemoteUserInheritingACLSecurityPolicy - return RemoteUserInheritingACLSecurityPolicy - -class TestWhoACLSecurityPolicy(unittest.TestCase): +class TestViewPermissionFactory(unittest.TestCase): def setUp(self): cleanUp() def tearDown(self): cleanUp() - - def _getTargetClass(self): - from repoze.bfg.security import WhoACLSecurityPolicy - return WhoACLSecurityPolicy - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_instance_implements_ISecurityPolicy(self): - from zope.interface.verify import verifyObject - from repoze.bfg.interfaces import ISecurityPolicy - verifyObject(ISecurityPolicy, self._makeOne()) - - def test_authenticated_userid(self): - context = DummyContext() - identity = {'repoze.who.identity':{'repoze.who.userid':'fred'}} - request = DummyRequest(identity) - policy = self._makeOne() - result = policy.authenticated_userid(request) - self.assertEqual(result, 'fred') - - def test_authenticated_userid_no_who_ident(self): - context = DummyContext() - request = DummyRequest({}) - policy = self._makeOne() - result = policy.authenticated_userid(request) - self.assertEqual(result, None) - - def test_effective_principals(self): - context = DummyContext() - identity = {'repoze.who.identity':{'repoze.who.userid':'fred'}} - request = DummyRequest(identity) - policy = self._makeOne() - result = policy.effective_principals(request) - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - self.assertEqual(result, [Everyone, Authenticated, 'fred']) - - def test_effective_principals_no_who_ident(self): - context = DummyContext() - request = DummyRequest({}) - policy = self._makeOne() - result = policy.effective_principals(request) - from repoze.bfg.security import Everyone - self.assertEqual(result, [Everyone]) - -class TestWhoInheritingACLSecurityPolicy(TestWhoACLSecurityPolicy): - def _getTargetClass(self): - from repoze.bfg.security import WhoInheritingACLSecurityPolicy - return WhoInheritingACLSecurityPolicy - -class TestAPIFunctions(unittest.TestCase): - def setUp(self): - cleanUp() - def tearDown(self): - cleanUp() - - def _registerSecurityPolicy(self, secpol): - import zope.component - gsm = zope.component.getGlobalSiteManager() - from repoze.bfg.interfaces import ISecurityPolicy - gsm.registerUtility(secpol, ISecurityPolicy) - - def test_has_permission_registered(self): - secpol = DummySecurityPolicy(False) - self._registerSecurityPolicy(secpol) - from repoze.bfg.security import has_permission - self.assertEqual(has_permission('view', None, None), False) - - def test_has_permission_not_registered(self): - from repoze.bfg.security import has_permission - result = has_permission('view', None, None) - self.assertEqual(result, True) - self.assertEqual(result.msg, 'No security policy in use.') - - def test_authenticated_userid_registered(self): - secpol = DummySecurityPolicy(False) - self._registerSecurityPolicy(secpol) - from repoze.bfg.security import authenticated_userid - request = DummyRequest({}) - self.assertEqual(authenticated_userid(request), 'fred') - - def test_authenticated_userid_not_registered(self): - from repoze.bfg.security import authenticated_userid - request = DummyRequest({}) - self.assertEqual(authenticated_userid(request), None) - - def test_effective_principals_registered(self): - secpol = DummySecurityPolicy(False) - self._registerSecurityPolicy(secpol) - from repoze.bfg.security import effective_principals - request = DummyRequest({}) - self.assertEqual(effective_principals(request), ['fred', 'bob']) - - def test_effective_principals_not_registered(self): - from repoze.bfg.security import effective_principals - request = DummyRequest({}) - self.assertEqual(effective_principals(request), []) - - def test_principals_allowed_by_permission_not_registered(self): - from repoze.bfg.security import principals_allowed_by_permission - from repoze.bfg.security import Everyone - self.assertEqual(principals_allowed_by_permission(None, None), - [Everyone]) - - def test_principals_allowed_by_permission_registered(self): - secpol = DummySecurityPolicy(False) - self._registerSecurityPolicy(secpol) - from repoze.bfg.security import principals_allowed_by_permission - self.assertEqual(principals_allowed_by_permission(None, None), - ['fred', 'bob']) - -class TestViewPermission(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.security import ViewPermission - return ViewPermission - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_call(self): - context = DummyContext() - request = DummyRequest({}) - secpol = DummySecurityPolicy(True) - permission = self._makeOne(context, request, 'repoze.view') - result = permission(secpol) - self.assertEqual(result, True) - self.assertEqual(secpol.checked, (context, request, 'repoze.view')) - - def test_repr(self): - context = DummyContext() - request = DummyRequest({}) - request.view_name = 'viewname' - secpol = DummySecurityPolicy(True) - permission = self._makeOne(context, request, 'repoze.view') - result = repr(permission) - self.failUnless(result.startswith('")) - -class TestViewPermissionFactory(unittest.TestCase): def _getTargetClass(self): from repoze.bfg.security import ViewPermissionFactory return ViewPermissionFactory @@ -671,10 +46,9 @@ class TestViewPermissionFactory(unittest.TestCase): context = DummyContext() request = DummyRequest({}) factory = self._makeOne('repoze.view') + self.assertEqual(factory.permission_name, 'repoze.view') result = factory(context, request) - self.assertEqual(result.permission_name, 'repoze.view') - self.assertEqual(result.context, context) - self.assertEqual(result.request, request) + self.assertEqual(result, True) class TestAllowed(unittest.TestCase): def _getTargetClass(self): @@ -752,6 +126,222 @@ class TestACLDenied(unittest.TestCase): self.failUnless('" % msg in repr(denied)) +class TestViewExecutionPermitted(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg, **kw): + from repoze.bfg.security import view_execution_permitted + return view_execution_permitted(*arg, **kw) + + def _registerViewPermission(self, view_name, allow=True): + import zope.component + from zope.interface import Interface + from repoze.bfg.interfaces import IViewPermission + class Checker(object): + def __call__(self, context, request): + self.context = context + self.request = request + return allow + checker = Checker() + gsm = zope.component.getGlobalSiteManager() + gsm.registerAdapter(checker, (Interface, Interface), + IViewPermission, + view_name) + return checker + + def test_no_permission(self): + import zope.component + gsm = zope.component.getGlobalSiteManager() + from repoze.bfg.interfaces import ISettings + settings = DummySettings(debug_authorization=True) + gsm.registerUtility(settings, ISettings) + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request, '') + msg = result.msg + self.failUnless("Allowed: view name '' in context" in msg) + self.failUnless('(no permission defined)' in msg) + self.assertEqual(result, True) + + def test_with_permission(self): + from zope.interface import Interface + from zope.interface import directlyProvides + from repoze.bfg.interfaces import IRequest + class IContext(Interface): + pass + context = DummyContext() + directlyProvides(context, IContext) + checker = self._registerViewPermission('', True) + request = DummyRequest({}) + directlyProvides(request, IRequest) + result = self._callFUT(context, request, '') + self.failUnless(result is True) + +def _registerAuthenticationPolicy(result): + from repoze.bfg.interfaces import IAuthenticationPolicy + policy = DummyAuthenticationPolicy(result) + import zope.component + gsm = zope.component.getGlobalSiteManager() + gsm.registerUtility(policy, IAuthenticationPolicy) + return policy + +def _registerAuthorizationPolicy(result): + from repoze.bfg.interfaces import IAuthorizationPolicy + policy = DummyAuthorizationPolicy(result) + import zope.component + gsm = zope.component.getGlobalSiteManager() + gsm.registerUtility(policy, IAuthorizationPolicy) + return policy + + +class TestHasPermission(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg): + from repoze.bfg.security import has_permission + return has_permission(*arg) + + def test_no_authentication_policy(self): + result = self._callFUT('view', None, None) + self.assertEqual(result, True) + self.assertEqual(result.msg, 'No authentication policy in use.') + + def test_authentication_policy_no_authorization_policy(self): + _registerAuthenticationPolicy(None) + self.assertRaises(ValueError, self._callFUT, 'view', None, None) + + def test_authn_and_authz_policies_registered(self): + _registerAuthenticationPolicy(None) + pol = _registerAuthorizationPolicy('yo') + self.assertEqual(self._callFUT('view', None, None), 'yo') + +class TestAuthenticatedUserId(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg): + from repoze.bfg.security import authenticated_userid + return authenticated_userid(*arg) + + def test_no_authentication_policy(self): + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request) + self.assertEqual(result, None) + + def test_with_authentication_policy(self): + _registerAuthenticationPolicy('yo') + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request) + self.assertEqual(result, 'yo') + +class TestEffectivePrincipals(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg): + from repoze.bfg.security import effective_principals + return effective_principals(*arg) + + def test_no_authentication_policy(self): + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request) + self.assertEqual(result, []) + + def test_with_authentication_policy(self): + _registerAuthenticationPolicy('yo') + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request) + self.assertEqual(result, 'yo') + +class TestPrincipalsAllowedByPermission(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg): + from repoze.bfg.security import principals_allowed_by_permission + return principals_allowed_by_permission(*arg) + + def test_no_authorization_policy(self): + from repoze.bfg.security import Everyone + context = DummyContext() + result = self._callFUT(context, 'view') + self.assertEqual(result, [Everyone]) + + def test_with_authorization_policy(self): + _registerAuthorizationPolicy('yo') + context = DummyContext() + result = self._callFUT(context, 'view') + self.assertEqual(result, 'yo') + +class TestRemember(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg): + from repoze.bfg.security import remember + return remember(*arg) + + def test_no_authentication_policy(self): + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request, 'me') + self.assertEqual(result, []) + + def test_with_authentication_policy(self): + _registerAuthenticationPolicy('yo') + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request, 'me') + self.assertEqual(result, 'yo') + +class TestForget(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, *arg): + from repoze.bfg.security import forget + return forget(*arg) + + def test_no_authentication_policy(self): + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request) + self.assertEqual(result, []) + + def test_with_authentication_policy(self): + _registerAuthenticationPolicy('yo') + context = DummyContext() + request = DummyRequest({}) + result = self._callFUT(context, request) + self.assertEqual(result, 'yo') + class DummyContext: def __init__(self, *arg, **kw): self.__dict__.update(kw) @@ -760,33 +350,33 @@ class DummyRequest: def __init__(self, environ): self.environ = environ -class DummySecurityPolicy: +class DummyAuthenticationPolicy: def __init__(self, result): self.result = result - def permits(self, *args): - self.checked = args + def effective_principals(self, context, request): return self.result - def authenticated_userid(self, request): - return 'fred' + def authenticated_userid(self, context, request): + return self.result - def effective_principals(self, request): - return ['fred', 'bob'] + def remember(self, context, request, principal, **kw): + return self.result + + def forget(self, context, request): + return self.result + +class DummyAuthorizationPolicy: + def __init__(self, result): + self.result = result + + def permits(self, context, principals, permission): + return self.result def principals_allowed_by_permission(self, context, permission): - return ['fred', 'bob'] - -VIEW = 'view' -EDIT = 'edit' -CREATE = 'create' -DELETE = 'delete' -MODERATE = 'moderate' -ADMINISTER = 'administer' -COMMENT = 'comment' - -GUEST_PERMS = (VIEW, COMMENT) -MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE) -MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,) -ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,) + return self.result + +class DummySettings: + def __init__(self, **kw): + self.__dict__.update(kw) diff --git a/repoze/bfg/tests/test_testing.py b/repoze/bfg/tests/test_testing.py index 504151ce2..5024c41ba 100644 --- a/repoze/bfg/tests/test_testing.py +++ b/repoze/bfg/tests/test_testing.py @@ -8,29 +8,20 @@ class TestTestingFunctions(unittest.TestCase): def tearDown(self): cleanUp() - def test_registerDummySecurityPolicy_permissive(self): - from repoze.bfg import testing - testing.registerDummySecurityPolicy('user', ('group1', 'group2'), - permissive=True) - from repoze.bfg.interfaces import ISecurityPolicy - from zope.component import getUtility - ut = getUtility(ISecurityPolicy) - from repoze.bfg.testing import DummyAllowingSecurityPolicy - self.failUnless(isinstance(ut, DummyAllowingSecurityPolicy)) - self.assertEqual(ut.userid, 'user') - self.assertEqual(ut.groupids, ('group1', 'group2')) - - def test_registerDummySecurityPolicy_nonpermissive(self): + def test_registerDummySecurityPolicy(self): from repoze.bfg import testing testing.registerDummySecurityPolicy('user', ('group1', 'group2'), permissive=False) - from repoze.bfg.interfaces import ISecurityPolicy + from repoze.bfg.interfaces import IAuthenticationPolicy + from repoze.bfg.interfaces import IAuthorizationPolicy from zope.component import getUtility - ut = getUtility(ISecurityPolicy) - from repoze.bfg.testing import DummyDenyingSecurityPolicy - self.failUnless(isinstance(ut, DummyDenyingSecurityPolicy)) + ut = getUtility(IAuthenticationPolicy) + from repoze.bfg.testing import DummySecurityPolicy + self.failUnless(isinstance(ut, DummySecurityPolicy)) + ut = getUtility(IAuthorizationPolicy) self.assertEqual(ut.userid, 'user') self.assertEqual(ut.groupids, ('group1', 'group2')) + self.assertEqual(ut.permissive, False) def test_registerModels(self): ob1 = object() @@ -153,36 +144,30 @@ class TestTestingFunctions(unittest.TestCase): self.assertEqual(response.body, '123') def test_registerViewPermission_defaults(self): + from repoze.bfg.security import view_execution_permitted from repoze.bfg import testing view = testing.registerViewPermission('moo.html') - from repoze.bfg.view import view_execution_permitted testing.registerDummySecurityPolicy() result = view_execution_permitted(None, None, 'moo.html') self.failUnless(result) self.assertEqual(result.msg, 'message') def test_registerViewPermission_denying(self): + from repoze.bfg.security import view_execution_permitted from repoze.bfg import testing view = testing.registerViewPermission('moo.html', result=False) - from repoze.bfg.view import view_execution_permitted testing.registerDummySecurityPolicy() result = view_execution_permitted(None, None, 'moo.html') self.failIf(result) self.assertEqual(result.msg, 'message') def test_registerViewPermission_custom(self): - class ViewPermission: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self, secpol): - return True - + from repoze.bfg.security import view_execution_permitted + def viewperm(context, request): + return True from repoze.bfg import testing view = testing.registerViewPermission('moo.html', - viewpermission=ViewPermission) - from repoze.bfg.view import view_execution_permitted + viewpermission=viewperm) testing.registerDummySecurityPolicy() result = view_execution_permitted(None, None, 'moo.html') self.failUnless(result is True) @@ -226,30 +211,30 @@ class TestTestingFunctions(unittest.TestCase): testing.registerUtility(utility, iface, name='mudge') self.assertEqual(getUtility(iface, name='mudge')(), 'foo') -class TestDummyAllowingSecurityPolicy(unittest.TestCase): +class TestDummySecurityPolicy(unittest.TestCase): def _getTargetClass(self): - from repoze.bfg.testing import DummyAllowingSecurityPolicy - return DummyAllowingSecurityPolicy + from repoze.bfg.testing import DummySecurityPolicy + return DummySecurityPolicy - def _makeOne(self, userid=None, groupids=()): + def _makeOne(self, userid=None, groupids=(), permissive=True): klass = self._getTargetClass() - return klass(userid, groupids) + return klass(userid, groupids, permissive) def test_authenticated_userid(self): policy = self._makeOne('user') - self.assertEqual(policy.authenticated_userid(None), 'user') + self.assertEqual(policy.authenticated_userid(None, None), 'user') def test_effective_principals_userid(self): policy = self._makeOne('user', ('group1',)) from repoze.bfg.security import Everyone from repoze.bfg.security import Authenticated - self.assertEqual(policy.effective_principals(None), + self.assertEqual(policy.effective_principals(None, None), [Everyone, Authenticated, 'user', 'group1']) def test_effective_principals_nouserid(self): policy = self._makeOne() from repoze.bfg.security import Everyone - self.assertEqual(policy.effective_principals(None), [Everyone]) + self.assertEqual(policy.effective_principals(None, None), [Everyone]) def test_permits(self): policy = self._makeOne() @@ -259,44 +244,19 @@ class TestDummyAllowingSecurityPolicy(unittest.TestCase): policy = self._makeOne('user', ('group1',)) from repoze.bfg.security import Everyone from repoze.bfg.security import Authenticated - self.assertEqual(policy.principals_allowed_by_permission(None, None), - [Everyone, Authenticated, 'user', 'group1']) - - -class TestDummyDenyingSecurityPolicy(unittest.TestCase): - def _getTargetClass(self): - from repoze.bfg.testing import DummyDenyingSecurityPolicy - return DummyDenyingSecurityPolicy - - def _makeOne(self, userid=None, groupids=()): - klass = self._getTargetClass() - return klass(userid, groupids) + result = policy.principals_allowed_by_permission(None, None) + self.assertEqual(result, [Everyone, Authenticated, 'user', 'group1']) - def test_authenticated_userid(self): - policy = self._makeOne('user') - self.assertEqual(policy.authenticated_userid(None), 'user') - - def test_effective_principals_userid(self): - policy = self._makeOne('user', ('group1',)) - from repoze.bfg.security import Everyone - from repoze.bfg.security import Authenticated - self.assertEqual(policy.effective_principals(None), - [Everyone, Authenticated, 'user', 'group1']) - - def test_effective_principals_nouserid(self): + def test_forget(self): policy = self._makeOne() - from repoze.bfg.security import Everyone - self.assertEqual(policy.effective_principals(None), [Everyone]) - - def test_permits(self): + self.assertEqual(policy.forget(None, None), []) + + def test_remember(self): policy = self._makeOne() - self.assertEqual(policy.permits(None, None, None), False) + self.assertEqual(policy.remember(None, None, None), []) - def test_principals_allowed_by_permission(self): - policy = self._makeOne('user', ('group1',)) - self.assertEqual(policy.principals_allowed_by_permission(None, None), - []) + class TestDummyModel(unittest.TestCase): def _getTargetClass(self): from repoze.bfg.testing import DummyModel diff --git a/repoze/bfg/tests/test_threadlocal.py b/repoze/bfg/tests/test_threadlocal.py new file mode 100644 index 000000000..230bb3726 --- /dev/null +++ b/repoze/bfg/tests/test_threadlocal.py @@ -0,0 +1,46 @@ +from repoze.bfg.testing import cleanUp +import unittest + +class TestThreadLocalManager(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from repoze.bfg.threadlocal import ThreadLocalManager + return ThreadLocalManager + + def _makeOne(self, default=lambda *x: 1): + return self._getTargetClass()(default) + + def test_init(self): + local = self._makeOne() + self.assertEqual(local.stack, []) + self.assertEqual(local.get(), 1) + + def test_default(self): + from zope.component import getGlobalSiteManager + local = self._makeOne(getGlobalSiteManager) + self.assertEqual(local.stack, []) + self.assertEqual(local.get(), getGlobalSiteManager()) + + def test_push_and_pop(self): + local = self._makeOne() + local.push(True) + self.assertEqual(local.get(), True) + self.assertEqual(local.pop(), True) + self.assertEqual(local.pop(), None) + self.assertEqual(local.get(), 1) + + def test_set_get_and_clear(self): + local = self._makeOne() + local.set(None) + self.assertEqual(local.stack, [None]) + self.assertEqual(local.get(), None) + local.clear() + self.assertEqual(local.get(), 1) + local.clear() + self.assertEqual(local.get(), 1) + diff --git a/repoze/bfg/tests/test_view.py b/repoze/bfg/tests/test_view.py index 08beffeaa..cc293d6ef 100644 --- a/repoze/bfg/tests/test_view.py +++ b/repoze/bfg/tests/test_view.py @@ -15,11 +15,21 @@ class BaseTest(object): from repoze.bfg.interfaces import IView gsm.registerAdapter(app, for_, IView, name) - def _registerPermission(self, permission, name, *for_): + def _registerViewPermission(self, view_name, allow=True): import zope.component - gsm = zope.component.getGlobalSiteManager() + from zope.interface import Interface from repoze.bfg.interfaces import IViewPermission - gsm.registerAdapter(permission, for_, IViewPermission, name) + class Checker(object): + def __call__(self, context, request): + self.context = context + self.request = request + return allow + checker = Checker() + gsm = zope.component.getGlobalSiteManager() + gsm.registerAdapter(checker, (Interface, Interface), + IViewPermission, + view_name) + return checker def _registerSecurityPolicy(self, secpol): import zope.component @@ -61,12 +71,10 @@ class RenderViewToResponseTests(BaseTest, unittest.TestCase): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(False) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', False) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -85,12 +93,10 @@ class RenderViewToResponseTests(BaseTest, unittest.TestCase): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(True) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', True) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -109,12 +115,10 @@ class RenderViewToResponseTests(BaseTest, unittest.TestCase): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(False) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', False) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -146,12 +150,10 @@ class RenderViewToIterableTests(BaseTest, unittest.TestCase): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(False) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', False) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -170,12 +172,10 @@ class RenderViewToIterableTests(BaseTest, unittest.TestCase): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(True) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', True) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -194,12 +194,10 @@ class RenderViewToIterableTests(BaseTest, unittest.TestCase): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(False) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', False) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -231,12 +229,10 @@ class RenderViewTests(unittest.TestCase, BaseTest): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(False) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', False) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -255,12 +251,10 @@ class RenderViewTests(unittest.TestCase, BaseTest): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(True) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', True) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -278,12 +272,10 @@ class RenderViewTests(unittest.TestCase, BaseTest): directlyProvides(context, IContext) response = DummyResponse() secpol = DummySecurityPolicy() - permissionfactory = make_permission_factory(False) view = make_view(response) self._registerView(view, 'registered', IContext, IRequest) self._registerSecurityPolicy(secpol) - self._registerPermission(permissionfactory, 'registered', IContext, - IRequest) + self._registerViewPermission('registered', False) environ = self._makeEnviron() from webob import Request request = Request(environ) @@ -314,67 +306,6 @@ class TestIsResponse(unittest.TestCase): response.status = None self.assertEqual(self._callFUT(response), False) -class TestViewExecutionPermitted(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, *arg, **kw): - from repoze.bfg.view import view_execution_permitted - return view_execution_permitted(*arg, **kw) - - def _registerSecurityPolicy(self, secpol): - import zope.component - gsm = zope.component.getGlobalSiteManager() - from repoze.bfg.interfaces import ISecurityPolicy - gsm.registerUtility(secpol, ISecurityPolicy) - - def _registerPermission(self, permission, name, *for_): - import zope.component - gsm = zope.component.getGlobalSiteManager() - from repoze.bfg.interfaces import IViewPermission - gsm.registerAdapter(permission, for_, IViewPermission, name) - - def test_no_secpol(self): - context = DummyContext() - request = DummyRequest() - result = self._callFUT(context, request, '') - msg = result.msg - self.failUnless("Allowed: view name '' in context" in msg) - self.failUnless('(no security policy in use)' in msg) - self.assertEqual(result, True) - - def test_secpol_no_permission(self): - secpol = DummySecurityPolicy() - self._registerSecurityPolicy(secpol) - context = DummyContext() - request = DummyRequest() - result = self._callFUT(context, request, '') - msg = result.msg - self.failUnless("Allowed: view name '' in context" in msg) - self.failUnless("(no permission registered for name '')" in msg) - self.assertEqual(result, True) - - def test_secpol_and_permission(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from repoze.bfg.interfaces import IRequest - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - permissionfactory = make_permission_factory(True) - self._registerPermission(permissionfactory, '', IContext, - IRequest) - secpol = DummySecurityPolicy() - self._registerSecurityPolicy(secpol) - request = DummyRequest() - directlyProvides(request, IRequest) - result = self._callFUT(context, request, '') - self.failUnless(result is True) - class TestStaticView(unittest.TestCase, BaseTest): def setUp(self): cleanUp() @@ -527,18 +458,6 @@ def make_view(response): return response return view -def make_permission_factory(result): - class DummyPermissionFactory: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self, secpol): - self.__class__.checked_with = secpol - return result - - return DummyPermissionFactory - class DummyResponse: status = '200 OK' headerlist = () diff --git a/repoze/bfg/tests/test_wsgi.py b/repoze/bfg/tests/test_wsgi.py index b9568eb82..893364635 100644 --- a/repoze/bfg/tests/test_wsgi.py +++ b/repoze/bfg/tests/test_wsgi.py @@ -131,7 +131,7 @@ class TestNotFound(unittest.TestCase): ('Content-Type', 'text/html')]) def test_with_message(self): - environ = {'message':''} + environ = {'repoze.bfg.message':''} L = [] def start_response(status, headers): L.append((status, headers)) @@ -166,7 +166,7 @@ class TestUnauthorized(unittest.TestCase): ('Content-Type', 'text/html')]) def test_with_message(self): - environ = {'message':''} + environ = {'repoze.bfg.message':''} L = [] def start_response(status, headers): L.append((status, headers)) -- cgit v1.2.3