Commit 0d45f608 authored by Jérome Perrin's avatar Jérome Perrin

patches/Restricted: fix access check for type

On python2, attributes of new style classes (classes, not instances)
were not properly validated. On python3, attributes of classes were not.
parent d055c3e0
...@@ -124,26 +124,37 @@ class TypeAccessChecker: ...@@ -124,26 +124,37 @@ class TypeAccessChecker:
as "a method which returing a method" because we can not know what is the as "a method which returing a method" because we can not know what is the
type until it is actually called. So the three ways are simulated the type until it is actually called. So the three ways are simulated the
function returned by this method. function returned by this method.
We don't return a simple function, but a class instance with a __bool__ method
to accomodate the two cases where this is called by SecurityManager.validate when
checking access on the class (then only the bool is used) or by guarded_getattr
when checking access on the instance (the __call__ is used).
""" """
def factory(inst, name): class _AccessChecker:
""" def __call__(self, inst, name):
Check function used with ContainerAssertions checked by cAccessControl. """
""" Check function used with ContainerAssertions checked by cAccessControl.
access = _safe_class_attribute_dict.get(inst, 0) """
# The next 'dict' only checks the access configuration type access = _safe_class_attribute_dict.get(inst, 0)
if access == 1 or (isinstance(access, dict) and access.get(name, 0) == 1): # The next 'dict' only checks the access configuration type
pass if access == 1 or (isinstance(access, dict) and access.get(name, 0) == 1):
elif isinstance(access, dict) and callable(access.get(name, 0)): pass
guarded_method = access.get(name) elif isinstance(access, dict) and callable(access.get(name, 0)):
return guarded_method(inst, name) guarded_method = access.get(name)
elif callable(access): return guarded_method(inst, name)
# Only check whether the access configuration raise error or not elif callable(access):
access(inst, name) # Only check whether the access configuration raise error or not
else: access(inst, name)
# fallback to default security else:
aq_acquire(inst, name, aq_validate, getSecurityManager().validate) # fallback to default security
return v aq_acquire(inst, name, aq_validate, getSecurityManager().validate)
return factory return v
def __bool__(self):
return False
__nonzero__ = __bool__ # six.PY2
return _AccessChecker()
def __bool__(self): def __bool__(self):
# If Containers(type(x)) is true, ZopeGuard checks will short circuit, # If Containers(type(x)) is true, ZopeGuard checks will short circuit,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment