def test_ProxyFactory(self): class SomeClass(object): pass import zope.security checker = NamesChecker() specific_checker = NamesChecker() checker_as_magic_attr = NamesChecker() obj = SomeClass() proxy = ProxyFactory(obj) self.assert_(type(proxy) is Proxy) from zope.security.checker import _defaultChecker self.assert_(getChecker(proxy) is _defaultChecker) defineChecker(SomeClass, checker) proxy = ProxyFactory(obj) self.assert_(type(proxy) is Proxy) self.assert_(getChecker(proxy) is checker) obj.__Security_checker__ = checker_as_magic_attr proxy = ProxyFactory(obj) self.assert_(type(proxy) is Proxy) self.assert_(getChecker(proxy) is checker_as_magic_attr) proxy = ProxyFactory(obj, specific_checker) self.assert_(type(proxy) is Proxy) self.assert_(getChecker(proxy) is specific_checker)
def canWrite(obj, name): """Check whether the interaction may write an attribute named name on obj. Convenience method. Rather than using checkPermission in high level code, use canWrite and canAccess to avoid binding code to permissions. """ obj = ProxyFactory(obj) checker = getChecker(obj) try: checker.check_setattr(obj, name) except Unauthorized: return False except ForbiddenAttribute: # we are going to be a bit DWIM-y here: see # http://www.zope.org/Collectors/Zope3-dev/506 # generally, if the check is ForbiddenAttribute we want it to be # raised: it probably indicates a programming or configuration error. # However, we special case a write ForbiddenAttribute when one can # actually read the attribute: this represents a reasonable # configuration of a readonly attribute, and returning False (meaning # "no, you can't write it") is arguably more useful than raising the # exception. try: checker.check_getattr(obj, name) # we'll let *this* ForbiddenAttribute fall through, if any. It # means that both read and write are forbidden. except Unauthorized: pass return False # all other exceptions, other than Unauthorized and ForbiddenAttribute, # should be passed through uncaught, as they indicate programmer error return True
def ProxyFactory(object, checker=None): """Factory function that creates a proxy for an object The proxy checker is looked up if not provided. """ if type(object) is Proxy: if checker is None or checker is getChecker(object): return object else: # We have a proxy, but someone asked us to change its checker. # Let's raise an exception. # # Other reasonable actions would be to either keep the existing # proxy, or to create a new one with the given checker. # The latter might be a security hole though, if untrusted code # can call ProxyFactory. raise TypeError("Tried to use ProxyFactory to change a Proxy's" " checker.") if checker is None: checker = getattr(object, '__Security_checker__', None) if checker is None: checker = selectChecker(object) if checker is None: return object return Proxy(object, checker)
def canAccess(obj, name): """Check whether the interaction may access an attribute named name on obj. Convenience method. Rather than using checkPermission in high level code, use canWrite and canAccess to avoid binding code to permissions. """ # access attributes and methods, including, in the current checker # implementation, special names like __getitem__ obj = ProxyFactory(obj) checker = getChecker(obj) try: checker.check_getattr(obj, name) except Unauthorized: return False # if it is Forbidden (or anything else), let it be raised: it probably # indicates a programming or configuration error return True
def __get__(self, inst, cls=None): if inst is None: return self else: proxied_object = getProxiedObject(inst) if type(proxied_object) is Proxy: checker = getChecker(proxied_object) else: checker = getattr(proxied_object, '__Security_checker__', None) if checker is None: checker = selectChecker(proxied_object) wrapper_checker = selectChecker(inst) if wrapper_checker is None: return checker elif checker is None: return wrapper_checker else: return CombinedChecker(wrapper_checker, checker)
def test_proxy(self): checker = NamesChecker(()) from zope.security.checker import BasicTypes_examples rocks = tuple(BasicTypes_examples.values()) for rock in rocks: proxy = checker.proxy(rock) self.failUnless(proxy is rock, (rock, type(proxy))) for class_ in OldInst, NewInst: inst = class_() for ob in inst, class_: proxy = checker.proxy(ob) self.failUnless(removeSecurityProxy(proxy) is ob) checker = getChecker(proxy) if ob is inst: self.assertEqual(checker.permission_id('__str__'), None) else: self.assertEqual(checker.permission_id('__str__'), CheckerPublic)
def __get__(self, inst, cls=None): if inst is None: return self else: proxied_object = getProxiedObject(inst) if type(proxied_object) is Proxy: checker = getChecker(proxied_object) else: checker = getattr(proxied_object, '__Security_checker__', None) if checker is None: checker = selectChecker(proxied_object) wrapper_checker = selectChecker(inst) if wrapper_checker is None and checker is None: raise AttributeError("%r has no attribute %r" % (proxied_object.__class__.__name__, '__Security_checker__')) elif wrapper_checker is None: return checker elif checker is None: return wrapper_checker else: return CombinedChecker(wrapper_checker, checker)
def testGetChecker(self): self.assertEqual(self.c, getChecker(self.p))
def __exit__(self, *args): getChecker(self._obj).interaction = self.previous_interaction
def __enter__(self): _checker = getChecker(self._obj) self.previous_interaction = _checker.interaction _checker.interaction = new_interaction('root') return self._obj