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 49d978f..fcccbb5 100644 --- a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java +++ b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java @@ -5,8 +5,13 @@ import java.util.Arrays; import javax.inject.Singleton; import javax.jcr.Node; import javax.jcr.Session; +import javax.jcr.security.AccessControlEntry; +import javax.jcr.security.Privilege; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; +import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.data.access.storagehub.handlers.ItemHandler; @@ -21,18 +26,47 @@ public class AuthorizationChecker { if (item.isShared()) { SharedFolder parentShared = retrieveSharedFolderParent(item, session); - if (!parentShared.getUsers().getValue().containsKey(AuthorizationProvider.instance.get().getClient().getId())) + if (!parentShared.getUsers().getValues().containsKey(AuthorizationProvider.instance.get().getClient().getId())) throw new IllegalAccessException("Insufficent Provileges to read node with id "+id); } else if (!node.getProperty("hl:portalLogin").getString().equals(AuthorizationProvider.instance.get().getClient().getId())) throw new IllegalAccessException("Insufficent Provileges to read node with id "+id); } - + private SharedFolder retrieveSharedFolderParent(Item item, Session session) throws Exception{ if (item instanceof SharedFolder) return (SharedFolder)item; else return retrieveSharedFolderParent(ItemHandler.getItem(session.getNodeByIdentifier(item.getParentId()), Arrays.asList("hl:accounting","jcr:content")), session); + + } + + public void checkWriteAuthorizationControl(Session session, String id) throws Exception { + + Node node = session.getNodeByIdentifier(id); + + Item item = ItemHandler.getItem(node, Arrays.asList("hl:accounting","jcr:content")); + + if (item.isShared()) { + //put it in a different method + JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(session, node.getPath()); + AccessControlEntry[] entries = accessControlList.getAccessControlEntries(); + for (AccessControlEntry entry: entries) { + if (entry.getPrincipal().equals(AuthorizationProvider.instance.get().getClient().getId())) { + for (Privilege privilege : entry.getPrivileges()){ + AccessType access = AccessType.valueOf(privilege.getName()); + if (access==AccessType.ADMINISTRATOR || access==AccessType.WRITE_ALL || (access==AccessType.WRITE_OWNER && item.getOwner().equals(AuthorizationProvider.instance.get().getClient().getId()))) + return; + else throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); + } + } + } + throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); + } else + if(!item.getOwner().equals(AuthorizationProvider.instance.get().getClient().getId())) + throw new IllegalAccessException("Insufficent Provileges to write node with id "+id); } - + + + } diff --git a/src/main/java/org/gcube/data/access/storagehub/StorageHub.java b/src/main/java/org/gcube/data/access/storagehub/StorageHub.java index dad2906..5630f91 100644 --- a/src/main/java/org/gcube/data/access/storagehub/StorageHub.java +++ b/src/main/java/org/gcube/data/access/storagehub/StorageHub.java @@ -6,6 +6,7 @@ import java.util.Set; import javax.ws.rs.Path; import javax.ws.rs.core.Application; +import org.gcube.data.access.storagehub.services.ACLManager; import org.gcube.data.access.storagehub.services.ItemsCreator; import org.gcube.data.access.storagehub.services.ItemsManager; import org.gcube.data.access.storagehub.services.WorkspaceManager; @@ -22,6 +23,7 @@ public class StorageHub extends Application { classes.add(WorkspaceManager.class); classes.add(ItemsManager.class); classes.add(ItemsCreator.class); + classes.add(ACLManager.class); return classes; } diff --git a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java index 521e7ab..555b96d 100644 --- a/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/accounting/AccountingHandler.java @@ -7,9 +7,6 @@ import javax.inject.Singleton; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; -import javax.jcr.UnsupportedRepositoryOperationException; -import javax.jcr.version.Version; -import javax.jcr.version.VersionManager; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.storagehub.model.items.nodes.accounting.AccountingEntryType; @@ -42,15 +39,39 @@ public class AccountingHandler { accountingNode.setProperty("hl:date", Calendar.getInstance()); accountingNode.setProperty("hl:itemName", title); - try { - VersionManager vManager = ses.getWorkspace().getVersionManager(); + /*try { + //VersionManager vManager = ses.getWorkspace().getVersionManager(); //VersionManager versionManager = session.getWorkspace().getVersionManager(); //Version version = versionManager.checkin(node.getPath()); - Version version = vManager.getBaseVersion(node.getNode("jcr:content").getPath()); - accountingNode.setProperty("hl:version", version.getName()); + //Version version = vManager.getBaseVersion(node.getNode("jcr:content").getPath()); + //accountingNode.setProperty("hl:version", version.getName()); }catch(UnsupportedRepositoryOperationException uropex) { logger.warn("version cannot be retrieved", uropex); + }*/ + if (saveHistory) ses.save(); + } catch (RepositoryException e) { + logger.warn("error trying to retrieve accountign node",e); + } + } + + + public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node node, boolean saveHistory ) { + try { + Node directoryNode = node.getParent(); + + if (!directoryNode.hasNode(NodeProperty.ACCOUNTING.toString())){ + directoryNode.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString()); } + + Node accountingNodeParent = directoryNode.getNode(NodeProperty.ACCOUNTING.toString()); + Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.ADD.getNodeTypeDefinition()); + accountingNode.setProperty("hl:user", AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty("hl:date", Calendar.getInstance()); + accountingNode.setProperty("hl:itemName", title); + accountingNode.setProperty("hl:itemType", itemType); + if (mimeType!=null) + accountingNode.setProperty("hl:mimeType", mimeType); + if (saveHistory) ses.save(); } catch (RepositoryException e) { logger.warn("error trying to retrieve accountign node",e); diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java index 79d15ab..eea538f 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/ItemHandler.java @@ -105,7 +105,7 @@ public class ItemHandler { }catch(PathNotFoundException e){ logger.debug("the current node dosn't contain {} property",attribute.value()); } catch (Exception e ) { - logger.warn("error setting value",e); + logger.warn("error setting value for property {} ",attribute.value()); } } else if (field.isAnnotationPresent(NodeAttribute.class)){ String fieldNodeName = field.getAnnotation(NodeAttribute.class).value(); @@ -322,6 +322,7 @@ public class ItemHandler { for (Field field : retrieveAllFields(item.getClass())){ if (field.isAnnotationPresent(Attribute.class)){ Attribute attribute = field.getAnnotation(Attribute.class); + if (attribute.isReadOnly()) continue; field.setAccessible(true); try{ //Class returnType = field.getType(); @@ -361,6 +362,7 @@ public class ItemHandler { for (Field field : retrieveAllFields(object.getClass())){ if (field.isAnnotationPresent(Attribute.class)){ Attribute attribute = field.getAnnotation(Attribute.class); + if (attribute.isReadOnly()) continue; field.setAccessible(true); try{ @SuppressWarnings("rawtypes") diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/content/ContentHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/content/ContentHandler.java index f446d47..1dbbc27 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/content/ContentHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/content/ContentHandler.java @@ -1,7 +1,6 @@ package org.gcube.data.access.storagehub.handlers.content; import java.io.InputStream; -import java.util.List; import org.gcube.common.storagehub.model.items.AbstractFileItem; import org.gcube.common.storagehub.model.items.nodes.Content; 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 new file mode 100644 index 0000000..dc54d97 --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/services/ACLManager.java @@ -0,0 +1,88 @@ +package org.gcube.data.access.storagehub.services; + +import java.util.ArrayList; +import java.util.List; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; +import javax.jcr.security.AccessControlEntry; +import javax.jcr.security.Privilege; +import javax.servlet.ServletContext; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; +import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; +import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.provider.CalledMethodProvider; +import org.gcube.common.storagehub.model.acls.ACL; +import org.gcube.common.storagehub.model.acls.AccessType; +import org.gcube.common.storagehub.model.types.ACLList; +import org.gcube.data.access.storagehub.AuthorizationChecker; +import org.gcube.data.access.storagehub.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("item") +public class ACLManager { + + private static final Logger log = LoggerFactory.getLogger(ACLManager.class); + + @Inject + RepositoryInitializer repository; + + @RequestScoped + @PathParam("id") + String id; + + @Context + ServletContext context; + + @Inject + AuthorizationChecker authChecker; + + + @Produces(MediaType.APPLICATION_JSON) + @GET + @Path("{id}/acls") + public ACLList getACL() { + CalledMethodProvider.instance.set("getACLById"); + Session ses = null; + List acls = new ArrayList<>(); + try{ + ses = repository.getRepository().login(new SimpleCredentials(context.getInitParameter(Constants.ADMIN_PARAM_NAME),context.getInitParameter(Constants.ADMIN_PARAM_PWD).toCharArray())); + authChecker.checkReadAuthorizationControl(ses, id); + JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(ses, ses.getNodeByIdentifier(id).getPath()); + for (AccessControlEntry aclEntry : accessControlList.getAccessControlEntries()) { + ACL acl = new ACL(); + acl.setPricipal(aclEntry.getPrincipal().getName()); + List types = new ArrayList<>(); + for (Privilege priv : aclEntry.getPrivileges()) + try { + types.add(AccessType.fromValue(priv.getName())); + }catch (Exception e) { + log.warn(priv.getName()+" cannot be mapped to AccessTypes",e); + } + acl.setAccessTypes(types); + acls.add(acl); + } + return new ACLList(acls); + }catch (Exception e) { + log.error("error gettign ACL",e); + throw new WebApplicationException(e); + }finally{ + if (ses!=null) + ses.logout(); + } + + + } + +} diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java index 894953b..50c14d3 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemsCreator.java @@ -3,6 +3,7 @@ package org.gcube.data.access.storagehub.services; import java.io.BufferedInputStream; import java.io.InputStream; import java.util.Arrays; +import java.util.Calendar; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -19,6 +20,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -34,10 +36,13 @@ import org.gcube.common.storagehub.model.items.AbstractFileItem; import org.gcube.common.storagehub.model.items.FolderItem; import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.service.ItemWrapper; +import org.gcube.common.storagehub.model.types.ItemAction; +import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; import org.gcube.data.access.storagehub.MetaInfo; import org.gcube.data.access.storagehub.MultipleOutputStream; import org.gcube.data.access.storagehub.Utils; +import org.gcube.data.access.storagehub.accounting.AccountingHandler; import org.gcube.data.access.storagehub.handlers.ItemHandler; import org.gcube.data.access.storagehub.handlers.VersionHandler; import org.gcube.data.access.storagehub.handlers.content.ContentHandler; @@ -64,9 +69,18 @@ public class ItemsCreator { @Inject VersionHandler versionHandler; + @Inject + AuthorizationChecker authChecker; + + @Inject + AccountingHandler accountingHandler; + @POST + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + @Produces(MediaType.APPLICATION_JSON) @Path("/{id}/create/{type:(?!FILE)[^/?$]*}") - public Response createItem(@Context UriInfo uriInfo, @PathParam("id") String id, @PathParam("type") String type){ + public Response createItem(@Context UriInfo uriInfo, @PathParam("id") String id, @PathParam("type") String type,@QueryParam("name") String name, @QueryParam("description") String description){ + CalledMethodProvider.instance.set(String.format("createItem(%s)",type)); log.info("create generic item called"); Session ses = null; Item destinationItem = null; @@ -79,30 +93,45 @@ public class ItemsCreator { //validate input parameters for Item Type + if(!type.equals("FOLDER")) throw new IllegalAccessException("invalid item type"); + log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); Node destination = ses.getNodeByIdentifier(id); destinationItem = ItemHandler.getItem(destination,Arrays.asList("hl:accounting","jcr:content")); + + if (!(destinationItem instanceof FolderItem)) throw new Exception("an Item must be created into a directory"); - if (!(destinationItem instanceof FolderItem)) throw new Exception("an Item must be copyed to another directory"); - - //TODO: write control - if (!destinationItem.getOwner().equals(login)){ - /*AccessControlManager accessControlManager = ses.getAccessControlManager(); - boolean canWrite = accessControlManager.hasPrivileges(path, new Privilege[] { - accessControlManager.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES)});*/ - //if (!canWrite) - - throw new IllegalAccessException("Insufficent Provileges to write in "+destinationItem.getPath()); - } - - //ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); - - //TODO for now only owner of the destination folder can move file + authChecker.checkWriteAuthorizationControl(ses, destinationItem.getId()); + + ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); + + FolderItem item = new FolderItem(); + Calendar now = Calendar.getInstance(); + item.setName(name); + item.setTitle(name); + item.setDescription(description); + //item.setCreationTime(now); + item.setHidden(false); + item.setLastAction(ItemAction.CREATED); + item.setLastModificationTime(now); + item.setLastModifiedBy(login); + item.setOwner(login); + + //to inherit hidden property + item.setHidden(destinationItem.isHidden()); + + log.debug("item prepared, fulfilling content"); + log.debug("content prepared"); + Node newnode = ItemHandler.createNodeFromItem(ses, destination, item); + accountingHandler.createFolderAddObj(name, type, null, ses, newnode, false); ses.save(); + log.info("item correctly created"); + return Response.ok(new ItemWrapper<>(item)).build(); + }catch(Exception e){ log.error("error creating item", e); - return Response.serverError().build(); + throw new WebApplicationException(e); } finally{ if (ses!=null){ if (destinationItem!=null) @@ -114,7 +143,6 @@ public class ItemsCreator { ses.logout(); } } - return Response.ok().build(); } @@ -125,7 +153,7 @@ public class ItemsCreator { @Path("/{id}/create/FILE") public Response createFileItem(InputStream stream , @PathParam("id") String id, @QueryParam("name") String name, @QueryParam("description") String description){ - CalledMethodProvider.instance.set("createFileItem"); + CalledMethodProvider.instance.set(String.format("createItem(FILE)")); log.info("create file called"); Session ses = null; Item destinationItem = null; @@ -136,36 +164,27 @@ public class ItemsCreator { //TODO check if it is possible to change all the ACL on a workspace ses = repository.getRepository().login(new SimpleCredentials(context.getInitParameter(Constants.ADMIN_PARAM_NAME),context.getInitParameter(Constants.ADMIN_PARAM_PWD).toCharArray())); - //validate input parameters for Item Type - + //TODO: validate input parameters for Item Type log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); Node destination = ses.getNodeByIdentifier(id); destinationItem = ItemHandler.getItem(destination,Arrays.asList("hl:accounting","jcr:content")); log.debug("destination item path is {}",destinationItem.getPath()); if (!(destinationItem instanceof FolderItem)) throw new Exception("an Item must be copyed to another directory"); - - //TODO: write control - if (!destinationItem.getOwner().equals(login)){ - /*AccessControlManager accessControlManager = ses.getAccessControlManager(); - boolean canWrite = accessControlManager.hasPrivileges(path, new Privilege[] { - accessControlManager.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES)});*/ - //if (!canWrite) - - throw new IllegalAccessException("Insufficent Provileges to write in "+destinationItem.getPath()); - } - - + authChecker.checkWriteAuthorizationControl(ses, destinationItem.getId()); ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); - ContentHandler handler = getContentHandler(stream , name, destinationItem.getPath()); AbstractFileItem item =handler.buildItem(name, description, login); + //to inherit hidden property + item.setHidden(destinationItem.isHidden()); + log.debug("item prepared, fulfilling content"); log.debug("content prepared"); Node newNode = ItemHandler.createNodeFromItem(ses, destination, item); + accountingHandler.createFolderAddObj(name, "FILE", item.getContent().getMimeType(), ses, newNode, false); versionHandler.makeVersionableContent(newNode, ses); ses.save(); versionHandler.checkinContentNode(newNode, ses);; @@ -251,17 +270,4 @@ public class ItemsCreator { } - - - /* - private boolean hasSharedChildren(FolderItem folder, Session session) throws Exception{ - Node currentNode = session.getNodeByIdentifier(folder.getId()); - for (Item item : Utils.getItemList(currentNode,Arrays.asList("hl:accounting","jcr:content"), null)){ - if (item instanceof FolderItem) - return (item instanceof SharedFolder) || hasSharedChildren((FolderItem)item, session); - } - return false; - - }*/ - } 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 8497453..3b234b3 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 @@ -5,7 +5,9 @@ import java.io.OutputStream; import java.net.URL; import java.util.Arrays; import java.util.Deque; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.zip.Deflater; import java.util.zip.ZipOutputStream; @@ -28,6 +30,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.provider.CalledMethodProvider; import org.gcube.common.storagehub.model.Paths; import org.gcube.common.storagehub.model.items.AbstractFileItem; import org.gcube.common.storagehub.model.items.FolderItem; @@ -73,15 +76,13 @@ public class ItemsManager { @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public ItemWrapper getById(@QueryParam("exclude") List excludes){ + CalledMethodProvider.instance.set("getById"); Session ses = null; Item toReturn = null; try{ String login = AuthorizationProvider.instance.get().getClient().getId(); - long start = System.currentTimeMillis(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); authChecker.checkReadAuthorizationControl(ses, id); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - log.info("excludes is {}",excludes); toReturn = ItemHandler.getItem(ses.getNodeByIdentifier(id), excludes); }catch(Throwable e){ log.error("error reading the node children of {}",id,e); @@ -99,15 +100,13 @@ public class ItemsManager { @Path("{id}/children/count") @Produces(MediaType.APPLICATION_JSON) public Long countById(@QueryParam("showHidden") Boolean showHidden, @QueryParam("exclude") List excludes){ + CalledMethodProvider.instance.set("countById"); Session ses = null; Long toReturn = null; try{ String login = AuthorizationProvider.instance.get().getClient().getId(); - long start = System.currentTimeMillis(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); authChecker.checkReadAuthorizationControl(ses, id); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - log.info("excludes is {}",excludes); toReturn = Utils.getItemCount(ses.getNodeByIdentifier(id), showHidden==null?false:showHidden); }catch(Throwable e){ log.error("error reading the node children of {}",id,e); @@ -123,15 +122,13 @@ public class ItemsManager { @Path("{id}/children") @Produces(MediaType.APPLICATION_JSON) public ItemList listById(@QueryParam("showHidden") Boolean showHidden, @QueryParam("exclude") List excludes){ + CalledMethodProvider.instance.set("listById"); Session ses = null; List toReturn = null; try{ String login = AuthorizationProvider.instance.get().getClient().getId(); - long start = System.currentTimeMillis(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); authChecker.checkReadAuthorizationControl(ses, id); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - log.info("excludes is {}",excludes); toReturn = Utils.getItemList(ses.getNodeByIdentifier(id), excludes, null, showHidden==null?false:showHidden); }catch(Throwable e){ log.error("error reading the node children of {}",id,e); @@ -148,14 +145,13 @@ public class ItemsManager { @Path("{id}/children/paged") @Produces(MediaType.APPLICATION_JSON) public ItemList listByIdPaged(@QueryParam("showHidden") Boolean showHidden, @QueryParam("start") Integer start, @QueryParam("limit") Integer limit, @QueryParam("exclude") List excludes){ + CalledMethodProvider.instance.set("listByIdPaged"); Session ses = null; List toReturn = null; try{ String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); authChecker.checkReadAuthorizationControl(ses, id); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - log.info("excludes is {}",excludes); toReturn = Utils.getItemList(ses.getNodeByIdentifier(id), excludes, new Range(start, limit),showHidden==null?false:showHidden); }catch(Throwable e){ log.error("error reading the node children of {}",id,e); @@ -171,6 +167,7 @@ public class ItemsManager { @GET @Path("{id}/publiclink") public URL getPubliclink() { + CalledMethodProvider.instance.set("getPubliclink"); //TODO: check who can call this method Session ses = null; try{ @@ -189,22 +186,59 @@ public class ItemsManager { } + @GET + @Path("{id}/anchestors") + @Produces(MediaType.APPLICATION_JSON) + public ItemList getAnchestors(@QueryParam("exclude") List excludes){ + CalledMethodProvider.instance.set("getAnchestors"); + org.gcube.common.storagehub.model.Path absolutePath = Utils.getHomePath(); + Session ses = null; + List toReturn = new LinkedList<>(); + try{ + String login = AuthorizationProvider.instance.get().getClient().getId(); + ses = repository.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); + authChecker.checkReadAuthorizationControl(ses, id); + Item currentItem = ItemHandler.getItem(ses.getNodeByIdentifier(id), excludes); + log.trace("current node is {}",currentItem.getPath()); + while (!(currentItem.getPath()+"/").equals(absolutePath.toPath())) { + if (currentItem instanceof SharedFolder){ + Map users = ((SharedFolder) currentItem).getUsers().getValues(); + String[] user = ((String)users.get(login)).split("/"); + String parentId = user[0]; + currentItem = ItemHandler.getItem(ses.getNodeByIdentifier(parentId), excludes); + + }else + currentItem = ItemHandler.getItem(ses.getNodeByIdentifier(currentItem.getParentId()), excludes); + + + log.trace("current node is {}",currentItem.getPath()); + toReturn.add(currentItem); + } + + }catch(Throwable e){ + log.error("error retrieving parents of node with id {}",id,e); + throw new WebApplicationException(e); + }finally{ + if (ses!=null) + ses.logout(); + } + + log.trace("item list to return is empty ? {}",toReturn.isEmpty()); + + return new ItemList(toReturn); + } + @GET @Path("{id}/download") public Response download(){ - + CalledMethodProvider.instance.set("downloadById"); Session ses = null; try{ final String login = AuthorizationProvider.instance.get().getClient().getId(); - long start = System.currentTimeMillis(); ses = repository.getRepository().login(new SimpleCredentials(context.getInitParameter(Constants.ADMIN_PARAM_NAME),context.getInitParameter(Constants.ADMIN_PARAM_PWD).toCharArray())); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); - final Node node = ses.getNodeByIdentifier(id); - authChecker.checkReadAuthorizationControl(ses, id); - final Item item = ItemHandler.getItem(node, null); if (item instanceof AbstractFileItem){ AbstractFileItem fileItem =(AbstractFileItem) item; @@ -264,28 +298,28 @@ public class ItemsManager { @PUT @Path("{id}/move") - public Response move(@QueryParam("newpath") String path, @PathParam("id") String identifier){ + public Response move(@QueryParam("destinationId") String destinationId, @PathParam("id") String identifier){ + CalledMethodProvider.instance.set("move"); Session ses = null; try{ final String login = AuthorizationProvider.instance.get().getClient().getId(); - long start = System.currentTimeMillis(); //ses = RepositoryInitializer.getRepository().login(new SimpleCredentials(login,Utils.getSecurePassword(login).toCharArray())); //TODO check if it is possible to change all the ACL on a workspace ses = repository.getRepository().login(new SimpleCredentials(context.getInitParameter(Constants.ADMIN_PARAM_NAME),context.getInitParameter(Constants.ADMIN_PARAM_PWD).toCharArray())); - authChecker.checkReadAuthorizationControl(ses, id); - log.info("time to connect to repo {}",(System.currentTimeMillis()-start)); + + authChecker.checkWriteAuthorizationControl(ses, destinationId); + authChecker.checkReadAuthorizationControl(ses, identifier); + final Node nodeToMove = ses.getNodeByIdentifier(identifier); - final Node destination = ses.getNode(path); + final Node destination = ses.getNodeByIdentifier(destinationId); Item destinationItem = ItemHandler.getItem(destination,null); - //TODO for now only owner of the destination folder can move file - if (!destinationItem.getOwner().equals(login)){ - /*AccessControlManager accessControlManager = ses.getAccessControlManager(); - boolean canWrite = accessControlManager.hasPrivileges(path, new Privilege[] { - accessControlManager.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES)});*/ - //if (!canWrite) - - throw new IllegalAccessException("Insufficent Provileges to write in "+path); - } + + + + + ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); + ses.getWorkspace().getLockManager().lock(destinationItem.getPath(), true, true, 0,login); + final Item item = ItemHandler.getItem(nodeToMove, null); if (item instanceof SharedFolder){ throw new Exception("shared folder cannot be moved"); @@ -298,7 +332,7 @@ public class ItemsManager { } ses.save(); }catch(Exception e){ - log.error("error moving item with id {} in path {}",identifier, path,e); + log.error("error moving item with id {} in item with id {}",identifier, destinationId,e); throw new WebApplicationException(e); } finally{ if (ses!=null) ses.logout(); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java b/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java index e868078..4954ad1 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/WorkspaceManager.java @@ -22,6 +22,7 @@ import javax.ws.rs.core.MediaType; import javax.xml.ws.WebServiceException; import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.provider.CalledMethodProvider; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; @@ -62,6 +63,7 @@ public class WorkspaceManager { @GET @Produces(MediaType.APPLICATION_JSON) public ItemWrapper getWorkspace(){ + CalledMethodProvider.instance.set("getWorkspace"); Session ses = null; org.gcube.common.storagehub.model.Path absolutePath = Utils.getHomePath(); Item toReturn = null; @@ -86,6 +88,7 @@ public class WorkspaceManager { @GET @Produces(MediaType.APPLICATION_JSON) public ItemWrapper getVreRootFolder(){ + CalledMethodProvider.instance.set("getVreRootFolder"); Session ses = null; org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME); @@ -124,6 +127,7 @@ public class WorkspaceManager { @GET @Produces(MediaType.APPLICATION_JSON) public ItemWrapper getTrashRootFolder(){ + CalledMethodProvider.instance.set("getTrashRootFolder"); Session ses = null; org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getHomePath(), Constants.TRASH_ROOT_FOLDER_NAME); @@ -154,6 +158,7 @@ public class WorkspaceManager { @GET @Produces(MediaType.APPLICATION_JSON) public ItemList getVreFolders(){ + CalledMethodProvider.instance.set("getVreFolders"); Session ses = null; org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME); @@ -176,6 +181,7 @@ public class WorkspaceManager { @GET @Produces(MediaType.APPLICATION_JSON) public ItemList getVreFoldersPaged(@QueryParam("start") Integer start, @QueryParam("limit") Integer limit){ + CalledMethodProvider.instance.set("getVreFoldersPaged"); Session ses = null; org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME); @@ -198,6 +204,7 @@ public class WorkspaceManager { @GET @Produces(MediaType.APPLICATION_JSON) public ItemList searchItems(@QueryParam("n") String node, @QueryParam("e") String jsonExpr, @QueryParam("o") List orderField, @QueryParam("l") Integer limit, @QueryParam("f") Integer offset){ + CalledMethodProvider.instance.set("searchItems"); Session ses = null; List toReturn = new ArrayList<>();