def on_delete(cls, item, attr, trans, bPermanent): if not item._isDeleted: from porcupine import datatypes lstValue = attr.value if lstValue and attr.respectsReferences: raise exceptions.ReferentialIntegrityError, ( 'Cannot delete object "%s" ' % item.displayName.value + 'because it is being referenced by other objects.') # remove references for sID in lstValue: oItemRef = _db.getItem(sID, trans) if oItemRef.getContentclass() in attr.relCc: oAttrRef = getattr(oItemRef, attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): try: oAttrRef.value.remove(item._id) except ValueError: pass elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = '' _db.putItem(oItemRef, trans) else: attr.value.remove(sID)
def on_update(cls, item, new_attr, old_attr, trans): from porcupine import datatypes # get previous value if old_attr: prvValue = old_attr.value else: prvValue = '' if new_attr.value != prvValue: if new_attr.value: oItemRef = _db.getItem(new_attr.value, trans) if oItemRef.getContentclass() in new_attr.relCc: oAttrRef = getattr(oItemRef, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): oAttrRef.value.append(item._id) elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = item._id _db.putItem(oItemRef, trans) else: new_attr.value = '' if prvValue: oItemRef = _db.getItem(prvValue, trans) oAttrRef = getattr(oItemRef, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): try: oAttrRef.value.remove(item._id) except ValueError: pass elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = '' _db.putItem(oItemRef, trans)
def delete(self, trans): """ Deletes the item permanently. @param trans: A valid transaction handle @return: None """ oUser = currentThread().context.session.user self = _db.getItem(self._id, trans) iUserRole = objectAccess.getAccess(self, oUser) bCanDelete = (iUserRole > objectAccess.AUTHOR) or \ (iUserRole == objectAccess.AUTHOR and self._owner == oUser._id) if (not(self._isSystem) and bCanDelete): # delete item physically self._delete(trans) # update container oParent = _db.getItem(self._parentid, trans) oParent._removeItemReference(self) _db.putItem(oParent, trans) else: raise exceptions.PermissionDenied, \ 'The object was not deleted.\n' + \ 'The user has insufficient permissions.'
def restoreTo(self, sParentId, trans): """ Restores the deleted object to the specified container. @param sParentId: The ID of the container in which the item will be restored @type sParentId: str @param trans: A valid transaction handle @return: None """ ## TODO: check if oDeleted exists oDeleted = _db.getDeletedItem(self._deletedId, trans) oParent = _db.getItem(sParentId, trans) if not(oDeleted.getContentclass() in oParent.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type "%s".' % oDeleted.getContentclass() # try to restore original item self._restore(oDeleted, oParent, trans) self.delete(trans, False) # update container oParent._addItemReference(oDeleted) _db.putItem(oParent, trans)
def _applySecurity(self, oParent, trans): if self.inheritRoles: self.security = oParent.security if self.isCollection: for sID in self._subfolders.values() + self._items.values(): oItem = _db.getItem(sID, trans) if oItem.inheritRoles: oItem._applySecurity(self, trans) _db.putItem(oItem, trans)
def on_update(cls, item, new_attr, old_attr, trans): from porcupine.systemObjects import Composite # load objects dctObjects = {} for i, obj in enumerate(new_attr.value): if isinstance(obj, Composite): obj._containerid = item._id elif isinstance(obj, str): obj = _db.getItem(obj, trans) new_attr.value[i] = obj else: raise exceptions.ContainmentError, \ 'Invalid object type "%s" in composition.' % \ obj.__class__.__name__ dctObjects[obj._id] = obj # check containment compositeClass = misc.getCallableByName(new_attr.compositeClass) if [obj for obj in dctObjects.values() if not isinstance(obj, compositeClass)]: raise exceptions.ContainmentError, \ 'Invalid content class "%s" in composition.' % \ obj.getContentclass() # get previous value if old_attr != None: old_ids = set(old_attr.value) else: old_ids = set() new_ids = set([obj._id for obj in new_attr.value]) # calculate added composites lstAdded = list(new_ids - old_ids) for obj_id in lstAdded: _db.handle_update(dctObjects[obj_id], None, trans) dctObjects[obj_id]._isDeleted = False _db.putItem(dctObjects[obj_id], trans) # calculate constant composites lstConstant = list(new_ids & old_ids) for obj_id in lstConstant: _db.handle_update(dctObjects[obj_id], _db.getItem(obj_id, trans), trans) _db.putItem(dctObjects[obj_id], trans) # calculate removed composites lstRemoved = list(old_ids - new_ids) for obj_id in lstRemoved: composite4removal = _db.getItem(obj_id, trans) cls.removeComposite(composite4removal, trans) new_attr.value = list(new_ids)
def on_create(item, attr, trans): if item._isDeleted and attr.cascadeDelete and attr.value: from porcupine.systemObjects import DeletedItem oItemRef = _db.getDeletedItem(attr.value, trans) parent = _db.getItem(oItemRef._parentid, trans) # update container parent._addItemReference(oItemRef) _db.putItem(parent, trans) deletedItem = DeletedItem(oItemRef, trans) deletedItem._undelete(oItemRef, trans) Relator1EventHandler.on_update(item, attr, None, trans)
def appendTo(self, parent, trans): """ Adds the item to the specified container. @param parent: The id of the destination container or the container itself @type parent: str OR L{Container} @param trans: A valid transaction handle @return: None """ if type(parent) == str: oParent = _db.getItem(parent, trans) else: oParent = parent if isinstance(self, Shortcut): contentclass = self.target.getItem(trans).getContentclass() else: contentclass = self.contentclass oUser = currentThread().context.user iUserRole = objectAccess.getAccess(oParent, oUser) if iUserRole == objectAccess.READER: raise exceptions.PermissionDenied, \ 'The user does not have write permissions ' + \ 'on the parent folder.' if not(contentclass in oParent.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type "%s".' % contentclass # set security to new item if iUserRole == objectAccess.COORDINATOR: # user is COORDINATOR self._applySecurity(oParent, trans) else: # user is not COORDINATOR self.inheritRoles = True self.security = oParent.security #if trans._retries == 0: # raise exceptions.DBTransactionIncomplete self._owner = oUser._id self._created = time.time() self.modifiedBy = oUser.displayName.value self.modified = time.time() self._parentid = oParent._id _db.handle_update(self, None, trans) _db.putItem(self, trans) # update container oParent._addItemReference(self) _db.putItem(oParent, trans)
def on_update(item, new_attr, old_attr, trans): from porcupine import datatypes # remove duplicates new_attr.value = list(set(new_attr.value)) # get previous value if old_attr: prvValue = set(old_attr.value) noAccessList = RelatorNEventHandler.getNoAccessIds(old_attr, trans) else: prvValue = set() noAccessList = [] # get current value currentValue = set(new_attr.value + noAccessList) if currentValue != prvValue: # calculate added references lstAdded = list(currentValue - prvValue) for sID in lstAdded: try: ref_item = _db.getItem(sID, trans) except exceptions.ObjectNotFound: ref_item = None if ref_item != None and \ (not new_attr.relCc or ref_item.getContentclass() in new_attr.relCc): oAttrRef = getattr(ref_item, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): oAttrRef.value.append(item._id) elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = item._id _db.putItem(ref_item, trans) else: new_attr.value.remove(sID) # calculate removed references lstRemoved = list(prvValue - currentValue) for sID in lstRemoved: ref_item = _db.getItem(sID, trans) oAttrRef = getattr(ref_item, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): try: oAttrRef.value.remove(item._id) except ValueError: pass elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = '' _db.putItem(ref_item, trans)
def on_delete(cls, item, attr, trans, bPermanent): if bPermanent: if item._isDeleted: func_get = _db.getDeletedItem else: func_get = _db.getItem composites = [func_get(sID, trans) for sID in attr.value] for composite in composites: cls.removeComposite(composite, trans) else: for sID in attr.value: composite = _db.getItem(sID, trans) _db.handle_delete(composite, trans, False) composite._isDeleted = True _db.putItem(composite, trans)
def _undelete(self, deletedItem, trans): """ Undeletes a logically deleted item. Returns: None """ _db.handle_update(deletedItem, None, trans) deletedItem._isDeleted = False if deletedItem.isCollection: lstChildren = deletedItem._items.values() + deletedItem._subfolders.values() for sID in lstChildren: oChild = _db.getDeletedItem(sID, trans) self._undelete(oChild, trans) _db.putItem(deletedItem, trans)
def _recycle(self, trans): """ Removes an item's references and marks it as deleted. Returns: None """ _db.handle_delete(self, trans, False) self._isDeleted = True if self.isCollection: lstChildren = self._items.values() + self._subfolders.values() for sID in lstChildren: oChild = _db.getItem(sID, trans) oChild._recycle(trans) _db.putItem(self, trans)
def on_update(cls, item, new_attr, old_attr, trans): from porcupine import datatypes # remove duplicates new_attr.value = list(set(new_attr.value)) # get previous value if old_attr: prvValue = set(old_attr.value) noAccessList = cls.getNoAccessIds(old_attr, trans) else: prvValue = set() noAccessList = [] # get current value currentValue = set(new_attr.value + noAccessList) if currentValue != prvValue: # calculate added references lstAdded = list(currentValue - prvValue) for sID in lstAdded: oItemRef = _db.getItem(sID, trans) if oItemRef.getContentclass() in new_attr.relCc: oAttrRef = getattr(oItemRef, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): oAttrRef.value.append(item._id) elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = item._id _db.putItem(oItemRef, trans) else: new_attr.value.remove(sID) # calculate removed references lstRemoved = list(prvValue - currentValue) for sID in lstRemoved: oItemRef = _db.getItem(sID, trans) oAttrRef = getattr(oItemRef, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): try: oAttrRef.value.remove(item._id) except ValueError: pass elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = '' _db.putItem(oItemRef, trans)
def on_delete(item, attr, trans, bPermanent): lstValue = attr.value if not item._isDeleted: from porcupine import datatypes if lstValue and attr.respectsReferences: raise exceptions.ReferentialIntegrityError, ( 'Cannot delete object "%s" ' % item.displayName.value + 'because it is being referenced by other objects.') # remove references for sID in lstValue: ref_item = _db.getItem(sID, trans) if ref_item.getContentclass() in attr.relCc: oAttrRef = getattr(ref_item, attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): try: oAttrRef.value.remove(item._id) except ValueError: pass elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = '' _db.putItem(ref_item, trans) else: attr.value.remove(sID) if attr.cascadeDelete: oParent = _db.getItem(oItemRef._parentid, trans) try: oParent._removeItemReference(oItemRef) _db.putItem(oParent, trans) except KeyError: pass if attr.cascadeDelete: for sID in lstValue: if item._isDeleted: oItemRef = _db.getDeletedItem(sID, trans) else: oItemRef = _db.getItem(sID, trans) if bPermanent: oItemRef._delete(trans) else: oItemRef._recycle(trans)
def on_delete(cls, item, attr, trans, bPermanent): if not item._isDeleted: from porcupine import datatypes if attr.value: if attr.respectsReferences: raise exceptions.ReferentialIntegrityError, ( 'Cannot delete object "%s" ' % item.displayName.value + 'because it is referenced by other objects.') # remove reference oItemRef = _db.getItem(attr.value, trans) oAttrRef = getattr(oItemRef, attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): try: oAttrRef.value.remove(item._id) except ValueError: pass elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = '' _db.putItem(oItemRef, trans)
def update(self, trans): """ Updates the item. @param trans: A valid transaction handle @return: None """ oOldItem = _db.getItem(self._id, trans) oUser = currentThread().context.session.user iUserRole = objectAccess.getAccess(oOldItem, oUser) if iUserRole > objectAccess.READER: # set security if iUserRole == objectAccess.COORDINATOR: # user is COORDINATOR if (self.inheritRoles != oOldItem.inheritRoles) or \ (not self.inheritRoles and self.security != oOldItem.security): oParent = _db.getItem(self._parentid, trans) self._applySecurity(oParent, trans) else: # restore previous ACL self.security = oOldItem.security self.inheritRoles = oOldItem.inheritRoles _db.handle_update(self, oOldItem, trans) self.modifiedBy = oUser.displayName.value self.modified = time.time() _db.putItem(self, trans) if self.displayName.value != oOldItem.displayName.value: oParent = _db.getItem(self._parentid, trans) oParent._removeItemReference(oOldItem) oParent._addItemReference(self) _db.putItem(oParent, trans) else: raise exceptions.PermissionDenied, \ 'The user does not have update permissions.'
def restore(self, trans): """ Restores the deleted item to its original location, if it still exists. @param trans: A valid transaction handle @return: None @raise L{porcupine.exceptions.ObjectNotFound}: If the original location no longer exists. """ ## TODO: check if oDeleted exists oDeleted = _db.getDeletedItem(self._deletedId, trans) oOriginalParent = _db.getItem(oDeleted._parentid, trans) # update container oOriginalParent._addItemReference(oDeleted) _db.putItem(oOriginalParent, trans) # try to restore original item self._restore(oDeleted, oOriginalParent, trans) self.delete(trans, False)
def on_update(item, new_attr, old_attr, trans): from porcupine import datatypes, systemObjects # get previous value if old_attr: prvValue = old_attr.value else: prvValue = '' if new_attr.value != prvValue: if new_attr.value: try: ref_item = _db.getItem(new_attr.value, trans) except exceptions.ObjectNotFound: ref_item = None if ref_item != None and \ (not new_attr.relCc or ref_item.getContentclass() in new_attr.relCc): oAttrRef = getattr(ref_item, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): oAttrRef.value.append(item._id) elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = item._id _db.putItem(ref_item, trans) else: new_attr.value = '' if prvValue: ref_item = _db.getItem(prvValue, trans) oAttrRef = getattr(ref_item, new_attr.relAttr) if isinstance(oAttrRef, datatypes.RelatorN): try: oAttrRef.value.remove(item._id) except ValueError: pass elif isinstance(oAttrRef, datatypes.Relator1): oAttrRef.value = '' _db.putItem(ref_item, trans)
def _copy(self, target, trans, clearRolesInherited=False): oCopy = self.clone() if clearRolesInherited: oCopy.inheritRoles = False oUser = currentThread().context.session.user oCopy._owner = oUser._id oCopy._created = time.time() oCopy.modifiedBy = oUser.displayName.value oCopy.modified = time.time() oCopy._parentid = target._id _db.handle_update(oCopy, None, trans) _db.putItem(oCopy, trans) if self.isCollection: lstChildrentIds = self._items.values() + self._subfolders.values() for sId in lstChildrentIds: child = _db.getItem(sId, trans) if child and objectAccess.getAccess(child, oUser): child._copy(oCopy, trans) target._addItemReference(oCopy) _db.putItem(target, trans)
def recycle(self, rbID, trans): """ Moves the item to the specified recycle bin. The item then becomes inaccesible. @param rbID: The id of the destination container, which must be a L{RecycleBin} instance @type rbID: str @param trans: A valid transaction handle @return: None """ oUser = currentThread().context.session.user self = _db.getItem(self._id, trans) iUserRole = objectAccess.getAccess(self, oUser) bCanDelete = (iUserRole > objectAccess.AUTHOR) or \ (iUserRole == objectAccess.AUTHOR and self._owner == oUser._id) if (not(self._isSystem) and bCanDelete): oDeleted = DeletedItem(self) oDeleted._owner = oUser._id oDeleted._created = time.time() oDeleted.modifiedBy = oUser.displayName.value oDeleted.modified = time.time() oDeleted._parentid = rbID _db.handle_update(oDeleted, None, trans) _db.putItem(oDeleted, trans) # delete item logically self._recycle(trans) # save container oParent = _db.getItem(self._parentid, trans) oParent._removeItemReference(self) _db.putItem(oParent, trans) #update recycle bin oRecycleBin = _db.getItem(rbID, trans) if not(oDeleted.getContentclass() in oRecycleBin.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type "%s".' % oDeleted.getContentclass() oRecycleBin._addItemReference(oDeleted) _db.putItem(oRecycleBin, trans) else: raise exceptions.PermissionDenied, \ 'The object was not deleted.\n' + \ 'The user has insufficient permissions.'
def moveTo(self, targetId, trans): """ Moves the item to the designated target. @param targetId: The ID of the destination container @type targetId: str @param trans: A valid transaction handle @return: None """ oUser = currentThread().context.session.user iUserRole = objectAccess.getAccess(self, oUser) bCanMove = (iUserRole > objectAccess.AUTHOR)## or (iUserRole == objectAccess.AUTHOR and oItem.owner == oUser.id) parentId = self._parentid oTarget = _db.getItem(targetId, trans) iUserRole2 = objectAccess.getAccess(oTarget, oUser) if self.isCollection and oTarget.isContainedIn(self._id, trans): raise exceptions.ContainmentError, \ 'Cannot move item to destination.\n' + \ 'The destination is contained in the source.' if (not(self._isSystem) and bCanMove and iUserRole2 > objectAccess.READER): if not(self.getContentclass() in oTarget.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type "%s".' % self.getContentclass() self._parentid = targetId self.inheritRoles = False _db.putItem(self, trans) #update target oTarget._addItemReference(self) _db.putItem(oTarget, trans) #update parent oParent = _db.getItem(parentId, trans) oParent._removeItemReference(self) _db.putItem(oParent, trans) else: raise exceptions.PermissionDenied, \ 'The object was not moved.\n' + \ 'The user has insufficient permissions.'
rootFolder = org.innoscript.desktop.schema.common.RootFolder() rootFolder._id = '' rootFolder.description.value = 'Root Folder' rootFolder.displayName.value = 'Porcupine Server' rootFolder._isSystem = True rootFolder._owner = sOwner rootFolder.modifiedBy = sOwner rootFolder._created = ftime rootFolder.modified = ftime rootFolder._subfolders = { 'Categories':'categories', 'Administrative Tools':'admintools', 'Personal folders':'personal' } rootFolder.security = {'everyone':1, 'administrators':8} _db.putItem(rootFolder, None) sys.stdout.write('[OK]\n') sys.stdout.write('Creating recycle bin...') rb = org.innoscript.desktop.schema.common.RecycleBin() rb._id = 'rb' rb.description.value = 'Deleted items container' rb.displayName.value = 'Recycle Bin' rb._isSystem = True rb._owner = sOwner rb.modifiedBy = sOwner rb._created = ftime rb.modified = ftime rb.inheritRoles = False rb.security = {'administrators':8} _db.putItem(rb, None)