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.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 extends Item> T getItem(Node node, List<String> excludes) throws RepositoryException, BackendGenericError{
@SuppressWarnings("unchecked")
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
AuthorizationChecker authChecker;
@Inject
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);
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<String> contentIdsToDelete = new HashSet<>();
for (Item trashItem: itemsToDelete) {
try {
Node trashItemNode = ses.getNodeByIdentifier(trashItem.getId());
List<Item> 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<Item> 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());

View File

@ -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();
}
}
}

View File

@ -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));