From 15f58c59c51289a88d67cb0ed5e102ea1214af35 Mon Sep 17 00:00:00 2001 From: Lucio Lelii Date: Wed, 22 May 2019 15:47:15 +0000 Subject: [PATCH] git-svn-id: https://svn.d4science-ii.research-infrastructures.eu/gcube/branches/data-access/storagehub-webapp/1.0@179520 82a268e6-3cf1-43bd-a215-b396298e98cf --- .../handlers/Node2ItemConverter.java | 17 +++- .../storagehub/handlers/TrashHandler.java | 48 ++++++----- .../storagehub/services/ACLManager.java | 84 +++++++++++-------- .../storagehub/services/ItemsManager.java | 7 +- 4 files changed, 95 insertions(+), 61 deletions(-) diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java b/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java index 6f978ca..2604bfe 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/Node2ItemConverter.java @@ -33,14 +33,13 @@ import org.gcube.common.storagehub.model.exceptions.BackendGenericError; 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.Utils; import org.reflections.Configuration; import org.reflections.Reflections; import org.reflections.util.ConfigurationBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.ClassToInstanceMap; - @Singleton public class Node2ItemConverter { @@ -58,7 +57,19 @@ public class Node2ItemConverter { public T getItem(Node node, List excludes) throws RepositoryException, BackendGenericError{ @SuppressWarnings("unchecked") Class classToHandle = (Class)ClassHandler.instance().get(node.getPrimaryNodeType().getName()); - return retrieveItem(node, excludes, classToHandle); + Node nodeToRetrieve= node; + if (SharedFolder.class.isAssignableFrom(classToHandle)) { + NodeIterator it= node.getSharedSet(); + while (it.hasNext()) { + Node sharedNode = it.nextNode(); + if (sharedNode.getPath().startsWith(Utils.getWorkspacePath().toPath())) { + nodeToRetrieve = sharedNode; + break; + } + + } + } + return retrieveItem(nodeToRetrieve, excludes, classToHandle); } 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 598924c..2bbf705 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 @@ -42,33 +42,39 @@ public class TrashHandler { @Inject AuthorizationChecker authChecker; - + @Inject Item2NodeConverter item2Node; - public void removeNodes(Session ses, List itemsToDelete) throws RepositoryException{ + + public void removeNodes(Session ses, List itemsToDelete) throws RepositoryException, BackendGenericError{ log.debug("defnitively removing nodes with ids {}",itemsToDelete); + for (Item item: itemsToDelete) { + removeNodesInternally(ses, item); + } + } + + private void removeNodesInternally(Session ses, Item itemToDelete) throws RepositoryException, BackendGenericError { final String login = AuthorizationProvider.instance.get().getClient().getId(); - final Node trashFolder = ses.getNode(Paths.append(Utils.getWorkspacePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath()); - //String parentPath = itemToDelete.getParentPath(); + try { - ses.getWorkspace().getLockManager().lock(trashFolder.getPath(), true, true, 0,login); + ses.getWorkspace().getLockManager().lock(itemToDelete.getPath(), true, true, 0,login); Set contentIdsToDelete = new HashSet<>(); - for (Item trashItem: itemsToDelete) { - try { - Node trashItemNode = ses.getNodeByIdentifier(trashItem.getId()); - List trashChildren = Utils.getItemList(trashItemNode, Excludes.GET_ONLY_CONTENT, null, true, null); - for (Item itemContentToRetrieve: trashChildren) - Utils.getAllContentIds(ses, contentIdsToDelete, itemContentToRetrieve, versionHandler); - trashItemNode.remove(); - }catch (Exception e) { - log.warn("error removing item with id {}",trashItem.getId(), e); - } + Node nodeToDelete = ses.getNodeByIdentifier(itemToDelete.getId()); + + if (itemToDelete instanceof TrashItem) { + List trashChildren = Utils.getItemList(nodeToDelete, Excludes.GET_ONLY_CONTENT, null, true, null); + for (Item itemContentToRetrieve: trashChildren) + Utils.getAllContentIds(ses, contentIdsToDelete, itemContentToRetrieve, versionHandler); + } else { + Utils.getAllContentIds(ses, contentIdsToDelete, itemToDelete, versionHandler); } + nodeToDelete.remove(); + log.debug("content ids to remove are {}",contentIdsToDelete); - - + + //TODO: make it as an authorizableTask String user = AuthorizationProvider.instance.get().getClient().getId(); new Thread() { @@ -87,12 +93,13 @@ public class TrashHandler { } }.start();; ses.save(); + }catch (Exception e) { + throw new BackendGenericError("error permanetly deleting items",e); }finally { - ses.getWorkspace().getLockManager().unlock(trashFolder.getPath()); + ses.getWorkspace().getLockManager().unlock(itemToDelete.getPath()); } } - public void moveToTrash(Session ses, Node nodeToDelete, Item item) throws RepositoryException, BackendGenericError{ log.debug("moving node {} to trash ",item.getId()); final Node trashFolder = ses.getNode(Paths.append(Utils.getWorkspacePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath()); @@ -148,10 +155,11 @@ public class TrashHandler { if (item instanceof AbstractFileItem) { if (((AbstractFileItem)item).getContent()!=null) mimetype = ((AbstractFileItem) item).getContent().getMimeType(); - else log.warn("the AbstractFileItem with id {} has no content (check it!!)", item.getId()); + else log.warn("the AbstractFileItem with id {} has no content (check it!!)", item.getId()); } accountingHandler.createFolderRemoveObj(item.getName(), item.getClass().getSimpleName(), mimetype, ses, ses.getNodeByIdentifier(item.getParentId()), true); }catch(Throwable t) { + log.error("error exceuting move to trash",t); throw new BackendGenericError(t); }finally { ses.getWorkspace().getLockManager().unlock(nodeToDelete.getPath()); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java b/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java index 4618eb9..c3001d7 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java @@ -13,6 +13,7 @@ import javax.jcr.security.AccessControlEntry; import javax.jcr.security.AccessControlManager; import javax.jcr.security.Privilege; import javax.servlet.ServletContext; +import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.PUT; @@ -40,6 +41,7 @@ import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.handlers.CredentialHandler; import org.gcube.data.access.storagehub.handlers.Node2ItemConverter; import org.gcube.smartgears.utils.InnerMethodName; +import org.glassfish.jersey.media.multipart.FormDataParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,10 +62,10 @@ public class ACLManager { @Inject Node2ItemConverter node2Item; - + @Inject AuthorizationChecker authChecker; - + /** * returns the AccessType for all the users in a shared folder * @@ -96,7 +98,7 @@ public class ACLManager { acl.setAccessTypes(types); acls.add(acl); } - + }catch(RepositoryException re){ log.error("jcr error getting acl", re); GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting acl", re)); @@ -108,7 +110,7 @@ public class ACLManager { ses.logout(); } return new ACLList(acls); - + } /** @@ -124,46 +126,60 @@ public class ACLManager { * @exception {@link InvalidItemException} when the folder is not share */ @PUT + @Consumes(MediaType.MULTIPART_FORM_DATA) @Path("{id}/acls") - public void setACL(@FormParam("user") String user, @FormParam("access") AccessType accessType) { + public void setACL(@FormDataParam("user") String user, @FormDataParam("access") AccessType accessType) { InnerMethodName.instance.set("setACLById"); Session ses = null; try{ ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - + Node node = ses.getNodeByIdentifier(id); - + Item item = node2Item.getItem(node, Excludes.ALL); - - if (!(item instanceof SharedFolder) || ((SharedFolder) item).isVreFolder() ) + + if (!(item instanceof SharedFolder)) throw new InvalidItemException("the item is not a shared folder"); - + authChecker.checkAdministratorControl(ses, (SharedFolder) item); - - if (!((SharedFolder) item).getUsers().getMap().containsKey(user)) - throw new InvalidCallParameters("shared folder with id "+item.getId()+" is not shared with user "+user); - - String path = node.getPath(); - - AccessControlManager acm = ses.getAccessControlManager(); - JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, path); - Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(accessType.getValue()) }; - AccessControlEntry aceToDelete = null;; - Principal principal = AccessControlUtils.getPrincipal(ses, user); - for (AccessControlEntry ace : acls.getAccessControlEntries()) - if (ace.getPrincipal().equals(principal)) { - aceToDelete = ace; - break; - } - - - if (aceToDelete!= null) - acls.removeAccessControlEntry(aceToDelete); - acls.addAccessControlEntry(principal, userPrivileges); - acm.setPolicy(path, acls); - ses.save(); + SharedFolder folder = ((SharedFolder)item); + if (folder.isVreFolder()) { + if (accessType!=AccessType.ADMINISTRATOR) + throw new InvalidCallParameters("acls in vreFolder cannot be changed, only new admin can be set"); + + + + //TODO if is a VRE FOLDER + + } else { + + + if (!((SharedFolder) item).getUsers().getMap().containsKey(user)) + throw new InvalidCallParameters("shared folder with id "+item.getId()+" is not shared with user "+user); + + String path = node.getPath(); + + AccessControlManager acm = ses.getAccessControlManager(); + JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, path); + Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(accessType.getValue()) }; + + AccessControlEntry aceToDelete = null;; + Principal principal = AccessControlUtils.getPrincipal(ses, user); + for (AccessControlEntry ace : acls.getAccessControlEntries()) + if (ace.getPrincipal().equals(principal)) { + aceToDelete = ace; + break; + } + + if (aceToDelete!= null) + acls.removeAccessControlEntry(aceToDelete); + acls.addAccessControlEntry(principal, userPrivileges); + acm.setPolicy(path, acls); + ses.save(); + } + }catch(RepositoryException re){ log.error("jcr error extracting archive", re); GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error setting acl", re)); @@ -174,7 +190,7 @@ public class ACLManager { if (ses!=null) ses.logout(); } - + } } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java index cdf081e..09c6020 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsManager.java @@ -968,10 +968,9 @@ public class ItemsManager { @DELETE @Path("{id}") - public Response deleteItem(){ + public Response deleteItem(@QueryParam("force") boolean force){ InnerMethodName.instance.set("deleteItem"); - - //TODO: check also that is not already trashed + Session ses = null; try{ @@ -991,7 +990,7 @@ public class ItemsManager { log.debug("item is trashed? {}", itemToDelete.isTrashed()); - if (!itemToDelete.isTrashed()) + if (!force && !itemToDelete.isTrashed() ) trashHandler.moveToTrash(ses, nodeToDelete, itemToDelete); else trashHandler.removeNodes(ses, Collections.singletonList(itemToDelete));