diff --git a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java index 890cdf2..8213129 100644 --- a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java +++ b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java @@ -15,6 +15,7 @@ import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.storagehub.model.Excludes; +import org.gcube.common.storagehub.model.Paths; import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters; @@ -22,6 +23,7 @@ import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException; import org.gcube.common.storagehub.model.items.FolderItem; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; +import org.gcube.common.storagehub.model.items.TrashItem; import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,10 +45,16 @@ public class AuthorizationChecker { if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node"); + //checking if the item is in the owner trash folder + if(item instanceof TrashItem && item.getParentPath().equals(String.format("%s%s",Utils.getWorkspacePath(login).toPath(),Constants.TRASH_ROOT_FOLDER_NAME))) + return; + + if (!item.isShared() && item.getOwner()!=null && item.getOwner().equals(login)) return; if (hasParentPublicFolder(session, item)) return; - + + if (item.isShared()) { SharedFolder parentShared = node2Item.getItem(retrieveSharedFolderParent(node, session), Excludes.EXCLUDE_ACCOUNTING); @@ -110,15 +118,19 @@ public class AuthorizationChecker { } + //newItem means that a new item will be created and id is the destination directory public void checkWriteAuthorizationControl(Session session, Item item, Node node, boolean isNewItem) throws UserNotAuthorizedException, BackendGenericError, RepositoryException { String login = AuthorizationProvider.instance.get().getClient().getId(); - + if (item==null) throw new UserNotAuthorizedException("Not valid StorageHub node"); - + if (Constants.WRITE_PROTECTED_FOLDER.contains(item.getName()) || Constants.WRITE_PROTECTED_FOLDER.contains(item.getTitle())) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+item.getId()+": it's a protected folder"); - + + if (item.isTrashed()) + throw new UserNotAuthorizedException("Trashed item cannot be written"); + if (item.isShared()) { Node parentSharedNode = retrieveSharedFolderParent(node, session); JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(session, parentSharedNode.getPath()); @@ -147,6 +159,7 @@ public class AuthorizationChecker { throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+item.getId()); } + //newItem means that a new item will be created and id is the destination directory public void checkWriteAuthorizationControl(Session session, String id, boolean isNewItem) throws UserNotAuthorizedException, BackendGenericError, RepositoryException { //in case of newItem the id is the parent otherwise the old node to replace Node node = session.getNodeByIdentifier(id); @@ -159,6 +172,7 @@ public class AuthorizationChecker { public void checkMoveOpsForProtectedFolders(Session session, String id) throws InvalidCallParameters, BackendGenericError, RepositoryException { Node node = session.getNodeByIdentifier(id); Item item = node2Item.getItem(node, Excludes.ALL); + if (Constants.PROTECTED_FOLDER.contains(item.getName()) || Constants.PROTECTED_FOLDER.contains(item.getTitle())) throw new InvalidCallParameters("protected folder cannot be moved or deleted"); } diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/TrashHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/TrashHandler.java index aec6452..c3f2b19 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/TrashHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/TrashHandler.java @@ -141,7 +141,7 @@ public class TrashHandler { trashItem.setName(item.getId()); trashItem.setOriginalParentId(nodeToDelete.getParent().getIdentifier()); - trashItem.setOwner(item.getOwner()); + trashItem.setOwner(login); trashItem.setLastModificationTime(item.getLastModificationTime()); trashItem.setLastModifiedBy(item.getLastModifiedBy()); @@ -206,41 +206,45 @@ public class TrashHandler { if(originalParentExists && !originalParentTrashed) { - authChecker.checkWriteAuthorizationControl(ses, originalParentItem, originalParent, false ); destinationNode = originalParent; }else { String homeWS = Utils.getWorkspacePath(login).toPath(); Node node = ses.getNode(homeWS); - authChecker.checkWriteAuthorizationControl(ses, node.getIdentifier(), false ); destinationNode = node; } } else { Node node = ses.getNodeByIdentifier(destination.getId()); - + if (!node2Item.checkNodeType(node, FolderItem.class)) throw new InvalidCallParameters("destination Node is not a folder"); - authChecker.checkWriteAuthorizationControl(ses, node.getIdentifier(), false ); destinationNode = node; } - + + authChecker.checkWriteAuthorizationControl(ses, destinationNode.getIdentifier(), true ); + ses.getWorkspace().getLockManager().lock(destinationNode.getPath(), true, true, 0,login); - - //the real node is a child of the Trash node - List items = Utils.getItemList(ses.getNodeByIdentifier(item.getId()), Excludes.ALL, null, false, null); - if (items.size()!=1) { - log.warn("a problem occurred restoring item from trash"); - throw new BackendGenericError("An error occurred on trash item"); + String newNodePath = null; + try { + //the real node is a child of the Trash node + List items = Utils.getItemList(ses.getNodeByIdentifier(item.getId()), Excludes.ALL, null, false, null); + if (items.size()!=1) { + log.warn("a problem occurred restoring item from trash"); + throw new BackendGenericError("An error occurred on trash item"); + } + Item itemToMove = items.get(0); + + item2Node.updateOwnerOnSubTree(ses.getNodeByIdentifier(itemToMove.getId()), login); + String uniqueName = Utils.checkExistanceAndGetUniqueName(ses, destinationNode, itemToMove.getName()); + newNodePath = Paths.append(Paths.getPath(destinationNode.getPath()),uniqueName).toPath(); + ses.move(itemToMove.getPath(), newNodePath); + Utils.setPropertyOnChangeNode(ses.getNode(newNodePath), login, ItemAction.RESTORED); + ses.removeItem(item.getPath()); + ses.save(); + }catch (Exception e) { + if (ses.getWorkspace().getLockManager().isLocked(destinationNode.getPath())) + ses.getWorkspace().getLockManager().unlock(destinationNode.getPath()); } - Item itemToMove = items.get(0); - - item2Node.updateOwnerOnSubTree(ses.getNodeByIdentifier(itemToMove.getId()), login); - - String newNodePath = Paths.append(Paths.getPath(destinationNode.getPath()), itemToMove.getName()).toPath(); - ses.move(itemToMove.getPath(), newNodePath); - Utils.setPropertyOnChangeNode(ses.getNode(newNodePath), login, ItemAction.MOVED); - ses.removeItem(item.getPath()); - ses.save(); return ses.getNode(newNodePath).getIdentifier(); }