def test_invoke_factory_blobstorage_and_demostorage(self): import os from urllib import quote as q from ZODB.blob import BlobStorage from ZODB.DemoStorage import DemoStorage from ZODB.FileStorage import FileStorage from zope.proxy import getProxiedObject DB_FILE = os.path.join(self.tmpdir, 'db.db') BLOB_DIR = os.path.join(self.tmpdir, 'blob') self.failIf(os.path.exists(DB_FILE)) resolver = self._makeOne() k, args, kw, factory = resolver( 'file://%s/db.db?quota=200&demostorage=true' '&blobstorage_dir=%s/blob' '&blobstorage_layout=bushy' % (self.tmpdir, q(self.tmpdir))) self.assertEqual(k, (('%s/db.db' % self.tmpdir,), (('blobstorage_dir', '%s/blob' % self.tmpdir), ('blobstorage_layout', 'bushy'), ('demostorage', 1), ('quota', 200), ), (('cache_size', 10000), ('database_name', 'unnamed'), ('pool_size', 7) ), ) ) db = factory() self.failUnless(isinstance(db._storage, BlobStorage)) self.failUnless(isinstance(getProxiedObject(db._storage), DemoStorage)) self.failUnless(isinstance(getProxiedObject(db._storage)._base, FileStorage)) self.failUnless(os.path.exists(DB_FILE)) self.failUnless(os.path.exists(BLOB_DIR))
def tpc_abort(self, *arg, **kw): # We need to override the base storage's abort instead of # providing an _abort method because methods found on the proxied object # aren't rebound to the proxy getProxiedObject(self).tpc_abort(*arg, **kw) while self.dirty_oids: oid, serial = self.dirty_oids.pop() clean = self.fshelper.getBlobFilename(oid, serial) if os.path.exists(clean): remove_committed(clean)
def test_w_checker(self): from zope.proxy import getProxiedObject _CHECKER = object() ctx = self._makeContext() proxy = self._callFUT(ctx, _CHECKER) self.assertTrue(getProxiedObject(proxy) is ctx) self.assertTrue(proxy.__Security_checker__ is _CHECKER)
def testLayeredProxies(self): """Tests that a Proxy will not be re-proxied.""" class Base: __Security_checker__ = NamesChecker(['__Security_checker__']) base = Base() checker = Checker({}) # base is not proxied, so we expect a proxy proxy1 = checker.proxy(base) self.assert_(type(proxy1) is Proxy) self.assert_(getProxiedObject(proxy1) is base) # proxy is a proxy, so we don't expect to get another proxy2 = checker.proxy(proxy1) self.assert_(proxy2 is proxy1) self.assert_(getProxiedObject(proxy2) is base)
def default(self, o, **settings): if proxy.isProxy(o, JSONEncoderSettingsProxy): o, settings = proxy.getProxiedObject(o), o.__json_settings__ adapter = self.adapters.lookup_adapter(providedBy(o)) if adapter is None: raise TypeError("%r is not JSON serializable" % o) return adapter(o, **settings)
def test__call__w_non_ILocation_multiple_args_extra_spacesuit(self): from zope.security.proxy import ProxyFactory from zope.security.proxy import removeSecurityProxy factory = self._makeFactory() ltaf = self._makeOne(factory) class _NotAdapter(object): pass class _Extra(object): pass adapter = _NotAdapter() extra = _Extra() proxy = ProxyFactory(extra) before = factory.__dict__.copy() returned = ltaf(adapter, proxy) self.assertFalse(returned is factory) ploc = removeSecurityProxy(returned) self.assertIs(ploc.__parent__, adapter) unwrapped = getProxiedObject(ploc) self.assertIs(unwrapped, factory) after = { k: v for k, v in unwrapped.__dict__.items() if k not in ('_called_with', ) } self.assertEqual(factory._called_with, (adapter, extra)) self.assertEqual(after, before) # no added attrs
def pack(self, packtime, referencesf): """Remove all unused OID/TID combinations.""" self._lock_acquire() try: if self._blobs_pack_is_in_progress: raise BlobStorageError('Already packing') self._blobs_pack_is_in_progress = True finally: self._lock_release() try: # Pack the underlying storage, which will allow us to determine # which serials are current. unproxied = getProxiedObject(self) result = unproxied.pack(packtime, referencesf) # Perform a pack on the blob data. if self.__supportsUndo: self._packUndoing(packtime, referencesf) else: self._packNonUndoing(packtime, referencesf) finally: self._lock_acquire() self._blobs_pack_is_in_progress = False self._lock_release() return result
class ShortNameProxy(ProxyBase): """This is a non-picklable proxy that can be put around objects to change the ``short_name`` attribute. """ __slots__ = 'short_name', '__Security_checker__' __safe_for_unpickling__ = True def __new__(self, ob, short_name=None): checker = getCheckerForInstancesOf(type(ob)) ob = ProxyBase.__new__(self, ob) ob.__Security_checker__ = checker return ob def __init__(self, ob, short_name=None): ProxyBase.__init__(self, ob) self.short_name = short_name @non_overridable def __reduce__(self, proto=None): raise TypeError("Not picklable") __doc__ = ClassAndInstanceDescr( lambda inst: getProxiedObject(inst).__doc__, lambda cls, __doc__=__doc__: __doc__, ) __reduce_ex__ = __reduce__ __providedBy__ = DecoratorSpecificationDescriptor()
class DublinCoreDescriptivePropertiesProxy(ProxyBase): """This is a non-picklable proxy that can be put around objects to add descriptive properties. """ zope.interface.implements(IDCDescriptiveProperties) __slots__ = 'title', 'description', '__Security_checker__' __safe_for_unpickling__ = True def __new__(self, ob, title=None, description=None): checker = getCheckerForInstancesOf(type(removeAllProxies(ob))) ob = ProxyBase.__new__(self, ob) ob.__Security_checker__ = checker return ob def __init__(self, ob, title=None, description=None): ProxyBase.__init__(self, ob) self.title = title self.description = description @non_overridable def __reduce__(self, proto=None): raise TypeError("Not picklable") __doc__ = ClassAndInstanceDescr( lambda inst: getProxiedObject(inst).__doc__, lambda cls, __doc__=__doc__: __doc__, ) __reduce_ex__ = __reduce__ __providedBy__ = DecoratorSpecificationDescriptor()
class LocationProxy(ProxyBase): """Location-object proxy This is a non-picklable proxy that can be put around objects that don't implement `ILocation`. """ zope.interface.implements(ILocation) __slots__ = '__parent__', '__name__' __safe_for_unpickling__ = True def __new__(self, ob, container=None, name=None): return ProxyBase.__new__(self, ob) def __init__(self, ob, container=None, name=None): ProxyBase.__init__(self, ob) self.__parent__ = container self.__name__ = name @non_overridable def __reduce__(self, proto=None): raise TypeError("Not picklable") __doc__ = ClassAndInstanceDescr( lambda inst: getProxiedObject(inst).__doc__, lambda cls, __doc__=__doc__: __doc__, ) __reduce_ex__ = __reduce__ __providedBy__ = DecoratorSpecificationDescriptor()
def __getitem__(self, key): try: obj = getProxiedObject(self) if not hasattr(obj, '__getitem__'): raise KeyError return obj[key] except KeyError: return self._attached[key]
def test_w_non_ILocation(self): class _NotAdapter(object): pass adapter = _NotAdapter() parent = object() returned = self._callFUT(adapter, parent) self.assertTrue(isinstance(returned, LocationProxy)) self.assertIs(getProxiedObject(returned), adapter) self.assertIs(returned.__parent__, parent)
def default(self, o, **settings): if proxy.isProxy(o, JSONEncoderSettingsProxy): o, settings = proxy.getProxiedObject(o), o.__json_settings__ if proxy.isProxy(o): o = proxy.removeAllProxies(o) return o adapter = self.adapters.lookup_adapter(providedBy(o)) if adapter is None: raise TypeError("%r is not JSON serializable" % o) return adapter(o, **settings)
def __get__(self, inst, cls=None): if inst is None: return getObjectSpecification(cls) else: provided = providedBy(getProxiedObject(inst)) # Use type rather than __class__ because inst is a proxy and # will return the proxied object's class. cls = type(inst) return ObjectSpecification(provided, cls)
def new_instance(self): """Implementation of IMVCCStorage.new_instance. This method causes all storage instances to be wrapped with a blob storage wrapper. """ base_dir = self.fshelper.base_dir s = getProxiedObject(self).new_instance() res = BlobStorage(base_dir, s) return res
def test_w_non_ILocation(self): from zope.location import LocationProxy from zope.proxy import getProxiedObject class _NotAdapter(object): pass adapter = _NotAdapter() parent = object() returned = self._callFUT(adapter, parent) self.assertTrue(isinstance(returned, LocationProxy)) self.assertTrue(getProxiedObject(returned) is adapter) self.assertTrue(returned.__parent__ is parent)
def unrelateCalendarOnDeletion(event): """When you delete an object, relationships of it's calendar should be removed >>> from schooltool.relationship.tests import setUp, tearDown >>> from schooltool.testing.setup import setUpCalendaring >>> setUp() >>> setUpCalendaring() >>> import zope.event >>> old_subscribers = zope.event.subscribers[:] >>> from schooltool.app.overlay import unrelateCalendarOnDeletion >>> zope.event.subscribers.append(unrelateCalendarOnDeletion) We will need some object that implements IHaveCalendar for that: >>> from zope.container.btree import BTreeContainer >>> container = BTreeContainer() >>> from schooltool.person.person import Person >>> container = BTreeContainer() >>> container['jonas'] = jonas = Person(username="******") >>> container['petras'] = petras = Person(username="******") Let's add calendar of Petras to the list of overlaid calendars: >>> jonas.overlaid_calendars.add(ISchoolToolCalendar(petras)) <...CalendarOverlayInfo object at ...> >>> list(jonas.overlaid_calendars) [<schooltool.app.overlay.CalendarOverlayInfo object at ...>] If we delete Petras - Jonas should have no calendars in his overlay list: >>> del container['petras'] >>> list(jonas.overlaid_calendars) [] Restore old subscribers: >>> zope.event.subscribers[:] = old_subscribers >>> tearDown() """ if not IObjectRemovedEvent.providedBy(event): return # event.object may be a ContainedProxy obj = getProxiedObject(event.object) if not IHaveCalendar.providedBy(obj): return calendar = ISchoolToolCalendar(obj) linkset = IRelationshipLinks(calendar, None) if linkset is not None: unrelateAll(calendar)
def test_no_checker_w_provides_and_permission_protected(self): from zope.interface import Interface from zope.proxy import getProxiedObject class IFoo(Interface): def bar(self): "bar" ctx = self._makeContext() proxy = self._callFUT(ctx, provides=IFoo, permission='testing') self.assertTrue(getProxiedObject(proxy) is ctx) checker = proxy.__Security_checker__ self.assertEqual(checker.get_permissions, {'bar': 'testing'}) self.assertFalse(checker.set_permissions)
def test_no_checker_w_provides_and_permission_protected(self): from zope.interface import Interface from zope.proxy import getProxiedObject class IFoo(Interface): def bar(self): pass ctx = self._makeContext() proxy = self._callFUT(ctx, provides=IFoo, permission='testing') self.assertTrue(getProxiedObject(proxy) is ctx) checker = proxy.__Security_checker__ self.assertEqual(checker.get_permissions, {'bar': 'testing'}) self.assertFalse(checker.set_permissions)
def _children(self): new_children = {} for x in self._copy_from._children.values(): try: new_child = x.withParentAndName(self, x.__name__) except AttributeError: if isinstance(x, LocationProxy): new_child = LocationProxy(getProxiedObject(x), self, x.__name__) else: new_child = LocationProxy(x, self, x.__name__) new_children[x.__name__] = new_child return new_children
def unindex(self, obj): wrapped_obj = obj if isinstance(obj, PathProxy): # Could be a PathProxy object from CMFCore.indexing obj = getProxiedObject(obj) if IMembraneUserObject(obj, None) is None and IGroup(obj, None) is None: return mbtool = getToolByName(obj, 'membrane_tool', None) if mbtool is not None: if getattr(obj, 'portal_type') in mbtool.listMembraneTypes(): mbtool.unindexObject(wrapped_obj)
def unindex(self, obj): wrapped_obj = obj if isinstance(obj, PathProxy): # Could be a PathProxy object from CMFCore.indexing obj = getProxiedObject(obj) if IMembraneUserObject( obj, None) is None and IGroup(obj, None) is None: return mbtool = getToolByName(obj, 'membrane_tool', None) if mbtool is not None: if getattr(obj, 'portal_type') in mbtool.listMembraneTypes(): mbtool.unindexObject(wrapped_obj)
def undo(self, serial_id, transaction): undo_serial, keys = getProxiedObject(self).undo(serial_id, transaction) # serial_id is the transaction id of the txn that we wish to undo. # "undo_serial" is the transaction id of txn in which the undo is # performed. "keys" is the list of oids that are involved in the # undo transaction. # The serial_id is assumed to be given to us base-64 encoded # (belying the web UI legacy of the ZODB code :-() serial_id = base64.decodestring(serial_id+'\n') self._lock_acquire() try: # we get all the blob oids on the filesystem related to the # transaction we want to undo. for oid in self.fshelper.getOIDsForSerial(serial_id): # we want to find the serial id of the previous revision # of this blob object. load_result = self.loadBefore(oid, serial_id) if load_result is None: # There was no previous revision of this blob # object. The blob was created in the transaction # represented by serial_id. We copy the blob data # to a new file that references the undo # transaction in case a user wishes to undo this # undo. It would be nice if we had some way to # link to old blobs. orig_fn = self.fshelper.getBlobFilename(oid, serial_id) new_fn = self.fshelper.getBlobFilename(oid, undo_serial) else: # A previous revision of this blob existed before the # transaction implied by "serial_id". We copy the blob # data to a new file that references the undo transaction # in case a user wishes to undo this undo. data, serial_before, serial_after = load_result orig_fn = self.fshelper.getBlobFilename(oid, serial_before) new_fn = self.fshelper.getBlobFilename(oid, undo_serial) orig = open(orig_fn, "r") new = open(new_fn, "wb") utils.cp(orig, new) orig.close() new.close() self.dirty_oids.append((oid, undo_serial)) finally: self._lock_release() return undo_serial, keys
def undo(self, serial_id, transaction): undo_serial, keys = getProxiedObject(self).undo(serial_id, transaction) # serial_id is the transaction id of the txn that we wish to undo. # "undo_serial" is the transaction id of txn in which the undo is # performed. "keys" is the list of oids that are involved in the # undo transaction. # The serial_id is assumed to be given to us base-64 encoded # (belying the web UI legacy of the ZODB code :-() serial_id = base64.decodestring(serial_id + '\n') self._lock_acquire() try: # we get all the blob oids on the filesystem related to the # transaction we want to undo. for oid in self.fshelper.getOIDsForSerial(serial_id): # we want to find the serial id of the previous revision # of this blob object. load_result = self.loadBefore(oid, serial_id) if load_result is None: # There was no previous revision of this blob # object. The blob was created in the transaction # represented by serial_id. We copy the blob data # to a new file that references the undo # transaction in case a user wishes to undo this # undo. It would be nice if we had some way to # link to old blobs. orig_fn = self.fshelper.getBlobFilename(oid, serial_id) new_fn = self.fshelper.getBlobFilename(oid, undo_serial) else: # A previous revision of this blob existed before the # transaction implied by "serial_id". We copy the blob # data to a new file that references the undo transaction # in case a user wishes to undo this undo. data, serial_before, serial_after = load_result orig_fn = self.fshelper.getBlobFilename(oid, serial_before) new_fn = self.fshelper.getBlobFilename(oid, undo_serial) orig = open(orig_fn, "r") new = open(new_fn, "wb") utils.cp(orig, new) orig.close() new.close() self.dirty_oids.append((oid, undo_serial)) finally: self._lock_release() return undo_serial, keys
def test__call__w_non_ILocation(self): factory = self._makeFactory() ltaf = self._makeOne(factory) class _NotAdapter(object): pass adapter = _NotAdapter() before = factory.__dict__.copy() returned = ltaf(adapter) self.assertFalse(returned is factory) unwrapped = getProxiedObject(returned) self.assertIs(unwrapped, factory) after = {k: v for k, v in returned.__dict__.items() if k != '_called_with'} self.assertEqual(factory._called_with, (adapter,)) self.assertEqual(after, before) # no added attrs
def test__call__w_non_ILocation(self): from zope.proxy import getProxiedObject factory = self._makeFactory() ltaf = self._makeOne(factory) class _NotAdapter(object): pass adapter = _NotAdapter() before = factory.__dict__.copy() returned = ltaf(adapter) self.assertFalse(returned is factory) unwrapped = getProxiedObject(returned) self.assertTrue(unwrapped is factory) after = dict([(k, v) for k, v in returned.__dict__.items() if k != '_called_with']) self.assertEqual(factory._called_with, (adapter,)) self.assertEqual(after, before) # no added attrs
def test__call__w_non_ILocation_multiple_args(self): from zope.proxy import getProxiedObject factory = self._makeFactory() ltaf = self._makeOne(factory) class _NotAdapter(object): pass adapter = _NotAdapter() extra = object() before = factory.__dict__.copy() returned = ltaf(adapter, extra) self.assertFalse(returned is factory) unwrapped = getProxiedObject(returned) self.assertTrue(unwrapped is factory) after = dict([(k, v) for k, v in returned.__dict__.items() if k != '_called_with']) self.assertEqual(factory._called_with, (adapter, extra)) self.assertEqual(after, before) # no added attrs
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 get_base(storage): #pragma NO COVERAGE """ The way to find the wrapped storage for a demo or blob storage changes from one ZODB version to the next and is inconsistent between storages. Putting the 'un' back in 'fun'. """ try: from zope.proxy import getProxiedObject base = getProxiedObject(storage) if base is not storage: return base except ImportError: pass base = getattr(storage, '_base', None) if base is None: base = getattr(storage, '_BlobStorage__storage', None) if base is None: base = storage.base return base
class LocationProxy(ProxyBase): """Location-object proxy This is a non-picklable proxy that can be put around objects that don't implement `ILocation`. """ __slots__ = ('__parent__', '__name__') __safe_for_unpickling__ = True __doc__ = ClassAndInstanceDescr( lambda inst: getProxiedObject(inst).__doc__, lambda cls, __doc__=__doc__: __doc__, ) def __new__(self, ob, container=None, name=None): return ProxyBase.__new__(self, ob) def __init__(self, ob, container=None, name=None): ProxyBase.__init__(self, ob) self.__parent__ = container self.__name__ = name def __getattribute__(self, name): if name in LocationProxy.__dict__: return object.__getattribute__(self, name) return ProxyBase.__getattribute__(self, name) def __setattr__(self, name, value): if name in self.__slots__ + getattr(ProxyBase, '__slots__', ()): #('_wrapped', '__parent__', '__name__'): try: return object.__setattr__(self, name, value) except TypeError: #pragma NO COVER C Optimization return ProxyBase.__setattr__(self, name, value) return ProxyBase.__setattr__(self, name, value) @non_overridable def __reduce__(self, proto=None): raise TypeError("Not picklable") __reduce_ex__ = __reduce__ __providedBy__ = DecoratorSpecificationDescriptor()
def test__call__w_non_ILocation_multiple_args(self): factory = self._makeFactory() ltaf = self._makeOne(factory) class _NotAdapter(object): pass adapter = _NotAdapter() extra = object() before = factory.__dict__.copy() returned = ltaf(adapter, extra) self.assertFalse(returned is factory) unwrapped = getProxiedObject(returned) self.assertIs(unwrapped, factory) after = { k: v for k, v in returned.__dict__.items() if k != '_called_with' } self.assertEqual(factory._called_with, (adapter, extra)) self.assertEqual(after, before) # no added attrs
def test__call__w_non_ILocation_w_spacesuit(self): from zope.security.proxy import ProxyFactory from zope.security.proxy import removeSecurityProxy factory = self._makeFactory() ltaf = self._makeOne(factory) class _NotAdapter(object): pass adapter = _NotAdapter() proxy = ProxyFactory(adapter) before = factory.__dict__.copy() returned = ltaf(proxy) self.assertFalse(returned is factory) ploc = removeSecurityProxy(returned) self.assertIs(ploc.__parent__, adapter) unwrapped = getProxiedObject(ploc) self.assertIs(unwrapped, factory) after = {k: v for k, v in unwrapped.__dict__.items() if k not in ('_called_with',)} self.assertEqual(factory._called_with, (adapter,)) self.assertEqual(after, before) # no added attrs
def test__call__w_non_ILocation_w_spacesuit_multiple_args(self): from zope.proxy import getProxiedObject from zope.security.proxy import ProxyFactory from zope.security.proxy import removeSecurityProxy factory = self._makeFactory() ltaf = self._makeOne(factory) class _NotAdapter(object): pass adapter = _NotAdapter() extra = object() proxy = ProxyFactory(adapter) before = factory.__dict__.copy() returned = ltaf(proxy, extra) self.assertFalse(returned is factory) ploc = removeSecurityProxy(returned) self.assertTrue(ploc.__parent__ is adapter) unwrapped = getProxiedObject(ploc) self.assertTrue(unwrapped is factory) after = dict([(k, v) for k, v in unwrapped.__dict__.items() if k not in ('_called_with',)]) self.assertEqual(factory._called_with, (adapter, extra)) self.assertEqual(after, before) # no added attrs
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 getSize(self): """Return the size of the database in bytes.""" # XXX The old way of computing is way to resource hungry. We need to # do some kind of estimation instead. return getProxiedObject(self).getSize()
def tpc_finish(self, *arg, **kw): # We need to override the base storage's tpc_finish instead of # providing a _finish method because methods found on the proxied # object aren't rebound to the proxy getProxiedObject(self).tpc_finish(*arg, **kw) self._blob_tpc_finish()
def __repr__(self): normal_storage = getProxiedObject(self) return '<BlobStorage proxy for %r at %s>' % (normal_storage, hex(id(self)))
def tpc_finish(self, *arg, **kw): # We need to override the base storage's tpc_finish instead of # providing a _finish method because methods found on the proxied # object aren't rebound to the proxy getProxiedObject(self).tpc_finish(*arg, **kw) self.dirty_oids = []
def _callFUT(self, *args): from zope.proxy import getProxiedObject return getProxiedObject(*args)
def tpc_abort(self, *arg, **kw): # We need to override the base storage's abort instead of # providing an _abort method because methods found on the proxied object # aren't rebound to the proxy getProxiedObject(self).tpc_abort(*arg, **kw) self._blob_tpc_abort()
def __providedBy__(self): return providedBy(getProxiedObject(self))
def __contains__(self, name): proxied = getProxiedObject(self) return name in proxied and not proxied[name].location in self.exclude
def restoreSortingAttrs(self): unproxied = getProxiedObject(self) self.before = getattr(unproxied, 'before', ()) self.after = getattr(unproxied, 'after', ())
def keys(self): proxied = getProxiedObject(self) return [k for k in proxied.keys() if not proxied[k].location in self.exclude]