Skip to content

Commit

Permalink
Added override_container context manager. (#22)
Browse files Browse the repository at this point in the history
Added `override_container` context manager.
  • Loading branch information
mauritsvanrees authored and hannosch committed Feb 15, 2017
1 parent 7c30b18 commit 2aac86a
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
4 changes: 3 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ For changes before verison 3.0, see ``HISTORY.txt``.
3.0.13 (unreleased)
-------------------

- Nothing changed yet.
- Added ``override_container`` context manager. Used this in tests to
make them pass when the standard permissive security assertions for
strings has been changed. [maurits]


3.0.12 (2015-12-21)
Expand Down
16 changes: 16 additions & 0 deletions src/AccessControl/SimpleObjectPolicies.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
'''

_noroles = [] # this is imported in various places
_marker = object()

from contextlib import contextmanager
import Record

# Allow access to unprotected attributes
Expand Down Expand Up @@ -119,3 +121,17 @@ def allow_type(Type, allowed=1):
if has_values:
assert key_type is type(tree.values())
assert key_type is type(tree.items())


@contextmanager
def override_containers(type_, assertions):
"""Temporarily override the container assertions."""
orig_container = Containers(type_, _marker)
ContainerAssertions[type_] = assertions
try:
yield
finally:
if orig_container is _marker:
del ContainerAssertions[type_]
else:
ContainerAssertions[type_] = orig_container
57 changes: 44 additions & 13 deletions src/AccessControl/tests/testZopeSecurityPolicy.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def test_checkPermission_proxy_role_scope(self):
self.a.subobject = ImplictAcqObject()
subobject = self.a.subobject
subobject.acl_users = UserFolder()
subobject.acl_users._doAddUser('theowner', 'password',
subobject.acl_users._doAddUser('theowner', 'password',
eo_roles + sysadmin_roles, ())
subobject.r_item = RestrictedSimpleItem()
r_subitem = subobject.r_item
Expand Down Expand Up @@ -336,18 +336,44 @@ def testUnicodeRolesForPermission(self):
v = self.policy.checkPermission(u'View', r_item, o_context)
self.assert_(v, '_View_Permission should grant access to theowner')

def testContainersContextManager(self):
from AccessControl.SimpleObjectPolicies import override_containers
from AccessControl.SimpleObjectPolicies import ContainerAssertions
from AccessControl.SimpleObjectPolicies import Containers
from types import EllipsisType
# Surely we have no assertions for this type. There might be a good
# reason to have then, but I have not even heard of this type.
self.assertFalse(EllipsisType in ContainerAssertions)
with override_containers(EllipsisType, 1):
self.assertTrue(EllipsisType in ContainerAssertions)
self.assertEqual(Containers(EllipsisType), 1)
# Override it again.
with override_containers(EllipsisType, {}):
self.assertEqual(Containers(EllipsisType), {})
# We are outside the nested override, so the first override should
# have been restored.
self.assertEqual(Containers(EllipsisType), 1)
# We are outside all overrides, so the type should no longer be in the
# assertions.
self.assertFalse(EllipsisType in ContainerAssertions)

def testAqNames(self):
policy = self.policy
names = {
'aq_self': 0, 'aq_base': 0,
'aq_parent': 1, 'aq_explicit': 1, 'aq_inner': 1
}
for name, allowed in names.items():
if not allowed:
self.assertRaises(Unauthorized, policy.validate,
'', '', name, '', None)
else:
policy.validate('', '', name, '', None)
from AccessControl.SimpleObjectPolicies import override_containers
# By default we allow all access to str, but this may have been
# overridden to disallow some access of str.format. So we temporarily
# restore the default of allowing all access.
with override_containers(str, 1):
for name, allowed in names.items():
if not allowed:
self.assertRaises(Unauthorized, policy.validate,
'', '', name, '', None)
else:
policy.validate('', '', name, '', None)

def testProxyRoleScope(self):
self.a.subobject = ImplictAcqObject()
Expand All @@ -359,11 +385,11 @@ def testProxyRoleScope(self):
subitem = subobject.item
subitem.owned_setuid_m = OwnedSetuidMethod()
subitem.getPhysicalRoot = lambda root=self.a: root

item = self.a.item
item.getPhysicalRoot = lambda root=self.a: root
self.context.stack.append(subitem.owned_setuid_m.__of__(subitem))

# Out of owner context
self.assertPolicyAllows(item, 'public_m')
self.assertPolicyDenies(item, 'protected_m')
Expand All @@ -380,7 +406,12 @@ def testProxyRoleScope(self):

def testUnicodeName(self):
policy = self.policy
assert policy.validate('', '', u'foo', '', None)
from AccessControl.SimpleObjectPolicies import override_containers
# By default we allow all access to str, but this may have been
# overridden to disallow some access of str.format. So we temporarily
# restore the default of allowing all access.
with override_containers(str, 1):
assert policy.validate('', '', u'foo', '', None)

if 0:
# This test purposely generates a log entry.
Expand Down Expand Up @@ -498,7 +529,7 @@ def test_getRoles():
"""
>>> from AccessControl.ZopeSecurityPolicy import getRoles
>>> class C:
... x = 'CRole'
Expand Down Expand Up @@ -613,10 +644,10 @@ def test_zsp_gets_right_roles_for_methods():
... self.user = user
>>> c = C()
>>> bool(zsp.validate(c, c, 'foo', c.foo, Context(User(['greeneggs']))))
True
>>> zsp.validate(c, c, 'foo', c.foo, Context(User(['spam'])))
Traceback (most recent call last):
...
Expand Down

0 comments on commit 2aac86a

Please sign in to comment.