This commit is contained in:
Lucio Lelii 2019-05-22 15:47:15 +00:00
parent 9c4699b57e
commit 15f58c59c5
4 changed files with 95 additions and 61 deletions

View File

@ -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.Item;
import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.common.storagehub.model.items.SharedFolder;
import org.gcube.common.storagehub.model.items.TrashItem; import org.gcube.common.storagehub.model.items.TrashItem;
import org.gcube.data.access.storagehub.Utils;
import org.reflections.Configuration; import org.reflections.Configuration;
import org.reflections.Reflections; import org.reflections.Reflections;
import org.reflections.util.ConfigurationBuilder; import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.common.collect.ClassToInstanceMap;
@Singleton @Singleton
public class Node2ItemConverter { public class Node2ItemConverter {
@ -58,7 +57,19 @@ public class Node2ItemConverter {
public <T extends Item> T getItem(Node node, List<String> excludes) throws RepositoryException, BackendGenericError{ public <T extends Item> T getItem(Node node, List<String> excludes) throws RepositoryException, BackendGenericError{
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Class<T> classToHandle = (Class<T>)ClassHandler.instance().get(node.getPrimaryNodeType().getName()); Class<T> classToHandle = (Class<T>)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);
} }

View File

@ -42,33 +42,39 @@ public class TrashHandler {
@Inject @Inject
AuthorizationChecker authChecker; AuthorizationChecker authChecker;
@Inject @Inject
Item2NodeConverter item2Node; Item2NodeConverter item2Node;
public void removeNodes(Session ses, List<Item> itemsToDelete) throws RepositoryException{
public void removeNodes(Session ses, List<Item> itemsToDelete) throws RepositoryException, BackendGenericError{
log.debug("defnitively removing nodes with ids {}",itemsToDelete); 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 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 { try {
ses.getWorkspace().getLockManager().lock(trashFolder.getPath(), true, true, 0,login); ses.getWorkspace().getLockManager().lock(itemToDelete.getPath(), true, true, 0,login);
Set<String> contentIdsToDelete = new HashSet<>(); Set<String> contentIdsToDelete = new HashSet<>();
for (Item trashItem: itemsToDelete) { Node nodeToDelete = ses.getNodeByIdentifier(itemToDelete.getId());
try {
Node trashItemNode = ses.getNodeByIdentifier(trashItem.getId()); if (itemToDelete instanceof TrashItem) {
List<Item> trashChildren = Utils.getItemList(trashItemNode, Excludes.GET_ONLY_CONTENT, null, true, null); List<Item> trashChildren = Utils.getItemList(nodeToDelete, Excludes.GET_ONLY_CONTENT, null, true, null);
for (Item itemContentToRetrieve: trashChildren) for (Item itemContentToRetrieve: trashChildren)
Utils.getAllContentIds(ses, contentIdsToDelete, itemContentToRetrieve, versionHandler); Utils.getAllContentIds(ses, contentIdsToDelete, itemContentToRetrieve, versionHandler);
trashItemNode.remove(); } else {
}catch (Exception e) { Utils.getAllContentIds(ses, contentIdsToDelete, itemToDelete, versionHandler);
log.warn("error removing item with id {}",trashItem.getId(), e);
}
} }
nodeToDelete.remove();
log.debug("content ids to remove are {}",contentIdsToDelete); log.debug("content ids to remove are {}",contentIdsToDelete);
//TODO: make it as an authorizableTask //TODO: make it as an authorizableTask
String user = AuthorizationProvider.instance.get().getClient().getId(); String user = AuthorizationProvider.instance.get().getClient().getId();
new Thread() { new Thread() {
@ -87,12 +93,13 @@ public class TrashHandler {
} }
}.start();; }.start();;
ses.save(); ses.save();
}catch (Exception e) {
throw new BackendGenericError("error permanetly deleting items",e);
}finally { }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{ public void moveToTrash(Session ses, Node nodeToDelete, Item item) throws RepositoryException, BackendGenericError{
log.debug("moving node {} to trash ",item.getId()); log.debug("moving node {} to trash ",item.getId());
final Node trashFolder = ses.getNode(Paths.append(Utils.getWorkspacePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath()); 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 (item instanceof AbstractFileItem) {
if (((AbstractFileItem)item).getContent()!=null) if (((AbstractFileItem)item).getContent()!=null)
mimetype = ((AbstractFileItem) item).getContent().getMimeType(); 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); accountingHandler.createFolderRemoveObj(item.getName(), item.getClass().getSimpleName(), mimetype, ses, ses.getNodeByIdentifier(item.getParentId()), true);
}catch(Throwable t) { }catch(Throwable t) {
log.error("error exceuting move to trash",t);
throw new BackendGenericError(t); throw new BackendGenericError(t);
}finally { }finally {
ses.getWorkspace().getLockManager().unlock(nodeToDelete.getPath()); ses.getWorkspace().getLockManager().unlock(nodeToDelete.getPath());

View File

@ -13,6 +13,7 @@ import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlManager; import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege; import javax.jcr.security.Privilege;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam; import javax.ws.rs.FormParam;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.PUT; 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.CredentialHandler;
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter; import org.gcube.data.access.storagehub.handlers.Node2ItemConverter;
import org.gcube.smartgears.utils.InnerMethodName; import org.gcube.smartgears.utils.InnerMethodName;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -60,10 +62,10 @@ public class ACLManager {
@Inject Node2ItemConverter node2Item; @Inject Node2ItemConverter node2Item;
@Inject @Inject
AuthorizationChecker authChecker; AuthorizationChecker authChecker;
/** /**
* returns the AccessType for all the users in a shared folder * returns the AccessType for all the users in a shared folder
* *
@ -96,7 +98,7 @@ public class ACLManager {
acl.setAccessTypes(types); acl.setAccessTypes(types);
acls.add(acl); acls.add(acl);
} }
}catch(RepositoryException re){ }catch(RepositoryException re){
log.error("jcr error getting acl", re); log.error("jcr error getting acl", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting acl", re)); GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting acl", re));
@ -108,7 +110,7 @@ public class ACLManager {
ses.logout(); ses.logout();
} }
return new ACLList(acls); return new ACLList(acls);
} }
/** /**
@ -124,46 +126,60 @@ public class ACLManager {
* @exception {@link InvalidItemException} when the folder is not share * @exception {@link InvalidItemException} when the folder is not share
*/ */
@PUT @PUT
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("{id}/acls") @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"); InnerMethodName.instance.set("setACLById");
Session ses = null; Session ses = null;
try{ try{
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
Node node = ses.getNodeByIdentifier(id); Node node = ses.getNodeByIdentifier(id);
Item item = node2Item.getItem(node, Excludes.ALL); 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"); throw new InvalidItemException("the item is not a shared folder");
authChecker.checkAdministratorControl(ses, (SharedFolder) item); 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;; SharedFolder folder = ((SharedFolder)item);
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();
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){ }catch(RepositoryException re){
log.error("jcr error extracting archive", re); log.error("jcr error extracting archive", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error setting acl", re)); GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error setting acl", re));
@ -174,7 +190,7 @@ public class ACLManager {
if (ses!=null) if (ses!=null)
ses.logout(); ses.logout();
} }
} }
} }

View File

@ -968,10 +968,9 @@ public class ItemsManager {
@DELETE @DELETE
@Path("{id}") @Path("{id}")
public Response deleteItem(){ public Response deleteItem(@QueryParam("force") boolean force){
InnerMethodName.instance.set("deleteItem"); InnerMethodName.instance.set("deleteItem");
//TODO: check also that is not already trashed
Session ses = null; Session ses = null;
try{ try{
@ -991,7 +990,7 @@ public class ItemsManager {
log.debug("item is trashed? {}", itemToDelete.isTrashed()); log.debug("item is trashed? {}", itemToDelete.isTrashed());
if (!itemToDelete.isTrashed()) if (!force && !itemToDelete.isTrashed() )
trashHandler.moveToTrash(ses, nodeToDelete, itemToDelete); trashHandler.moveToTrash(ses, nodeToDelete, itemToDelete);
else else
trashHandler.removeNodes(ses, Collections.singletonList(itemToDelete)); trashHandler.removeNodes(ses, Collections.singletonList(itemToDelete));