From a2613dc1a74e868168d718fc6f3cd82a09acf436 Mon Sep 17 00:00:00 2001 From: "lucio.lelii" Date: Wed, 31 Mar 2021 14:49:47 +0200 Subject: [PATCH] - possibility to impersonate people added --- .classpath | 4 +- .settings/org.eclipse.jdt.core.prefs | 8 - .settings/org.eclipse.wst.common.component | 51 ++- CHANGELOG.md | 4 + pom.xml | 17 +- .../storagehub/AuthorizationChecker.java | 81 +++-- .../data/access/storagehub/Constants.java | 12 +- .../data/access/storagehub/PathUtil.java | 42 +++ .../data/access/storagehub/StorageHub.java | 8 +- .../gcube/data/access/storagehub/Utils.java | 74 +--- .../accounting/AccountingHandler.java | 31 +- .../storagehub/handlers/GroupHandler.java | 8 +- .../storagehub/handlers/TrashHandler.java | 23 +- .../storagehub/handlers/UnshareHandler.java | 29 +- .../storagehub/handlers/VREManager.java | 60 ++++ .../handlers/items/ItemHandler.java | 48 ++- .../handlers/items/Node2ItemConverter.java | 9 +- .../builders/FileCreationParameters.java | 2 +- .../storagehub/services/ACLManager.java | 25 +- .../storagehub/services/GroupManager.java | 24 +- .../storagehub/services/Impersonable.java | 49 +++ .../storagehub/services/ItemSharing.java | 43 ++- .../storagehub/services/ItemsCreator.java | 40 +-- .../storagehub/services/ItemsManager.java | 101 +++--- .../storagehub/services/UserManager.java | 27 +- .../storagehub/services/WorkspaceManager.java | 57 ++-- .../services/admin/ItemManagerAdmin.java | 316 ------------------ .../services/admin/NodeManagerAdmin.java | 2 + .../services/admin/ScriptManager.java | 205 ++++++++++++ .../services/admin/ScriptUtilImpl.java | 33 ++ src/main/webapp/WEB-INF/README | 2 +- src/main/webapp/WEB-INF/gcube-app.xml | 2 +- 32 files changed, 751 insertions(+), 686 deletions(-) create mode 100644 src/main/java/org/gcube/data/access/storagehub/PathUtil.java create mode 100644 src/main/java/org/gcube/data/access/storagehub/services/Impersonable.java delete mode 100644 src/main/java/org/gcube/data/access/storagehub/services/admin/ItemManagerAdmin.java create mode 100644 src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptManager.java create mode 100644 src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptUtilImpl.java diff --git a/.classpath b/.classpath index 11def0e..298646d 100644 --- a/.classpath +++ b/.classpath @@ -13,15 +13,15 @@ + - - + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 8b5c4dc..2f5cc74 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,15 +1,7 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore org.eclipse.jdt.core.compiler.release=disabled diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index cefa543..f70b3ad 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,5 +1,8 @@ - + + + + @@ -16,7 +19,10 @@ - + + + + @@ -33,7 +39,10 @@ - + + + + @@ -50,7 +59,10 @@ - + + + + @@ -67,7 +79,10 @@ - + + + + @@ -84,7 +99,16 @@ - + + uses + + + uses + + + + + @@ -101,7 +125,10 @@ - + + + + @@ -118,7 +145,10 @@ - + + + + @@ -135,7 +165,10 @@ - + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 78c0d0b..e25b7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [v1.3.0] - [2021-03-31] + +- possibility to impersonate people added + ## [v1.2.5] - [2021-03-11] use of query (indexes are not working well in jackrabbit) to retrieve shared folder removed on delete user diff --git a/pom.xml b/pom.xml index d149164..2f12a76 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ 4.0.0 org.gcube.data.access storagehub - 1.2.5 + 1.3.0-SNAPSHOT storagehub @@ -107,6 +107,12 @@ [1.0.0,2.0.0-SNAPSHOT) + + org.gcube.data.access + storagehub-scripting-util + [1.0.0-SNAPSHOT,2.0.0) + + com.itextpdf itextpdf @@ -192,7 +198,7 @@ javamelody-core 1.82.0 - + @@ -200,21 +206,21 @@ javax.servlet-api 3.0.1 - + javax.interceptor javax.interceptor-api 1.2.2 - + javax.enterprise cdi-api 2.0 - + javax.ws.rs javax.ws.rs-api @@ -436,7 +442,6 @@ org.codehaus.mojo aspectj-maven-plugin - [1.0,) test-compile 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 af5da00..cee80be 100644 --- a/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java +++ b/src/main/java/org/gcube/data/access/storagehub/AuthorizationChecker.java @@ -1,7 +1,6 @@ package org.gcube.data.access.storagehub; import javax.inject.Inject; -import javax.inject.Singleton; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -14,6 +13,7 @@ import org.apache.jackrabbit.api.security.user.Authorizable; 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.authorization.library.provider.ClientInfo; import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.acls.AccessType; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; @@ -27,7 +27,13 @@ import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Singleton +/** + * + * + * the caller must be authorized, so i'm not passing the login also if it works on behalf of an user + * + * + */ public class AuthorizationChecker { private static Logger log = LoggerFactory.getLogger(AuthorizationChecker.class); @@ -35,25 +41,42 @@ public class AuthorizationChecker { @Inject Node2ItemConverter node2Item; + @Inject + PathUtil pathUtil; - public void checkReadAuthorizationControl(Session session, String id) throws UserNotAuthorizedException , BackendGenericError, RepositoryException{ - String login = AuthorizationProvider.instance.get().getClient().getId(); - checkReadAuthorizationControl(session, login, id); + String userToCheck; + + public AuthorizationChecker(){ + ClientInfo client = AuthorizationProvider.instance.get().getClient(); + this.userToCheck = client.getId(); } - public void checkReadAuthorizationControl(Session session, String login, String id) throws UserNotAuthorizedException , BackendGenericError, RepositoryException{ + public AuthorizationChecker(String userToCheck){ + this.userToCheck = userToCheck; + } + + public String getUserToCheck() { + return userToCheck; + } + + public void setUserToCheck(String user) { + this.userToCheck = user; + } + + public void checkReadAuthorizationControl(Session session, String id) throws UserNotAuthorizedException , BackendGenericError, RepositoryException{ + Node node = session.getNodeByIdentifier(id); Item item = node2Item.getItem(node, Excludes.ALL); - if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node"); + if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" 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))) + if(item instanceof TrashItem && item.getParentPath().equals(pathUtil.getOldTrashPath(userToCheck).toPath())) return; - if (!item.isShared() && item.getOwner()!=null && item.getOwner().equals(login)) return; + if (!item.isShared() && item.getOwner()!=null && item.getOwner().equals(userToCheck)) return; if (hasParentPublicFolder(session, item)) return; @@ -61,14 +84,14 @@ public class AuthorizationChecker { if (item.isShared()) { SharedFolder parentShared = node2Item.getItem(retrieveSharedFolderParent(node, session), Excludes.EXCLUDE_ACCOUNTING); - if (parentShared.getUsers().getMap().keySet().contains(login)) return; + if (parentShared.getUsers().getMap().keySet().contains(userToCheck)) return; //CHECKING ACL FOR VREFOLDER AND SHARED FOLDER JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(session, parentShared.getPath()); AccessControlEntry[] entries = accessControlList.getAccessControlEntries(); - Authorizable userAuthorizable = ((JackrabbitSession) session).getUserManager().getAuthorizable(login); + Authorizable userAuthorizable = ((JackrabbitSession) session).getUserManager().getAuthorizable(userToCheck); for (AccessControlEntry entry: entries) { - log.debug("checking access right for {} with compared with {}",login, entry.getPrincipal()); + log.debug("checking access right for {} with compared with {}",userToCheck, entry.getPrincipal()); Authorizable authorizable = ((JackrabbitSession) session).getUserManager().getAuthorizable(entry.getPrincipal()); if (authorizable==null) { @@ -77,17 +100,17 @@ public class AuthorizationChecker { } try { - if (!authorizable.isGroup() && entry.getPrincipal().getName().equals(login)) return; + if (!authorizable.isGroup() && entry.getPrincipal().getName().equals(userToCheck)) return; if (authorizable.isGroup() && ((Group) authorizable).isMember(userAuthorizable)) return; }catch (Throwable e) { log.warn("someting went wrong checking authorizations",e); } } - throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to read node with id "+id); } - throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to read node with id "+id); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to read node with id "+id); } @@ -123,14 +146,11 @@ 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(); - + public void checkWriteAuthorizationControl(Session session, Item item, Node node, boolean isNewItem) throws UserNotAuthorizedException, BackendGenericError, RepositoryException { 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"); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to write into node with id "+item.getId()+": it's a protected folder"); /* if (item.isTrashed()) @@ -140,18 +160,18 @@ public class AuthorizationChecker { Node parentSharedNode = retrieveSharedFolderParent(node, session); JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(session, parentSharedNode.getPath()); AccessControlEntry[] entries = accessControlList.getAccessControlEntries(); - Authorizable UserAuthorizable = ((JackrabbitSession) session).getUserManager().getAuthorizable(login); + Authorizable UserAuthorizable = ((JackrabbitSession) session).getUserManager().getAuthorizable(userToCheck); //put it in a different method for (AccessControlEntry entry: entries) { Authorizable authorizable = ((JackrabbitSession) session).getUserManager().getAuthorizable(entry.getPrincipal()); - if ((!authorizable.isGroup() && entry.getPrincipal().getName().equals(login)) || (authorizable.isGroup() && ((Group) authorizable).isMember(UserAuthorizable))){ + if ((!authorizable.isGroup() && entry.getPrincipal().getName().equals(userToCheck)) || (authorizable.isGroup() && ((Group) authorizable).isMember(UserAuthorizable))){ for (Privilege privilege : entry.getPrivileges()){ AccessType access = AccessType.fromValue(privilege.getName()); if (isNewItem && access!=AccessType.READ_ONLY) return; else if (!isNewItem && - (access==AccessType.ADMINISTRATOR || access==AccessType.WRITE_ALL || (access==AccessType.WRITE_OWNER && item.getOwner().equals(login)))) + (access==AccessType.ADMINISTRATOR || access==AccessType.WRITE_ALL || (access==AccessType.WRITE_OWNER && item.getOwner().equals(userToCheck)))) return; } @@ -159,9 +179,9 @@ public class AuthorizationChecker { } } } else - if(item.getOwner().equals(login)) + if(item.getOwner().equals(userToCheck)) return; - throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+" to write into node with id "+item.getId()); + throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+" to write into node with id "+item.getId()); } //newItem means that a new item will be created and id is the destination directory @@ -170,7 +190,6 @@ public class AuthorizationChecker { Node node = session.getNodeByIdentifier(id); Item item = node2Item.getItem(node, Excludes.ALL); checkWriteAuthorizationControl(session, item, node, isNewItem); - } @@ -184,10 +203,8 @@ public class AuthorizationChecker { public void checkAdministratorControl(Session session, SharedFolder item) throws UserNotAuthorizedException, BackendGenericError, RepositoryException { - //TODO: riguardare questo pezzo di codice - String login = AuthorizationProvider.instance.get().getClient().getId(); - - if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+login+": it's not a valid StorageHub node"); + + if (item==null) throw new UserNotAuthorizedException("Insufficent Privileges for user "+userToCheck+": it's not a valid StorageHub node"); Node node = session.getNodeByIdentifier(item.getId()); @@ -199,7 +216,7 @@ public class AuthorizationChecker { SharedFolder parentShared = node2Item.getItem(parentSharedNode, Excludes.EXCLUDE_ACCOUNTING); for (AccessControlEntry entry: entries) { - if (entry.getPrincipal().getName().equals(login) || (parentShared.isVreFolder() && entry.getPrincipal().getName().equals(parentShared.getTitle()))) { + if (entry.getPrincipal().getName().equals(userToCheck) || (parentShared.isVreFolder() && entry.getPrincipal().getName().equals(parentShared.getTitle()))) { for (Privilege privilege : entry.getPrivileges()){ AccessType access = AccessType.fromValue(privilege.getName()); if (access==AccessType.ADMINISTRATOR) @@ -212,7 +229,7 @@ public class AuthorizationChecker { } //else should never happen - throw new UserNotAuthorizedException("The user "+login+" is not an administrator of node with id "+item.getId()); + throw new UserNotAuthorizedException("The user "+userToCheck+" is not an administrator of node with id "+item.getId()); } diff --git a/src/main/java/org/gcube/data/access/storagehub/Constants.java b/src/main/java/org/gcube/data/access/storagehub/Constants.java index 8d7a25b..259687f 100644 --- a/src/main/java/org/gcube/data/access/storagehub/Constants.java +++ b/src/main/java/org/gcube/data/access/storagehub/Constants.java @@ -5,7 +5,11 @@ import java.util.List; public class Constants { - public static final String VRE_FOLDER_PARENT_NAME = "MySpecialFolders"; + public static final String OLD_VRE_FOLDER_PARENT_NAME = "MySpecialFolders"; + + public static final String PERSONAL_VRES_FOLDER_PARENT_NAME = "VREs"; + + public static final String SHARED_WITH_ME_PARENT_NAME = "SharedWithMe"; public static final String SHARED_FOLDER_PATH = "/Share"; @@ -19,9 +23,9 @@ public class Constants { public static final String ADMIN_PARAM_PWD ="admin-pwd"; - public static final List FOLDERS_TO_EXLUDE = Arrays.asList(Constants.VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME); + public static final List FOLDERS_TO_EXLUDE = Arrays.asList(Constants.OLD_VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME); - public static final List WRITE_PROTECTED_FOLDER = Arrays.asList(Constants.VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME); + public static final List WRITE_PROTECTED_FOLDER = Arrays.asList(Constants.OLD_VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME); - public static final List PROTECTED_FOLDER = Arrays.asList(Constants.WORKSPACE_ROOT_FOLDER_NAME, Constants.VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME); + public static final List PROTECTED_FOLDER = Arrays.asList(Constants.WORKSPACE_ROOT_FOLDER_NAME, Constants.OLD_VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME); } diff --git a/src/main/java/org/gcube/data/access/storagehub/PathUtil.java b/src/main/java/org/gcube/data/access/storagehub/PathUtil.java new file mode 100644 index 0000000..d0896ff --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/PathUtil.java @@ -0,0 +1,42 @@ +package org.gcube.data.access.storagehub; + +import javax.inject.Singleton; +import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.storagehub.model.Paths; +import org.gcube.common.storagehub.model.Path; + +@Singleton +public class PathUtil { + + public Path getWorkspacePath(String login){ + return Paths.getPath(String.format("/Home/%s/%s",login,Constants.WORKSPACE_ROOT_FOLDER_NAME)); + } + + public Path getHome(String login){ + return Paths.getPath(String.format("/Home/%s",login)); + } + + @Deprecated + public Path getOldTrashPath(String login){ + return Paths.append(getWorkspacePath(login),Constants.TRASH_ROOT_FOLDER_NAME); + } + + public Path getTrashPath(String login){ + return Paths.append(getHome(login), Constants.TRASH_ROOT_FOLDER_NAME); + } + + @Deprecated + public Path getOldVREsPath(String login){ + return Paths.append(getWorkspacePath(login),Constants.OLD_VRE_FOLDER_PARENT_NAME); + } + + public Path getVREsPath(String login){ + return Paths.append(getWorkspacePath(login),Constants.PERSONAL_VRES_FOLDER_PARENT_NAME); + } + + public Path getSharedWithMePath(String login){ + return Paths.append(getWorkspacePath(login),Constants.SHARED_WITH_ME_PARENT_NAME); + } + + +} 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 1dd8db2..a1f57c4 100644 --- a/src/main/java/org/gcube/data/access/storagehub/StorageHub.java +++ b/src/main/java/org/gcube/data/access/storagehub/StorageHub.java @@ -9,13 +9,14 @@ import javax.ws.rs.core.Application; import org.gcube.common.gxrest.response.entity.SerializableErrorEntityTextWriter; import org.gcube.data.access.storagehub.services.ACLManager; import org.gcube.data.access.storagehub.services.GroupManager; +import org.gcube.data.access.storagehub.services.Impersonable; import org.gcube.data.access.storagehub.services.ItemSharing; import org.gcube.data.access.storagehub.services.ItemsCreator; import org.gcube.data.access.storagehub.services.ItemsManager; import org.gcube.data.access.storagehub.services.UserManager; import org.gcube.data.access.storagehub.services.WorkspaceManager; -import org.gcube.data.access.storagehub.services.admin.ItemManagerAdmin; import org.gcube.data.access.storagehub.services.admin.NodeManagerAdmin; +import org.gcube.data.access.storagehub.services.admin.ScriptManager; import org.glassfish.jersey.media.multipart.MultiPartFeature; @Path("workspace") @@ -25,7 +26,7 @@ public class StorageHub extends Application { public Set> getClasses() { final Set> classes = new HashSet>(); // register resources and features - classes.add(MultiPartFeature.class); + classes.add(Impersonable.class); classes.add(WorkspaceManager.class); classes.add(ItemsManager.class); classes.add(ItemsCreator.class); @@ -33,8 +34,9 @@ public class StorageHub extends Application { classes.add(ItemSharing.class); classes.add(UserManager.class); classes.add(GroupManager.class); - classes.add(ItemManagerAdmin.class); classes.add(NodeManagerAdmin.class); + classes.add(ScriptManager.class); + classes.add(MultiPartFeature.class); classes.add(SerializableErrorEntityTextWriter.class); classes.add(MyApplicationListener.class); return classes; diff --git a/src/main/java/org/gcube/data/access/storagehub/Utils.java b/src/main/java/org/gcube/data/access/storagehub/Utils.java index 8274e73..449e559 100644 --- a/src/main/java/org/gcube/data/access/storagehub/Utils.java +++ b/src/main/java/org/gcube/data/access/storagehub/Utils.java @@ -30,10 +30,6 @@ import javax.jcr.version.Version; import org.apache.commons.io.FilenameUtils; import org.apache.jackrabbit.util.ISO9075; import org.apache.jackrabbit.util.Text; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; -import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.common.scope.impl.ScopeBean; -import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.Paths; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; @@ -49,8 +45,6 @@ import org.gcube.common.storagehub.model.types.ItemAction; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.data.access.storagehub.accounting.AccountingHandler; import org.gcube.data.access.storagehub.handlers.StorageBackendHandler; -import org.gcube.data.access.storagehub.handlers.VRE; -import org.gcube.data.access.storagehub.handlers.VREManager; import org.gcube.data.access.storagehub.handlers.VersionHandler; import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter; import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; @@ -59,8 +53,8 @@ import org.slf4j.LoggerFactory; public class Utils { - public final static String SERVICE_NAME = "home-library"; - public final static String SERVICE_CLASS = "org.gcube.portlets.user"; + public final static String SERVICE_NAME = "home-library"; + public final static String SERVICE_CLASS = "org.gcube.portlets.user"; private static final String FOLDERS_TYPE = "nthl:workspaceItem"; private static final Logger logger = LoggerFactory.getLogger(Utils.class); @@ -200,19 +194,8 @@ public class Utils { (node.getPrimaryNodeType().getName().equals(FOLDERS_TYPE) && Constants.FOLDERS_TO_EXLUDE.contains(node.getName()))); } - public static org.gcube.common.storagehub.model.Path getWorkspacePath(){ - return Paths.getPath(String.format("/Home/%s/%s",AuthorizationProvider.instance.get().getClient().getId(), Constants.WORKSPACE_ROOT_FOLDER_NAME)); - } - public static org.gcube.common.storagehub.model.Path getWorkspacePath(String login){ - return Paths.getPath(String.format("/Home/%s/%s",login,Constants.WORKSPACE_ROOT_FOLDER_NAME)); - } - - public static org.gcube.common.storagehub.model.Path getHome(String login){ - return Paths.getPath(String.format("/Home/%s",login)); - } - - public static Deque getAllNodesForZip(FolderItem directory, Session session, AccountingHandler accountingHandler, List excludes) throws RepositoryException, BackendGenericError{ + public static Deque getAllNodesForZip(FolderItem directory, Session session, String login, AccountingHandler accountingHandler, List excludes) throws RepositoryException, BackendGenericError{ Deque queue = new LinkedList(); Node currentNode = session.getNodeByIdentifier(directory.getId()); queue.push(directory); @@ -221,11 +204,11 @@ public class Utils { for (Item item : Utils.getItemList(currentNode,Excludes.GET_ONLY_CONTENT, null, false, null)){ if (excludes.contains(item.getId())) continue; if (item instanceof FolderItem) - tempQueue.addAll(getAllNodesForZip((FolderItem) item, session, accountingHandler, excludes)); + tempQueue.addAll(getAllNodesForZip((FolderItem) item, session, login, accountingHandler, excludes)); else if (item instanceof AbstractFileItem){ logger.trace("adding file {}",item.getPath()); AbstractFileItem fileItem = (AbstractFileItem) item; - accountingHandler.createReadObj(fileItem.getTitle(), session, session.getNodeByIdentifier(item.getId()), false); + accountingHandler.createReadObj(fileItem.getTitle(), session, session.getNodeByIdentifier(item.getId()), login, false); queue.addLast(item); } } @@ -360,7 +343,7 @@ public class Utils { } - public static Node createFolderInternally(Session ses, Node destinationNode, String name, String description, boolean hidden, String login, AccountingHandler accountingHandler) throws BackendGenericError { + public static Node createFolderInternally(Session ses, String login, Node destinationNode, String name, String description, boolean hidden, AccountingHandler accountingHandler) throws BackendGenericError { logger.debug("creating folder {} in {}", name, destinationNode); String uniqueName = Utils.checkExistanceAndGetUniqueName(ses, destinationNode, name); @@ -386,8 +369,8 @@ public class Utils { Node newNode = new Item2NodeConverter().getNode(destinationNode, item); if (accountingHandler!=null) { - accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false); - accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false); + accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, login, destinationNode, false); + accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, login, false); } return newNode; } @@ -419,8 +402,8 @@ public class Utils { Node newNode = new Item2NodeConverter().getNode(destinationNode, item); if (accountingHandler!=null) { - accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false); - accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false); + accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, login, destinationNode, false); + accountingHandler.createEntryCreate(item.getTitle(), ses, newNode,login, false); } return newNode; } @@ -452,42 +435,5 @@ public class Utils { node.setProperty(NodeProperty.LAST_ACTION.toString(), action.name()); } - public static synchronized VRE getVreFolderItem(Session ses, Node2ItemConverter node2Item, VREManager vreManager, List excludes ) throws RepositoryException, BackendGenericError{ - org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME); - ScopeBean bean = new ScopeBean(ScopeProvider.instance.get()); - if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE"); - String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-"); - VRE vre = vreManager.getVRE(entireScopeName); - if (vre!=null) return vre; - else { - String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",entireScopeName, vrePath.toPath()); - Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); - NodeIterator it = jcrQuery.execute().getNodes(); - - if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+entireScopeName); - - Node folder = it.nextNode(); - Item vreFolder = node2Item.getItem(folder, excludes); - return vreManager.putVRE(vreFolder); - } - - } - - public static synchronized VRE getVreFolderItemByGroupNameAndUser(Session ses, String goupName, String userId, Node2ItemConverter node2Item, VREManager vreManager, List excludes ) throws RepositoryException, BackendGenericError{ - org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(userId), Constants.VRE_FOLDER_PARENT_NAME); - VRE vre = vreManager.getVRE(goupName); - if (vre!=null) return vre; - else { - String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",goupName, vrePath.toPath()); - Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); - NodeIterator it = jcrQuery.execute().getNodes(); - - if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+goupName); - - Node folder = it.nextNode(); - Item vreFolder = node2Item.getItem(folder, excludes); - return vreManager.putVRE(vreFolder); - } - } } 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 d321019..be909c8 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 @@ -14,7 +14,6 @@ import javax.jcr.version.VersionHistory; import javax.jcr.version.VersionIterator; import javax.jcr.version.VersionManager; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.storagehub.model.items.nodes.accounting.AccountingEntryType; import org.gcube.common.storagehub.model.types.NodeProperty; import org.slf4j.Logger; @@ -37,7 +36,7 @@ public class AccountingHandler { private static final Logger logger = LoggerFactory.getLogger(AccountingHandler.class); - public void createReadObj(String title, Session ses, Node node, boolean saveHistory ) { + public void createReadObj(String title, Session ses, Node node, String login, boolean saveHistory ) { try { if (!node.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -47,7 +46,7 @@ public class AccountingHandler { Node accountingNodeParent = node.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.READ.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(USER, login); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(ITEM_NAME, title); @@ -70,7 +69,7 @@ public class AccountingHandler { } } - public void createEntryCreate(String title, Session ses, Node node, boolean saveHistory ) { + public void createEntryCreate(String title, Session ses, Node node, String login, boolean saveHistory ) { try { if (!node.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -79,7 +78,7 @@ public class AccountingHandler { Node accountingNodeParent = node.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.CREATE.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(USER, login); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(ITEM_NAME, title); @@ -89,7 +88,7 @@ public class AccountingHandler { } } - public void createFileUpdated(String title, Session ses, Node node, boolean saveHistory ) { + public void createFileUpdated(String title, Session ses, Node node, String login, boolean saveHistory ) { try { if (!node.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -99,7 +98,7 @@ public class AccountingHandler { Node accountingNodeParent = node.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.UPDATE.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(USER, login); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(ITEM_NAME, title); @@ -126,7 +125,7 @@ public class AccountingHandler { } - public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node parentNode, boolean saveHistory ) { + public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, String login, Node parentNode, boolean saveHistory ) { try { @@ -136,7 +135,7 @@ public class AccountingHandler { Node accountingNodeParent = parentNode.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.ADD.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(USER, login); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(ITEM_NAME, title); accountingNode.setProperty(ITEM_TYPE, itemType); @@ -149,7 +148,7 @@ public class AccountingHandler { } } - public void createFolderRemoveObj(String title, String itemType, String mimeType, Session ses, Node parentNode, boolean saveHistory ) { + public void createFolderRemoveObj(String title, String itemType, String mimeType, Session ses, String login, Node parentNode, boolean saveHistory ) { try { if (!parentNode.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -158,7 +157,7 @@ public class AccountingHandler { Node accountingNodeParent = parentNode.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.REMOVAL.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(USER, login); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(ITEM_NAME, title); accountingNode.setProperty(ITEM_TYPE, itemType); @@ -171,7 +170,7 @@ public class AccountingHandler { } } - public void createShareFolder(String title, Set users, Session ses, Node sharedNode, boolean saveHistory ) { + public void createShareFolder(String title, Set users, Session ses, Node sharedNode, String login, boolean saveHistory ) { try { if (!sharedNode.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -180,7 +179,7 @@ public class AccountingHandler { Node accountingNodeParent = sharedNode.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.SHARE.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(USER, login); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(ITEM_NAME, title); accountingNode.setProperty(MEMBERS, users.toArray(new String[users.size()])); @@ -191,7 +190,7 @@ public class AccountingHandler { } } - public void createUnshareFolder(String title, String user, Session ses, Node sharedNode, boolean saveHistory ) { + public void createUnshareFolder(String title, Session ses, String user, Node sharedNode, boolean saveHistory ) { try { if (!sharedNode.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -210,7 +209,7 @@ public class AccountingHandler { } } - public void createRename(String oldTitle, String newTitle, Node node, Session ses, boolean saveHistory ) { + public void createRename(String oldTitle, String newTitle, Node node, String login, Session ses, boolean saveHistory ) { try { if (!node.hasNode(NodeProperty.ACCOUNTING.toString())){ @@ -219,7 +218,7 @@ public class AccountingHandler { Node accountingNodeParent = node.getNode(NodeProperty.ACCOUNTING.toString()); Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.RENAMING.getNodeTypeDefinition()); - accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId()); + accountingNode.setProperty(USER, login); accountingNode.setProperty(DATE, Calendar.getInstance()); accountingNode.setProperty(OLD_ITEM_NAME, oldTitle); accountingNode.setProperty(NEW_ITEM_NAME, newTitle); diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/GroupHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/GroupHandler.java index 336ac8d..7b15df5 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/GroupHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/GroupHandler.java @@ -1,5 +1,6 @@ package org.gcube.data.access.storagehub.handlers; +import javax.inject.Inject; import javax.inject.Singleton; import javax.jcr.Node; import javax.jcr.NodeIterator; @@ -14,7 +15,7 @@ import org.gcube.common.storagehub.model.exceptions.InvalidItemException; import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.data.access.storagehub.Constants; -import org.gcube.data.access.storagehub.Utils; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.services.GroupManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,6 +25,9 @@ public class GroupHandler { private static final Logger log = LoggerFactory.getLogger(GroupManager.class); + @Inject + PathUtil pathUtil; + public boolean removeUserFromGroup(String groupId, String userId, JackrabbitSession session) throws StorageHubException, RepositoryException { org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager(); @@ -40,7 +44,7 @@ public class GroupHandler { NodeIterator ni = folder.getSharedSet(); while (ni.hasNext()) { Node node = ni.nextNode(); - if (node.getPath().startsWith(Utils.getWorkspacePath(user.getPrincipal().getName()).toPath())) { + if (node.getPath().startsWith(pathUtil.getWorkspacePath(user.getPrincipal().getName()).toPath())) { node.removeShare(); break; } 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 3b1a0df..46fa85f 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 @@ -29,7 +29,7 @@ import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.TrashItem; 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.PathUtil; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.accounting.AccountingHandler; import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter; @@ -59,6 +59,9 @@ public class TrashHandler { @Inject Node2ItemConverter node2Item; + @Inject + PathUtil pathUtil; + @Inject StorageBackendHandler storageHandler; @@ -95,7 +98,6 @@ public class TrashHandler { log.debug("content ids to remove are {}",contentIdsToDelete); - //String user = AuthorizationProvider.instance.get().getClient().getId(); Runnable deleteFromStorageRunnable = AuthorizedTasks.bind(new Runnable() { @Override @@ -121,11 +123,9 @@ public class TrashHandler { } } - public void moveToTrash(Session ses, Node nodeToDelete, Item item) throws RepositoryException, BackendGenericError{ + public void moveToTrash(Session ses, Node nodeToDelete, Item item, String login) 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()); - - final String login = AuthorizationProvider.instance.get().getClient().getId(); + final Node trashFolder = ses.getNode(pathUtil.getOldTrashPath(login).toPath()); try { ses.getWorkspace().getLockManager().lock(trashFolder.getPath(), true, true, 0,login); @@ -134,7 +134,7 @@ public class TrashHandler { log.debug("preparing thrash item"); TrashItem trashItem = new TrashItem(); - trashItem.setDeletedBy(AuthorizationProvider.instance.get().getClient().getId()); + trashItem.setDeletedBy(login); trashItem.setDeletedFrom(nodeToDelete.getParent().getPath()); Calendar now = Calendar.getInstance(); trashItem.setDeletedTime(now); @@ -178,7 +178,7 @@ public class TrashHandler { mimetype = ((AbstractFileItem) item).getContent().getMimeType(); 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, login, (Node) item.getRelatedNode(), true); }catch(Throwable t) { log.error("error exceuting move to trash",t); throw new BackendGenericError(t); @@ -189,9 +189,8 @@ public class TrashHandler { } - public String restoreItem(Session ses, TrashItem item, FolderItem destination) throws RepositoryException, StorageHubException, BackendGenericError{ + public String restoreItem(Session ses, TrashItem item, FolderItem destination, String login) throws RepositoryException, StorageHubException, BackendGenericError{ log.debug("restoring node from trash"); - final String login = AuthorizationProvider.instance.get().getClient().getId(); //final Node trashFolder = ses.getNode(Paths.append(Utils.getHomePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath()); Node destinationNode= null; @@ -215,12 +214,12 @@ public class TrashHandler { if(originalParentExists && !originalParentTrashed) { destinationNode = originalParent; }else { - String homeWS = Utils.getWorkspacePath(login).toPath(); + String homeWS = pathUtil.getWorkspacePath(login).toPath(); Node node = ses.getNode(homeWS); destinationNode = node; } } else { - Node node = ses.getNodeByIdentifier(destination.getId()); + Node node = (Node)destination.getRelatedNode(); if (!node2Item.checkNodeType(node, FolderItem.class)) throw new InvalidCallParameters("destination Node is not a folder"); diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java index 70933c6..529652e 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/UnshareHandler.java @@ -7,7 +7,6 @@ import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; -import javax.jcr.ItemNotFoundException; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; @@ -31,6 +30,7 @@ import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.common.storagehub.model.types.ItemAction; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.data.access.storagehub.AuthorizationChecker; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.accounting.AccountingHandler; import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter; @@ -52,6 +52,9 @@ public class UnshareHandler { @Inject AuthorizationChecker authChecker; + + @Inject + PathUtil pathUtil; @Inject Item2NodeConverter item2Node; @@ -138,9 +141,9 @@ public class UnshareHandler { while(it.hasNext()) { Node node = it.nextNode(); - log.info("[UNSHARE] checking node {} starts with {} ",node.getPath(),Utils.getHome(login).toPath()); + log.info("[UNSHARE] checking node {} starts with {} ",node.getPath(),pathUtil.getHome(login).toPath()); - if (node.getPath().startsWith(Utils.getHome(login).toPath())) { + if (node.getPath().startsWith(pathUtil.getHome(login).toPath())) { sharedOwnerNode =node; break; } @@ -167,7 +170,7 @@ public class UnshareHandler { //set owner of all the unshared items to the caller item2Node.updateOwnerOnSubTree(unsharedNode, login); - accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), "ALL", ses, unsharedNode, false); + accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), ses, "ALL", unsharedNode, false); unsharedNodeIdentifier = unsharedNode.getIdentifier(); log.info("[UNSHARE] unshared node id {}",unsharedNodeIdentifier); @@ -195,19 +198,14 @@ public class UnshareHandler { private String unshareCaller(String login, Session ses, SharedFolder item) throws StorageHubException, RepositoryException{ log.info("unshare caller"); - if (login.equals(item.getOwner())) throw new InvalidCallParameters("the caller is the owner, the folder cannot be unshared"); Node sharedFolderNode =ses.getNodeByIdentifier(item.getId()); - - log.debug("removed Access control entry for user {}",login); - Node sharedItemNode = ses.getNodeByIdentifier(item.getId()); - if (item.getUsers().getMap().get(login)!=null) { - Node usersNode = sharedItemNode.getNode(NodeConstants.USERS_NAME); + Node usersNode = sharedFolderNode.getNode(NodeConstants.USERS_NAME); usersNode.remove(); - Node newUsersNode = sharedItemNode.addNode(NodeConstants.USERS_NAME); + Node newUsersNode = sharedFolderNode.addNode(NodeConstants.USERS_NAME); item.getUsers().getMap().entrySet().stream().filter(entry -> !entry.getKey().equals(login)).forEach(entry-> {try { newUsersNode.setProperty(entry.getKey(), (String)entry.getValue()); @@ -217,7 +215,6 @@ public class UnshareHandler { } Node shareNode = getUserSharingNode(login, ses, item); - String parentId = shareNode.getParent().getIdentifier(); //not returning an error to correct all the old ACL @@ -240,7 +237,9 @@ public class UnshareHandler { acm.setPolicy(sharedFolderNode.getPath(), acls); - accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), login, ses, sharedItemNode, false); + log.debug("removed Access control entry for user {}",login); + + accountingHandler.createUnshareFolder(item.getTitle(), ses, login, sharedFolderNode, false); ses.save(); @@ -296,7 +295,7 @@ public class UnshareHandler { acm.setPolicy(sharedFolderNode.getPath(), acls); for (String user: usersToUnshare) { - accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), user, ses, sharedItemNode, false); + accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), ses, user, sharedItemNode, false); } ses.save(); @@ -326,7 +325,7 @@ public class UnshareHandler { NodeIterator it = sharedFolderNode.getSharedSet(); while(it.hasNext()) { Node node = it.nextNode(); - if (node.getPath().startsWith(Utils.getHome(user).toPath())) { + if (node.getPath().startsWith(pathUtil.getHome(user).toPath())) { shareNode =node; break; } diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java b/src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java index f5de4da..fe03bb7 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/VREManager.java @@ -1,17 +1,30 @@ package org.gcube.data.access.storagehub.handlers; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.inject.Inject; import javax.inject.Singleton; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; import javax.jcr.SimpleCredentials; +import javax.jcr.query.Query; import javax.servlet.ServletContext; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.gcube.common.scope.impl.ScopeBean.Type; +import org.gcube.common.storagehub.model.Paths; +import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.items.Item; import org.gcube.data.access.storagehub.Constants; +import org.gcube.data.access.storagehub.PathUtil; +import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; import org.gcube.data.access.storagehub.services.RepositoryInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,6 +39,12 @@ public class VREManager { @Inject RepositoryInitializer repository; + @Inject + Node2ItemConverter node2Item; + + @Inject + PathUtil pathUtil; + ExecutorService executor = Executors.newFixedThreadPool(5); SimpleCredentials credentials; @@ -56,4 +75,45 @@ public class VREManager { } + public synchronized VRE getVreFolderItem(Session ses, String userId, List excludes ) throws RepositoryException, BackendGenericError{ + + + org.gcube.common.storagehub.model.Path vrePath = Paths.append(pathUtil.getWorkspacePath(userId), Constants.OLD_VRE_FOLDER_PARENT_NAME); + ScopeBean bean = new ScopeBean(ScopeProvider.instance.get()); + if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE"); + String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-"); + VRE vre = this.getVRE(entireScopeName); + if (vre!=null) return vre; + else { + String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",entireScopeName, vrePath.toPath()); + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); + NodeIterator it = jcrQuery.execute().getNodes(); + + if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+entireScopeName); + + Node folder = it.nextNode(); + Item vreFolder = node2Item.getItem(folder, excludes); + return this.putVRE(vreFolder); + } + + } + + public synchronized VRE getVreFolderItemByGroupNameAndUser(Session ses, String goupName, String userId, List excludes ) throws RepositoryException, BackendGenericError{ + org.gcube.common.storagehub.model.Path vrePath = Paths.append(pathUtil.getWorkspacePath(userId), Constants.OLD_VRE_FOLDER_PARENT_NAME); + VRE vre = this.getVRE(goupName); + if (vre!=null) return vre; + else { + String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",goupName, vrePath.toPath()); + Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE); + NodeIterator it = jcrQuery.execute().getNodes(); + + if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+goupName); + + Node folder = it.nextNode(); + Item vreFolder = node2Item.getItem(folder, excludes); + return this.putVRE(vreFolder); + } + } + + } diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/items/ItemHandler.java b/src/main/java/org/gcube/data/access/storagehub/handlers/items/ItemHandler.java index 9be7629..34e9e30 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/items/ItemHandler.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/items/ItemHandler.java @@ -61,9 +61,7 @@ import org.slf4j.LoggerFactory; @Singleton public class ItemHandler { - @Inject - AuthorizationChecker authChecker; - + @Inject AccountingHandler accountingHandler; @@ -83,7 +81,7 @@ public class ItemHandler { private static Logger log = LoggerFactory.getLogger(ItemHandler.class); - public String create(T parameters) throws Exception{ + public String create(T parameters, AuthorizationChecker authChecker) throws Exception{ Session ses = parameters.getSession(); Node destination; @@ -103,19 +101,19 @@ public class ItemHandler { Node newNode = null; switch (parameters.getMangedType()) { case FILE: - newNode = create((FileCreationParameters)parameters, destination); + newNode = create((FileCreationParameters)parameters, authChecker, destination); break; case FOLDER: - newNode = create((FolderCreationParameters)parameters, destination); + newNode = create((FolderCreationParameters)parameters, authChecker, destination); break; case ARCHIVE: - newNode = create((ArchiveStructureCreationParameter)parameters, destination); + newNode = create((ArchiveStructureCreationParameter)parameters, authChecker, destination); break; case URL: - newNode = create((URLCreationParameters) parameters, destination); + newNode = create((URLCreationParameters) parameters, authChecker, destination); break; case GCUBEITEM: - newNode = create((GCubeItemCreationParameters) parameters, destination); + newNode = create((GCubeItemCreationParameters) parameters, authChecker, destination); break; default: throw new InvalidCallParameters("Item not supported"); @@ -130,15 +128,15 @@ public class ItemHandler { } - private Node create(FolderCreationParameters params, Node destination) throws Exception{ + private Node create(FolderCreationParameters params, AuthorizationChecker authChecker, Node destination) throws Exception{ Utils.acquireLockWithWait(params.getSession(), destination.getPath(), false, params.getUser(), 10); - Node newNode = Utils.createFolderInternally(params.getSession(), destination, params.getName(), params.getDescription(), params.isHidden(), params.getUser(), accountingHandler); + Node newNode = Utils.createFolderInternally(params.getSession(), params.getUser(), destination, params.getName(), params.getDescription(), params.isHidden(), accountingHandler); params.getSession().save(); return newNode; } - private Node create(FileCreationParameters params, Node destination) throws Exception{ - Node newNode = createFileItemInternally(params.getSession(), destination, params.getStream(), params.getName(), params.getDescription(), params.getUser(), true); + private Node create(FileCreationParameters params, AuthorizationChecker authChecker, Node destination) throws Exception{ + Node newNode = createFileItemInternally(params.getSession(), authChecker, destination, params.getStream(), params.getName(), params.getDescription(), params.getUser(), true); params.getSession().save(); versionHandler.checkinContentNode(newNode, params.getSession()); @@ -146,16 +144,16 @@ public class ItemHandler { return newNode; } - private Node create(URLCreationParameters params, Node destination) throws Exception{ + private Node create(URLCreationParameters params, AuthorizationChecker authChecker, Node destination) throws Exception{ Utils.acquireLockWithWait(params.getSession(), destination.getPath(), false, params.getUser(), 10); Node newNode = Utils.createURLInternally(params.getSession(), destination, params.getName(), params.getUrl(), params.getDescription(), params.getUser(), accountingHandler); params.getSession().save(); return newNode; } - private Node create(ArchiveStructureCreationParameter params, Node destination) throws Exception{ + private Node create(ArchiveStructureCreationParameter params, AuthorizationChecker authChecker, Node destination) throws Exception{ Utils.acquireLockWithWait(params.getSession(), destination.getPath(), false, params.getUser(), 10); - Node parentDirectoryNode = Utils.createFolderInternally(params.getSession(), destination, params.getParentFolderName(), "", false, params.getUser(), accountingHandler); + Node parentDirectoryNode = Utils.createFolderInternally(params.getSession(), params.getUser(), destination, params.getParentFolderName(), "", false, accountingHandler); params.getSession().save(); try { if (params.getSession().getWorkspace().getLockManager().isLocked(destination.getPath())) @@ -200,13 +198,13 @@ public class ItemHandler { log.debug("creating file with entire path {}, name {}, parentPath {} ", entirePath, name, parentPath); Node fileNode = null; if (parentPath.isEmpty()) - fileNode = createFileItemInternally(params.getSession(), parentDirectoryNode, input, name, "", params.getUser(), false); + fileNode = createFileItemInternally(params.getSession(), authChecker, parentDirectoryNode, input, name, "", params.getUser(), false); else { Node parentNode = directoryNodeMap.get(parentPath); if (parentNode ==null) parentNode = createPath(parentPath, directoryNodeMap, parentDirectoryNode, params.getSession(), params.getUser()); - fileNode = createFileItemInternally(params.getSession(), parentNode, input, name, "", params.getUser(), false); + fileNode = createFileItemInternally(params.getSession(), authChecker, parentNode, input, name, "", params.getUser(), false); } fileNodes.add(fileNode); }catch(Exception e) { @@ -231,7 +229,7 @@ public class ItemHandler { relParentPath.append(parentPathSplit[i]).append("/"); if (relParentPath.toString().isEmpty()) { - Node createdNode = Utils.createFolderInternally(ses, rootNode, name, "", false, user, accountingHandler); + Node createdNode = Utils.createFolderInternally(ses, user, rootNode, name, "", false, accountingHandler); directoryNodeMap.put(name+"/", createdNode); return createdNode; }else { @@ -240,21 +238,21 @@ public class ItemHandler { relParentNode = createPath(relParentPath.toString(), directoryNodeMap, rootNode, ses, user); } - Node createdNode = Utils.createFolderInternally(ses, relParentNode, name, "", false, user, accountingHandler); + Node createdNode = Utils.createFolderInternally(ses, user, relParentNode, name, "", false, accountingHandler); directoryNodeMap.put(relParentPath.append(name).append("/").toString(), createdNode); return createdNode; } } - private Node create(GCubeItemCreationParameters params, Node destination) throws Exception{ + private Node create(GCubeItemCreationParameters params, AuthorizationChecker authChecker, Node destination) throws Exception{ Utils.acquireLockWithWait(params.getSession(), destination.getPath(), false, params.getUser(), 10); Node newNode = Utils.createGcubeItemInternally(params.getSession(), destination, params.getItem().getName(), params.getItem().getDescription(), params.getUser(), params.getItem(), accountingHandler); params.getSession().save(); return newNode; } - private Node createFileItemInternally(Session ses, Node destinationNode, InputStream stream, String name, String description, String login, boolean withLock) throws RepositoryException, UserNotAuthorizedException, ItemLockedException, BackendGenericError{ + private Node createFileItemInternally(Session ses, AuthorizationChecker authChecker, Node destinationNode, InputStream stream, String name, String description, String login, boolean withLock) throws RepositoryException, UserNotAuthorizedException, ItemLockedException, BackendGenericError{ Node newNode; try { @@ -273,7 +271,7 @@ public class ItemHandler { versionHandler.checkoutContentNode(newNode, ses); log.trace("replacing content of class {}",item.getContent().getClass()); item2Node.replaceContent(newNode,item, ItemAction.UPDATED); - accountingHandler.createFileUpdated(item.getTitle(), ses, newNode, false); + accountingHandler.createFileUpdated(item.getTitle(), ses, newNode, login, false); ses.save(); }finally { if (withLock) ses.getWorkspace().getLockManager().unlock(newNode.getPath()); @@ -291,13 +289,13 @@ public class ItemHandler { } try { newNode = item2Node.getNode(destinationNode, item); - accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false); + accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, login, false); ses.save(); }finally { if (withLock) ses.getWorkspace().getLockManager().unlock(destinationNode.getPath()); } versionHandler.makeVersionableContent(newNode, ses); - accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), item.getContent().getMimeType(), ses, destinationNode, false); + accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), item.getContent().getMimeType(), ses, login, destinationNode, false); } return newNode; diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/items/Node2ItemConverter.java b/src/main/java/org/gcube/data/access/storagehub/handlers/items/Node2ItemConverter.java index 95e164d..37100ee 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/items/Node2ItemConverter.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/items/Node2ItemConverter.java @@ -44,11 +44,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton +@SuppressWarnings("rawtypes") public class Node2ItemConverter { private static final Logger logger = LoggerFactory.getLogger(Node2ItemConverter.class); - private static HashMap> typeToSubtypeMap = new HashMap<>(); + + private static HashMap, Map> typeToSubtypeMap = new HashMap<>(); public T getFilteredItem(Node node, List excludes, Class nodeTypeToInclude) throws RepositoryException, BackendGenericError{ @SuppressWarnings("unchecked") @@ -78,7 +80,9 @@ public class Node2ItemConverter { } }*/ - return retrieveItem(node, excludes, classToHandle); + T item = retrieveItem(node, excludes, classToHandle); + item.setRelatedNode(node); + return item; } @@ -171,7 +175,6 @@ public class Node2ItemConverter { Attribute attribute = field.getAnnotation(Attribute.class); field.setAccessible(true); try{ - @SuppressWarnings("rawtypes") Class returnType = field.getType(); field.set(obj, getPropertyValue(returnType, node.getProperty(attribute.value()))); }catch(PathNotFoundException e){ diff --git a/src/main/java/org/gcube/data/access/storagehub/handlers/items/builders/FileCreationParameters.java b/src/main/java/org/gcube/data/access/storagehub/handlers/items/builders/FileCreationParameters.java index 81d423b..20af629 100644 --- a/src/main/java/org/gcube/data/access/storagehub/handlers/items/builders/FileCreationParameters.java +++ b/src/main/java/org/gcube/data/access/storagehub/handlers/items/builders/FileCreationParameters.java @@ -33,7 +33,7 @@ public class FileCreationParameters extends CreateParameters { @Override protected boolean isValid() { - return Objects.nonNull(name) && Objects.nonNull(description) && Objects.nonNull(stream) && Objects.nonNull(fileDetails); + return Objects.nonNull(name) && Objects.nonNull(description) && Objects.nonNull(stream); } @Override 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 a3ed5f8..0ec91a7 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 @@ -22,6 +22,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -43,9 +44,8 @@ import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.common.storagehub.model.items.VreFolder; import org.gcube.common.storagehub.model.types.ACLList; -import org.gcube.data.access.storagehub.AuthorizationChecker; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; -import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.handlers.CredentialHandler; import org.gcube.data.access.storagehub.handlers.UnshareHandler; import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; @@ -57,7 +57,7 @@ import org.slf4j.LoggerFactory; @Path("items") @ManagedBy(StorageHubAppllicationManager.class) -public class ACLManager { +public class ACLManager extends Impersonable { private static final Logger log = LoggerFactory.getLogger(ACLManager.class); @@ -66,7 +66,10 @@ public class ACLManager { @RequestScoped @PathParam("id") String id; - + + @Inject + PathUtil pathUtil; + @Context ServletContext context; @@ -74,9 +77,7 @@ public class ACLManager { @Inject Node2ItemConverter node2Item; - @Inject - AuthorizationChecker authChecker; - + /** * returns the AccessType for all the users in a shared folder * @@ -92,7 +93,7 @@ public class ACLManager { List acls = new ArrayList<>(); try{ ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - authChecker.checkReadAuthorizationControl(ses, id); + authChecker.checkReadAuthorizationControl(ses,id); String path = ses.getNodeByIdentifier(id).getPath(); log.info("checking acces for path {}",path); JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(ses, path ); @@ -190,7 +191,7 @@ public class ACLManager { boolean found = false; while (sharedSet.hasNext() && !found) { Node current = sharedSet.nextNode(); - if (current.getPath().startsWith(Utils.getWorkspacePath(user).toPath())) + if (current.getPath().startsWith(pathUtil.getWorkspacePath(user).toPath())) found = true; } if (!found) @@ -251,8 +252,6 @@ public class ACLManager { try{ ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - String login = AuthorizationProvider.instance.get().getClient().getId(); - Node node = ses.getNodeByIdentifier(id); Item item = node2Item.getItem(node, Excludes.ALL); @@ -266,7 +265,7 @@ public class ACLManager { authChecker.checkAdministratorControl(ses, (SharedFolder) item); - unshareHandler.unshare(ses, Collections.singleton(user), node, login); + unshareHandler.unshare(ses, Collections.singleton(user), node, currentUser); }catch(RepositoryException re){ log.error("jcr error extracting archive", re); @@ -294,7 +293,7 @@ public class ACLManager { throw new InvalidItemException("this method can be applied only to folder"); try { - authChecker.checkWriteAuthorizationControl(ses, id, true); + authChecker.checkWriteAuthorizationControl(ses, id, true); }catch (UserNotAuthorizedException e) { return false; } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java index ad74d72..c896d0c 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java @@ -9,6 +9,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.jcr.Node; import javax.jcr.PathNotFoundException; @@ -45,6 +46,7 @@ import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; 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; @@ -55,6 +57,7 @@ import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.common.storagehub.model.types.PrimaryNodeType; import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.exception.MyAuthException; @@ -95,8 +98,18 @@ public class GroupManager { Node2ItemConverter node2Item; @Inject + PathUtil pathUtil; + AuthorizationChecker authChecker; + @RequestScoped + @Inject + public void setAuthChecker(AuthorizationChecker authChecker) { + this.authChecker = authChecker; + log.info("auth checker initialized with login {}",this.authChecker.getUserToCheck()); + } + + @GET @Path("") @Produces(MediaType.APPLICATION_JSON) @@ -322,16 +335,17 @@ public class GroupManager { @Path("{groupId}/admins") @Produces(MediaType.APPLICATION_JSON) public List getAdmins(@PathParam("groupId") String groupId){ - + InnerMethodName.instance.set("getAdmins"); - + String login = AuthorizationProvider.instance.get().getClient().getId(); + JackrabbitSession session = null; List users = new ArrayList<>(); try { session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, AuthorizationProvider.instance.get().getClient().getId(), node2Item, vreManager, Excludes.ALL); + VRE vreFolder = vreManager.getVreFolderItemByGroupNameAndUser(session, groupId, login, Excludes.ALL); AccessControlManager acm = session.getAccessControlManager(); //authChecker.checkAdministratorControl(session, (VreFolder)vreFolder.getVreFolder()); Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId()); @@ -412,7 +426,7 @@ public class GroupManager { String folderName = group.getPrincipal().getName(); Node folder = groupHandler.getVreFolderNode(session, folderName); - String userPath = String.format("%s%s/%s",Utils.getWorkspacePath(user.getPrincipal().getName()).toPath(),Constants.VRE_FOLDER_PARENT_NAME, folderName); + String userPath = Paths.append(pathUtil.getOldVREsPath(user.getPrincipal().getName()), folderName).toPath(); log.debug("creating folder in user path {} from {}", userPath, folder.getPath() ); session.getWorkspace().clone(session.getWorkspace().getName(), folder.getPath(),userPath , false); @@ -519,7 +533,7 @@ public class GroupManager { log.info("creating vreFolder with name {} and title {} and owner {}", name, displayName, owner); - Node folder= Utils.createFolderInternally(session, sharedRootNode, name, "VREFolder for "+groupId, false, owner, null); + Node folder= Utils.createFolderInternally(session, owner, sharedRootNode, name, "VREFolder for "+groupId, false, null); folder.setPrimaryType(PrimaryNodeType.NT_WORKSPACE_SHARED_FOLDER); folder.setProperty(NodeProperty.IS_VRE_FOLDER.toString(), true); folder.setProperty(NodeProperty.TITLE.toString(), name); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/Impersonable.java b/src/main/java/org/gcube/data/access/storagehub/services/Impersonable.java new file mode 100644 index 0000000..ef47d49 --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/services/Impersonable.java @@ -0,0 +1,49 @@ +package org.gcube.data.access.storagehub.services; + + +import static org.gcube.data.access.storagehub.Roles.INFRASTRUCTURE_MANAGER_ROLE; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; + +import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.authorization.library.provider.ClientInfo; +import org.gcube.data.access.storagehub.AuthorizationChecker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("") +public abstract class Impersonable { + + Logger log = LoggerFactory.getLogger(Impersonable.class); + + AuthorizationChecker authChecker; + + @Context + ServletContext context; + + + + @RequestScoped + String currentUser; + + @RequestScoped + @Inject + public void setAuthChecker(AuthorizationChecker authChecker, @Context final HttpServletRequest request) { + + String impersonate = request!=null ? request.getParameter("impersonate") : null ; + ClientInfo info = AuthorizationProvider.instance.get().getClient(); + if(impersonate!=null && info.getRoles().contains(INFRASTRUCTURE_MANAGER_ROLE)) { + this.currentUser = impersonate; + } else + this.currentUser = info.getId(); + authChecker.setUserToCheck(currentUser); + this.authChecker = authChecker; + log.info("called with login {} and impersonate {}, auth checker initialized with {}",info.getId(), impersonate, authChecker.getUserToCheck()); + } + +} diff --git a/src/main/java/org/gcube/data/access/storagehub/services/ItemSharing.java b/src/main/java/org/gcube/data/access/storagehub/services/ItemSharing.java index 8bc1938..d65f280 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/ItemSharing.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/ItemSharing.java @@ -19,6 +19,7 @@ import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -26,7 +27,6 @@ import javax.ws.rs.core.Response; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.NodeConstants; @@ -41,8 +41,8 @@ import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.common.storagehub.model.types.NodeProperty; import org.gcube.common.storagehub.model.types.PrimaryNodeType; -import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.accounting.AccountingHandler; @@ -58,7 +58,7 @@ import org.slf4j.LoggerFactory; @Path("items") -public class ItemSharing { +public class ItemSharing extends Impersonable{ private static final Logger log = LoggerFactory.getLogger(ItemSharing.class); @@ -71,11 +71,9 @@ public class ItemSharing { @PathParam("id") String id; - @Context - ServletContext context; - + @Inject - AuthorizationChecker authChecker; + PathUtil pathUtil; @Inject UnshareHandler unshareHandler; @@ -83,7 +81,7 @@ public class ItemSharing { @Inject Node2ItemConverter node2Item; @Inject Item2NodeConverter item2Node; - + @SuppressWarnings("unchecked") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @POST @@ -107,7 +105,6 @@ public class ItemSharing { throw new InvalidCallParameters("invalid default accessType"); } - String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkWriteAuthorizationControl(ses, id, false); @@ -131,7 +128,7 @@ public class ItemSharing { ses.save(); try { - ses.getWorkspace().getLockManager().lock(sharedFolderNode.getPath(), true, true, 0,login); + ses.getWorkspace().getLockManager().lock(sharedFolderNode.getPath(), true, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } @@ -142,8 +139,8 @@ public class ItemSharing { if (!alreadyShared) { Privilege[] adminPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) }; - addUserToSharing(sharedFolderNode, ses, login, item, adminPrivileges, acls); - mapUserPermission.remove(login); + addUserToSharing(sharedFolderNode, ses, currentUser, item, adminPrivileges, acls); + mapUserPermission.remove(currentUser); } @@ -162,7 +159,8 @@ public class ItemSharing { acm.setPolicy(sharedFolderNode.getPath(), acls); - accountingHandler.createShareFolder(sharedFolderNode.getProperty(NodeProperty.TITLE.toString()).getString(), mapUserPermission.keySet(), ses, sharedFolderNode, false); + String title = sharedFolderNode.getProperty(NodeProperty.TITLE.toString()).getString(); + accountingHandler.createShareFolder(title, mapUserPermission.keySet(), ses, sharedFolderNode, currentUser, false); ses.save(); @@ -197,7 +195,6 @@ public class ItemSharing { Session ses = null; String toReturn = null; try{ - String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkWriteAuthorizationControl(ses, id, false); @@ -223,7 +220,7 @@ public class ItemSharing { ses.save(); try { - ses.getWorkspace().getLockManager().lock(sharedFolderNode.getPath(), true, true, 0,login); + ses.getWorkspace().getLockManager().lock(sharedFolderNode.getPath(), true, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } @@ -234,8 +231,8 @@ public class ItemSharing { if (!alreadyShared) { Privilege[] adminPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) }; - addUserToSharing(sharedFolderNode, ses, login, item, adminPrivileges, acls); - users.remove(login); + addUserToSharing(sharedFolderNode, ses, currentUser, item, adminPrivileges, acls); + users.remove(currentUser); } Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(accessType.getValue()) }; @@ -249,7 +246,7 @@ public class ItemSharing { acm.setPolicy(sharedFolderNode.getPath(), acls); - accountingHandler.createShareFolder(sharedFolderNode.getProperty(NodeProperty.TITLE.toString()).getString(), users, ses, sharedFolderNode, false); + accountingHandler.createShareFolder(sharedFolderNode.getProperty(NodeProperty.TITLE.toString()).getString(), users, ses, sharedFolderNode, currentUser, false); ses.save(); @@ -276,9 +273,8 @@ public class ItemSharing { private Node shareFolder(Node node, Session ses) throws RepositoryException, BackendGenericError, StorageHubException{ - String login = AuthorizationProvider.instance.get().getClient().getId(); - - if (!node2Item.checkNodeType(node, FolderItem.class) || Utils.hasSharedChildren(node) || !node.getProperty(NodeProperty.PORTAL_LOGIN.toString()).getString().equals(login)) + + if (!node2Item.checkNodeType(node, FolderItem.class) || Utils.hasSharedChildren(node) || !node.getProperty(NodeProperty.PORTAL_LOGIN.toString()).getString().equals(currentUser)) throw new InvalidItemException("item with id "+id+" cannot be shared"); String sharedFolderName = node.getIdentifier(); @@ -298,7 +294,7 @@ public class ItemSharing { String userRootWSId; String userPath; if (itemToShare==null) { - String userRootWS = Utils.getWorkspacePath(user).toPath(); + String userRootWS = pathUtil.getWorkspacePath(user).toPath(); userRootWSId = ses.getNode(userRootWS).getIdentifier(); userPath = String.format("%s%s",userRootWS,sharedFolderNode.getProperty(NodeProperty.TITLE.toString()).getString()); } @@ -327,14 +323,13 @@ public class ItemSharing { @Consumes(MediaType.MULTIPART_FORM_DATA) public String unshare(@FormDataParam("users") Set users){ InnerMethodName.instance.set("unshareFolder"); - String login = AuthorizationProvider.instance.get().getClient().getId(); Session ses = null; String toReturn = null; try { log.debug("unsharing folder with id {} with users {}", id, users); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); Node sharedNode = ses.getNodeByIdentifier(id); - toReturn = unshareHandler.unshare(ses, users, sharedNode, login); + toReturn = unshareHandler.unshare(ses, users, sharedNode, currentUser); if(toReturn == null ) throw new InvalidItemException("item with id "+id+" cannot be unshared"); }catch(RepositoryException re){ log.error("jcr unsharing", re); 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 6f65b38..be27f04 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 @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -13,21 +14,19 @@ import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.compress.archivers.ArchiveException; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.exceptions.StorageHubException; import org.gcube.common.storagehub.model.items.GCubeItem; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; import org.gcube.data.access.storagehub.handlers.CredentialHandler; -import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter; import org.gcube.data.access.storagehub.handlers.items.ItemHandler; -import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; import org.gcube.data.access.storagehub.handlers.items.builders.ArchiveStructureCreationParameter; import org.gcube.data.access.storagehub.handlers.items.builders.FileCreationParameters; import org.gcube.data.access.storagehub.handlers.items.builders.FolderCreationParameters; @@ -44,14 +43,12 @@ import org.slf4j.LoggerFactory; @Path("items") @ManagedBy(StorageHubAppllicationManager.class) -public class ItemsCreator { +public class ItemsCreator extends Impersonable{ private static final Logger log = LoggerFactory.getLogger(ItemsCreator.class); - @Context ServletContext context; - - RepositoryInitializer repository = StorageHubAppllicationManager.repository; + RepositoryInitializer repository = StorageHubAppllicationManager.repository; @Inject ItemHandler itemHandler; @@ -65,10 +62,9 @@ public class ItemsCreator { Session ses = null; String toReturn = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - ItemsParameterBuilder builder = FolderCreationParameters.builder().name(name).description(description).hidden(hidden).on(id).with(ses).author(login); - toReturn = itemHandler.create(builder.build()); + ItemsParameterBuilder builder = FolderCreationParameters.builder().name(name).description(description).hidden(hidden).on(id).with(ses).author(currentUser); + toReturn = itemHandler.create(builder.build(), authChecker); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); @@ -95,13 +91,11 @@ public class ItemsCreator { Session ses = null; String toReturn = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - ItemsParameterBuilder builder = URLCreationParameters.builder().name(name).description(description).url(value).on(id).with(ses).author(login); + ItemsParameterBuilder builder = URLCreationParameters.builder().name(name).description(description).url(value).on(id).with(ses).author(currentUser); - toReturn = itemHandler.create(builder.build()); + toReturn = itemHandler.create(builder.build(), authChecker); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); @@ -130,11 +124,10 @@ public class ItemsCreator { String toReturn = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - ItemsParameterBuilder builder = GCubeItemCreationParameters.builder().item(item).on(id).with(ses).author(login); + ItemsParameterBuilder builder = GCubeItemCreationParameters.builder().item(item).on(id).with(ses).author(currentUser); - toReturn = itemHandler.create(builder.build()); + toReturn = itemHandler.create(builder.build(), authChecker); }catch(StorageHubException she ){ log.error(she.getErrorMessage(), she); GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); @@ -164,13 +157,12 @@ public class ItemsCreator { Session ses = null; String toReturn = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); ItemsParameterBuilder builder = FileCreationParameters.builder().name(name).description(description).stream(stream).fileDetails(fileDetail) - .on(id).with(ses).author(login); + .on(id).with(ses).author(currentUser); - toReturn = itemHandler.create(builder.build()); + toReturn = itemHandler.create(builder.build(), authChecker); }catch(RepositoryException re ){ log.error("jcr error creating file item", re); @@ -207,14 +199,12 @@ public class ItemsCreator { Session ses = null; String toReturn = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); ItemsParameterBuilder builder = ArchiveStructureCreationParameter.builder().parentName(parentFolderName).stream(stream).fileDetails(fileDetail) - .on(id).with(ses).author(login); + .on(id).with(ses).author(currentUser); - toReturn = itemHandler.create(builder.build()); + toReturn = itemHandler.create(builder.build(), authChecker); }catch(RepositoryException | ArchiveException | IOException re){ log.error("jcr error extracting archive", re); 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 b3d40fd..c84c777 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 @@ -44,7 +44,6 @@ import javax.ws.rs.core.StreamingOutput; import org.apache.commons.io.FilenameUtils; import org.gcube.common.authorization.control.annotations.AuthorizationControl; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.encryption.encrypter.StringEncrypter; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.scope.api.ScopeProvider; @@ -69,8 +68,8 @@ import org.gcube.common.storagehub.model.service.ItemWrapper; import org.gcube.common.storagehub.model.service.VersionList; import org.gcube.common.storagehub.model.types.ItemAction; import org.gcube.common.storagehub.model.types.NodeProperty; -import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.Range; import org.gcube.data.access.storagehub.SingleFileStreamingOutput; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; @@ -92,7 +91,7 @@ import org.slf4j.LoggerFactory; @Path("items") @ManagedBy(StorageHubAppllicationManager.class) -public class ItemsManager { +public class ItemsManager extends Impersonable{ private static final Logger log = LoggerFactory.getLogger(ItemsManager.class); @@ -108,20 +107,20 @@ public class ItemsManager { @Context ServletContext context; - @Inject - AuthorizationChecker authChecker; - @Inject VersionHandler versionHandler; @Inject TrashHandler trashHandler; + @Inject PathUtil pathUtil; + @Inject Node2ItemConverter node2Item; @Inject Item2NodeConverter item2Node; @Inject StorageBackendHandler storageBackend; + @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) @@ -380,7 +379,6 @@ public class ItemsManager { log.warn("arrived id is {}",id); Session ses = null; try{ - String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); String complexId = id; @@ -425,9 +423,9 @@ public class ItemsManager { if (!(item instanceof AbstractFileItem)) throw new InvalidCallParameters("the choosen item is not a File"); if (versionName!=null) - return downloadVersionInternal(ses, login, itemId, versionName, false); + return downloadVersionInternal(ses, currentUser, itemId, versionName, false); else - return downloadFileInternal(ses, (AbstractFileItem) item, login, true); + return downloadFileInternal(ses, (AbstractFileItem) item, currentUser, true); }catch(RepositoryException re ){ @@ -648,11 +646,10 @@ public class ItemsManager { InnerMethodName.instance.set("downloadSpecificVersion"); Session ses = null; try{ - String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkReadAuthorizationControl(ses, id); - return downloadVersionInternal(ses, login, id, versionName, true); + return downloadVersionInternal(ses, currentUser, id, versionName, true); }catch(RepositoryException re ){ log.error("jcr error downloading version", re); @@ -690,7 +687,7 @@ public class ItemsManager { String fileName = String.format("%s_v%s.%s", oldfilename, version.getName(), ext); if (withAccounting) - accountingHandler.createReadObj(fileName, ses, node, true); + accountingHandler.createReadObj(fileName, ses, node, login, true); StreamingOutput so = new SingleFileStreamingOutput(streamToWrite); @@ -710,11 +707,11 @@ public class ItemsManager { @Produces(MediaType.APPLICATION_JSON) public ItemList getAnchestors(@QueryParam("exclude") List excludes){ InnerMethodName.instance.set("getAnchestors"); - org.gcube.common.storagehub.model.Path absolutePath = Utils.getWorkspacePath(); + org.gcube.common.storagehub.model.Path absolutePath = pathUtil.getWorkspacePath(currentUser); Session ses = null; List toReturn = new LinkedList<>(); try{ - String login = AuthorizationProvider.instance.get().getClient().getId(); + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkReadAuthorizationControl(ses, id); Node currentNode = ses.getNodeByIdentifier(id); @@ -726,7 +723,7 @@ public class ItemsManager { boolean found = false; while (sharedSetIterator.hasNext()) { Node sharedNode = sharedSetIterator.nextNode(); - if (sharedNode.getPath().startsWith(Utils.getWorkspacePath(login).toPath())) { + if (sharedNode.getPath().startsWith(absolutePath.toPath())) { currentNode = sharedNode.getParent(); found=true; break; @@ -769,17 +766,16 @@ public class ItemsManager { Session ses = null; Response response = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); final Node node = ses.getNodeByIdentifier(id); authChecker.checkReadAuthorizationControl(ses, id); final Item item = node2Item.getItem(node, null); if (item instanceof AbstractFileItem){ - return downloadFileInternal(ses, (AbstractFileItem) item, login, true); + return downloadFileInternal(ses, (AbstractFileItem) item, currentUser, true); } else if (item instanceof FolderItem){ try { - final Deque allNodes = Utils.getAllNodesForZip((FolderItem)item, ses, accountingHandler, excludes); + final Deque allNodes = Utils.getAllNodesForZip((FolderItem)item, ses, currentUser, accountingHandler, excludes); final org.gcube.common.storagehub.model.Path originalPath = Paths.getPath(item.getParentPath()); StreamingOutput so = new StreamingOutput() { @@ -790,7 +786,7 @@ public class ItemsManager { long start = System.currentTimeMillis(); zos.setLevel(Deflater.BEST_COMPRESSION); log.debug("writing StreamOutput"); - Utils.zipNode(zos, allNodes, login, originalPath, storageBackend); + Utils.zipNode(zos, allNodes, currentUser, originalPath, storageBackend); log.debug("StreamOutput written in {}",(System.currentTimeMillis()-start)); } catch (Exception e) { log.error("error writing stream",e); @@ -806,7 +802,7 @@ public class ItemsManager { .header("Content-Length", -1l) .build(); - accountingHandler.createReadObj(item.getTitle(), ses, ses.getNodeByIdentifier(item.getId()), false); + accountingHandler.createReadObj(item.getTitle(), ses, (Node) item.getRelatedNode(), currentUser, false); }finally { if (ses!=null) ses.save(); } @@ -830,7 +826,7 @@ public class ItemsManager { final InputStream streamToWrite = storageBackend.download(fileItem.getContent().getStorageId()); if (withAccounting) - accountingHandler.createReadObj(fileItem.getTitle(), ses, ses.getNodeByIdentifier(fileItem.getId()), true); + accountingHandler.createReadObj(fileItem.getTitle(), ses, (Node) fileItem.getRelatedNode(), login, true); StreamingOutput so = new SingleFileStreamingOutput(streamToWrite); @@ -851,8 +847,7 @@ public class ItemsManager { Session ses = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkMoveOpsForProtectedFolders(ses, id); @@ -884,8 +879,8 @@ public class ItemsManager { try { - ses.getWorkspace().getLockManager().lock(destination.getPath(), false, true, 0,login); - ses.getWorkspace().getLockManager().lock(nodeToMove.getPath(), true, true, 0,login); + ses.getWorkspace().getLockManager().lock(destination.getPath(), false, true, 0,currentUser); + ses.getWorkspace().getLockManager().lock(nodeToMove.getPath(), true, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } @@ -894,15 +889,15 @@ public class ItemsManager { String newPath = String.format("%s/%s",destination.getPath(), uniqueName); ses.getWorkspace().move(nodeToMove.getPath(), newPath); - Utils.setPropertyOnChangeNode(ses.getNode(newPath), login, ItemAction.MOVED); + Utils.setPropertyOnChangeNode(ses.getNode(newPath), currentUser, ItemAction.MOVED); String mimeTypeForAccounting = (item instanceof AbstractFileItem)? ((AbstractFileItem) item).getContent().getMimeType(): null; if (movingSharedItemOutside) - item2Node.updateOwnerOnSubTree(nodeToMove, login); + item2Node.updateOwnerOnSubTree(nodeToMove, currentUser); - accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting , ses, destination, false); - accountingHandler.createFolderRemoveObj(item.getTitle(), item.getClass().getSimpleName(), mimeTypeForAccounting, ses, originalParent, false); + accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting, ses, currentUser, destination, false); + accountingHandler.createFolderRemoveObj(item.getTitle(), item.getClass().getSimpleName(), mimeTypeForAccounting, ses, currentUser, originalParent, false); ses.save(); }finally { ses.getWorkspace().getLockManager().unlock(nodeToMove.getPath()); @@ -931,8 +926,6 @@ public class ItemsManager { Session ses = null; String newFileIdentifier = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - //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(CredentialHandler.getAdminCredentials(context)); @@ -949,8 +942,8 @@ public class ItemsManager { throw new InvalidItemException("folder cannot be copied"); try { - ses.getWorkspace().getLockManager().lock(destination.getPath(), false, true, 0,login); - ses.getWorkspace().getLockManager().lock(nodeToCopy.getPath(), true, true, 0,login); + ses.getWorkspace().getLockManager().lock(destination.getPath(), false, true, 0,currentUser); + ses.getWorkspace().getLockManager().lock(nodeToCopy.getPath(), true, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } @@ -968,13 +961,13 @@ public class ItemsManager { item2Node.replaceContent(newNode, (AbstractFileItem) item, ItemAction.CLONED); } - Utils.setPropertyOnChangeNode(newNode, login, ItemAction.CLONED); - newNode.setProperty(NodeProperty.PORTAL_LOGIN.toString(), login); + Utils.setPropertyOnChangeNode(newNode, currentUser, ItemAction.CLONED); + newNode.setProperty(NodeProperty.PORTAL_LOGIN.toString(), currentUser); newNode.setProperty(NodeProperty.IS_PUBLIC.toString(), false); newNode.setProperty(NodeProperty.TITLE.toString(), uniqueName); String mimeTypeForAccounting = (item instanceof AbstractFileItem)? ((AbstractFileItem) item).getContent().getMimeType(): null; - accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting, ses, destination, false); + accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting, ses, currentUser, destination, false); ses.save(); @@ -1005,8 +998,7 @@ public class ItemsManager { Session ses = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkMoveOpsForProtectedFolders(ses, id); @@ -1024,8 +1016,8 @@ public class ItemsManager { try { - ses.getWorkspace().getLockManager().lock(nodeToMove.getPath(), true, true, 0,login); - ses.getWorkspace().getLockManager().lock(nodeToMove.getParent().getPath(), false, true, 0,login); + ses.getWorkspace().getLockManager().lock(nodeToMove.getPath(), true, true, 0,currentUser); + ses.getWorkspace().getLockManager().lock(nodeToMove.getParent().getPath(), false, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } @@ -1035,9 +1027,9 @@ public class ItemsManager { String newPath = String.format("%s/%s", nodeToMove.getParent().getPath(), uniqueName); nodeToMove.setProperty(NodeProperty.TITLE.toString(), uniqueName); - Utils.setPropertyOnChangeNode(nodeToMove, login, ItemAction.RENAMED); + Utils.setPropertyOnChangeNode(nodeToMove, currentUser, ItemAction.RENAMED); ses.move(nodeToMove.getPath(), newPath); - accountingHandler.createRename(item.getTitle(), uniqueName, ses.getNode(newPath), ses, false); + accountingHandler.createRename(item.getTitle(), uniqueName, ses.getNode(newPath), currentUser, ses, false); ses.save(); }finally { ses.getWorkspace().getLockManager().unlock(nodeToMove.getPath()); @@ -1069,8 +1061,7 @@ public class ItemsManager { Session ses = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkWriteAuthorizationControl(ses, id, false); @@ -1078,12 +1069,12 @@ public class ItemsManager { final Node nodeToUpdate = ses.getNodeByIdentifier(id); try { - ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,login); + ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } try { - item2Node.updateHidden(nodeToUpdate, hidden, login); + item2Node.updateHidden(nodeToUpdate, hidden, currentUser); ses.save(); }finally { ses.getWorkspace().getLockManager().unlock(nodeToUpdate.getPath()); @@ -1115,8 +1106,7 @@ public class ItemsManager { Session ses = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkWriteAuthorizationControl(ses, id, false); @@ -1124,12 +1114,12 @@ public class ItemsManager { final Node nodeToUpdate = ses.getNodeByIdentifier(id); try { - ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,login); + ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } try { - item2Node.updateDescription(nodeToUpdate, description, login); + item2Node.updateDescription(nodeToUpdate, description, currentUser); ses.save(); }finally { ses.getWorkspace().getLockManager().unlock(nodeToUpdate.getPath()); @@ -1160,8 +1150,7 @@ public class ItemsManager { Session ses = null; try{ - final String login = AuthorizationProvider.instance.get().getClient().getId(); - + ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); authChecker.checkWriteAuthorizationControl(ses, id, false); @@ -1169,12 +1158,12 @@ public class ItemsManager { final Node nodeToUpdate = ses.getNodeByIdentifier(id); try { - ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,login); + ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,currentUser); }catch (LockException e) { throw new ItemLockedException(e); } try { - item2Node.updateMetadataNode(nodeToUpdate, metadata.getMap(), login); + item2Node.updateMetadataNode(nodeToUpdate, metadata.getMap(), currentUser); ses.save(); }finally { ses.getWorkspace().getLockManager().unlock(nodeToUpdate.getPath()); @@ -1202,7 +1191,7 @@ public class ItemsManager { @Path("{id}") public Response deleteItem(@QueryParam("force") boolean force){ InnerMethodName.instance.set("deleteItem("+force+")"); - + Session ses = null; try{ @@ -1223,7 +1212,7 @@ public class ItemsManager { log.debug("item is trashed? {}", itemToDelete.isTrashed()); if (!itemToDelete.isTrashed() && !force) { - trashHandler.moveToTrash(ses, nodeToDelete, itemToDelete); + trashHandler.moveToTrash(ses, nodeToDelete, itemToDelete, currentUser); }else trashHandler.removeNodes(ses, Collections.singletonList(itemToDelete)); diff --git a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java index 49202c1..082e83f 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/UserManager.java @@ -36,7 +36,6 @@ import org.apache.jackrabbit.core.security.principal.PrincipalImpl; import org.gcube.common.authorization.control.annotations.AuthorizationControl; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.storagehub.model.Excludes; -import org.gcube.common.storagehub.model.Paths; import org.gcube.common.storagehub.model.exceptions.BackendGenericError; import org.gcube.common.storagehub.model.exceptions.IdNotFoundException; import org.gcube.common.storagehub.model.exceptions.StorageHubException; @@ -45,6 +44,7 @@ import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.SharedFolder; import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; import org.gcube.data.access.storagehub.Utils; import org.gcube.data.access.storagehub.exception.MyAuthException; @@ -77,10 +77,10 @@ public class UserManager { @Inject GroupHandler groupHandler; - + @Inject - AuthorizationChecker authChecker; - + PathUtil pathUtil; + @GET @Path("") @Produces(MediaType.APPLICATION_JSON) @@ -178,13 +178,15 @@ public class UserManager { Node homeNode = session.getNode("/Home"); Node userHome = homeNode.addNode(user, "nthl:home"); - + + //TODO: changing version + //creating workspace folder - Node workspaceFolder = Utils.createFolderInternally(session, userHome, Constants.WORKSPACE_ROOT_FOLDER_NAME, "workspace of "+user, false, user, null); + Node workspaceFolder = Utils.createFolderInternally(session, user, userHome, Constants.WORKSPACE_ROOT_FOLDER_NAME, "workspace of "+user, false, null); //creating thrash folder - Utils.createFolderInternally(session, workspaceFolder, Constants.TRASH_ROOT_FOLDER_NAME, "trash of "+user, false, user, null); + Utils.createFolderInternally(session, user, workspaceFolder, Constants.TRASH_ROOT_FOLDER_NAME, "trash of "+user, false, null); //creating Vre container folder - Utils.createFolderInternally(session, workspaceFolder, Constants.VRE_FOLDER_PARENT_NAME, "special folder container of "+user, false, user, null); + Utils.createFolderInternally(session, user, workspaceFolder, Constants.OLD_VRE_FOLDER_PARENT_NAME, "special folder container of "+user, false, null); session.save(); }catch(StorageHubException she ){ @@ -275,12 +277,13 @@ public class UserManager { Node sharedFolderNode = session.getNode(Constants.SHARED_FOLDER_PATH); + AuthorizationChecker authChecker = new AuthorizationChecker(user); Predicate sharedWithUserChecker = new Predicate() { @Override public boolean test(Node t) { try { - authChecker.checkReadAuthorizationControl(t.getSession(), user, t.getIdentifier()); + authChecker.checkReadAuthorizationControl(t.getSession(), t.getIdentifier()); return true; } catch (UserNotAuthorizedException | BackendGenericError | RepositoryException e) { return false; @@ -315,9 +318,9 @@ public class UserManager { } private void removeUserHomeAndDeleteFiles(JackrabbitSession session, String user) throws RepositoryException, StorageHubException { - org.gcube.common.storagehub.model.Path homePath = Utils.getHome(user); - org.gcube.common.storagehub.model.Path workspacePath = Utils.getWorkspacePath(user); - org.gcube.common.storagehub.model.Path trashPath = Paths.append(workspacePath, Constants.TRASH_ROOT_FOLDER_NAME); + org.gcube.common.storagehub.model.Path homePath = pathUtil.getHome(user); + org.gcube.common.storagehub.model.Path workspacePath = pathUtil.getWorkspacePath(user); + org.gcube.common.storagehub.model.Path trashPath = pathUtil.getOldTrashPath(user); try { Node workspaceNode = session.getNode(workspacePath.toPath()); 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 0e867df..d52479e 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 @@ -14,7 +14,6 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.query.Query; import javax.jcr.query.QueryResult; -import javax.servlet.ServletContext; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; @@ -27,7 +26,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; -import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; import org.gcube.common.storagehub.model.Excludes; import org.gcube.common.storagehub.model.Paths; @@ -44,8 +42,8 @@ import org.gcube.common.storagehub.model.items.Item; import org.gcube.common.storagehub.model.items.TrashItem; import org.gcube.common.storagehub.model.service.ItemList; import org.gcube.common.storagehub.model.service.ItemWrapper; -import org.gcube.data.access.storagehub.AuthorizationChecker; import org.gcube.data.access.storagehub.Constants; +import org.gcube.data.access.storagehub.PathUtil; import org.gcube.data.access.storagehub.Range; import org.gcube.data.access.storagehub.StorageHubAppllicationManager; import org.gcube.data.access.storagehub.Utils; @@ -66,7 +64,7 @@ import org.slf4j.LoggerFactory; @Path("") @ManagedBy(StorageHubAppllicationManager.class) -public class WorkspaceManager { +public class WorkspaceManager extends Impersonable{ private static final Logger log = LoggerFactory.getLogger(WorkspaceManager.class); @@ -76,11 +74,7 @@ public class WorkspaceManager { Evaluators evaluator; @Inject - AuthorizationChecker authChecker; - - - @Inject - ServletContext context; + PathUtil pathUtil; @Inject VREManager vreManager; @@ -97,6 +91,8 @@ public class WorkspaceManager { @Inject StorageBackendHandler storageBackend; + + @Path("") @GET @Produces(MediaType.APPLICATION_JSON) @@ -105,19 +101,19 @@ public class WorkspaceManager { Session ses = null; org.gcube.common.storagehub.model.Path absolutePath; if (relPath==null) - absolutePath = Utils.getWorkspacePath(); - else absolutePath = Paths.append(Utils.getWorkspacePath(), relPath); + absolutePath = pathUtil.getWorkspacePath(currentUser); + else absolutePath = Paths.append(pathUtil.getWorkspacePath(currentUser), relPath); Item toReturn = null; try{ long start = System.currentTimeMillis(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - //TODO: remove it when users will be created via storageHub - String user = AuthorizationProvider.instance.get().getClient().getId(); - org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getWorkspacePath(), Constants.TRASH_ROOT_FOLDER_NAME); + //TODO: remove when all user will have TRASH + org.gcube.common.storagehub.model.Path trashPath = pathUtil.getOldTrashPath(currentUser); if (!ses.nodeExists(trashPath.toPath())) { - Utils.createFolderInternally(ses, ses.getNode(Utils.getWorkspacePath().toPath()) , Constants.TRASH_ROOT_FOLDER_NAME, "trash of "+user, false, user, null); + Node wsNode = ses.getNode(pathUtil.getWorkspacePath(currentUser).toPath()); + Utils.createFolderInternally(ses, currentUser, wsNode, Constants.TRASH_ROOT_FOLDER_NAME, "trash of "+currentUser, false, null); ses.save(); } @@ -170,7 +166,7 @@ public class WorkspaceManager { Item vreItem = null; try { ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - vreItem = Utils.getVreFolderItem(ses, node2Item, vreManager, excludes).getVreFolder(); + vreItem = vreManager.getVreFolderItem(ses, currentUser, excludes).getVreFolder(); }catch(RepositoryException re ){ log.error("jcr error getting vrefolder", re); GXOutboundErrorResponse.throwException(new BackendGenericError(re)); @@ -192,10 +188,9 @@ public class WorkspaceManager { Session ses = null; List recentItems = Collections.emptyList(); try{ - //String login = AuthorizationProvider.instance.get().getClient().getId(); ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - VRE vre = Utils.getVreFolderItem(ses, node2Item, vreManager, excludes); + VRE vre = vreManager.getVreFolderItem(ses, currentUser, excludes); log.trace("VRE retrieved {}",vre.getVreFolder().getTitle()); recentItems = vre.getRecents(); log.trace("recents retrieved {}",vre.getVreFolder().getTitle()); @@ -223,8 +218,7 @@ public class WorkspaceManager { public ItemWrapper getTrashRootFolder(){ InnerMethodName.instance.set("getTrashRootFolder"); Session ses = null; - //String user = AuthorizationProvider.instance.get().getClient().getId(); - org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getWorkspacePath(), Constants.TRASH_ROOT_FOLDER_NAME); + org.gcube.common.storagehub.model.Path trashPath = pathUtil.getOldTrashPath(currentUser); Item item = null; try{ long start = System.currentTimeMillis(); @@ -245,15 +239,15 @@ public class WorkspaceManager { } return new ItemWrapper(item); - } + @Path("trash/empty") @DELETE public String emptyTrash(){ InnerMethodName.instance.set("emptyTrash"); Session ses = null; - org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getWorkspacePath(), Constants.TRASH_ROOT_FOLDER_NAME); + org.gcube.common.storagehub.model.Path trashPath = pathUtil.getOldTrashPath(currentUser); String toReturn = null; try{ ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); @@ -298,10 +292,9 @@ public class WorkspaceManager { if (!(itemToRestore instanceof TrashItem)) throw new InvalidItemException("Only trash items can be restored"); - String user = AuthorizationProvider.instance.get().getClient().getId(); - org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getWorkspacePath(), Constants.TRASH_ROOT_FOLDER_NAME); + org.gcube.common.storagehub.model.Path trashPath = pathUtil.getOldTrashPath(currentUser); if (!itemToRestore.getPath().startsWith(trashPath.toPath())) - throw new UserNotAuthorizedException("this item is not in the user "+user+" trash"); + throw new UserNotAuthorizedException("this item is not in the user "+currentUser+" trash"); Item destinationItem = null; if (destinationFolderId!=null ) { @@ -309,9 +302,9 @@ public class WorkspaceManager { if (!(destinationItem instanceof FolderItem)) throw new InvalidCallParameters("destintation item is not a folder"); - toReturn = trashHandler.restoreItem(ses, (TrashItem)itemToRestore, (FolderItem) destinationItem); + toReturn = trashHandler.restoreItem(ses, (TrashItem)itemToRestore, (FolderItem) destinationItem, currentUser); } else { - toReturn = trashHandler.restoreItem(ses, (TrashItem)itemToRestore, null); + toReturn = trashHandler.restoreItem(ses, (TrashItem)itemToRestore, null, currentUser); } @@ -338,7 +331,7 @@ public class WorkspaceManager { InnerMethodName.instance.set("getVreFolders"); Session ses = null; - org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME); + org.gcube.common.storagehub.model.Path vrePath = pathUtil.getOldVREsPath(currentUser); List toReturn = null; try{ log.info("vres folder path is {}",vrePath.toPath()); @@ -364,7 +357,7 @@ public class WorkspaceManager { public ItemList getVreFoldersPaged(@QueryParam("start") Integer start, @QueryParam("limit") Integer limit){ InnerMethodName.instance.set("getVreFoldersPaged"); Session ses = null; - org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME); + org.gcube.common.storagehub.model.Path vrePath = pathUtil.getOldVREsPath(currentUser); List toReturn = null; try{ ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); @@ -397,7 +390,7 @@ public class WorkspaceManager { ObjectMapper mapper = new ObjectMapper(); Expression expression = mapper.readValue(jsonExpr, Expression.class); - String stringExpression = evaluator.evaluate(new And(new ISDescendant(Utils.getWorkspacePath()), expression)); + String stringExpression = evaluator.evaluate(new And(new ISDescendant(pathUtil.getWorkspacePath(currentUser)), expression)); String orderBy = ""; if (orderField!=null && orderField.size()>0) @@ -438,6 +431,8 @@ public class WorkspaceManager { return new ItemList(toReturn); } + + @Path("count") @GET public String getTotalItemsCount(){ @@ -453,5 +448,5 @@ public class WorkspaceManager { return storageBackend.getTotalVolume(); } - + } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/admin/ItemManagerAdmin.java b/src/main/java/org/gcube/data/access/storagehub/services/admin/ItemManagerAdmin.java deleted file mode 100644 index b3d2dce..0000000 --- a/src/main/java/org/gcube/data/access/storagehub/services/admin/ItemManagerAdmin.java +++ /dev/null @@ -1,316 +0,0 @@ -package org.gcube.data.access.storagehub.services.admin; - -import static org.gcube.data.access.storagehub.Roles.INFRASTRUCTURE_MANAGER_ROLE; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import javax.inject.Inject; -import javax.jcr.Node; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.security.AccessControlEntry; -import javax.jcr.security.Privilege; -import javax.jcr.version.Version; -import javax.servlet.ServletContext; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.jackrabbit.api.JackrabbitSession; -import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; -import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; -import org.gcube.common.authorization.control.annotations.AuthorizationControl; -import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse; -import org.gcube.common.storagehub.model.Excludes; -import org.gcube.common.storagehub.model.acls.ACL; -import org.gcube.common.storagehub.model.acls.AccessType; -import org.gcube.common.storagehub.model.exceptions.BackendGenericError; -import org.gcube.common.storagehub.model.exceptions.StorageHubException; -import org.gcube.common.storagehub.model.items.Item; -import org.gcube.common.storagehub.model.service.ItemList; -import org.gcube.common.storagehub.model.service.ItemWrapper; -import org.gcube.common.storagehub.model.types.ACLList; -import org.gcube.data.access.storagehub.StorageHubAppllicationManager; -import org.gcube.data.access.storagehub.Utils; -import org.gcube.data.access.storagehub.exception.MyAuthException; -import org.gcube.data.access.storagehub.handlers.CredentialHandler; -import org.gcube.data.access.storagehub.handlers.TrashHandler; -import org.gcube.data.access.storagehub.handlers.VersionHandler; -import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter; -import org.gcube.data.access.storagehub.handlers.items.Item2NodeConverter.Values; -import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; -import org.gcube.data.access.storagehub.services.RepositoryInitializer; -import org.gcube.smartgears.utils.InnerMethodName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -@Path("admin") -public class ItemManagerAdmin { - - private static final Logger log = LoggerFactory.getLogger(ItemManagerAdmin.class); - - RepositoryInitializer repository = StorageHubAppllicationManager.repository; - - @Inject - Node2ItemConverter node2Item; - - @Inject - TrashHandler trashHandler; - - @Inject - VersionHandler versionHandler; - - @Context ServletContext context; - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Path("items/{id}") - @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) - public String createItem(@PathParam("id") String id, Item item) { - InnerMethodName.instance.set("creteItemAdmin)"); - //TODO: implement this method - return null; - } - - - @GET - @Produces(MediaType.APPLICATION_JSON) - @Path("byPath/children") - @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) - public ItemList getbyPath(@QueryParam("path") String path) { - InnerMethodName.instance.set("getByPathChildrenAdmin"); - - List items =null; - Session session = null; - try{ - session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - - Node node = session.getNode(path); - items = Utils.getItemList(node, Excludes.EXCLUDE_ACCOUNTING , null, true, null); - }catch(RepositoryException re ){ - log.error("jcr error getting children by path", re); - GXOutboundErrorResponse.throwException(new BackendGenericError(re)); - }catch(StorageHubException she ){ - log.error(she.getErrorMessage(), she); - GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); - } finally{ - if (session!=null) { - session.logout(); - } - } - return new ItemList(items); - } - - @GET - @Produces(MediaType.APPLICATION_JSON) - @Path("{user}") - @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) - public ItemWrapper getWorkspace(@PathParam("user") String user) { - InnerMethodName.instance.set("getWorkspaceAdmin"); - - Item item =null; - Session session = null; - try{ - session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - String workspacePath = Utils.getWorkspacePath(user).toPath(); - Node node = session.getNode(workspacePath); - item = node2Item.getItem(node, Collections.emptyList()); - - }catch(RepositoryException re ){ - log.error("jcr error getting WS admin", re); - GXOutboundErrorResponse.throwException(new BackendGenericError(re)); - }catch(StorageHubException she ){ - log.error(she.getErrorMessage(), she); - GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); - } finally{ - if (session!=null) { - session.logout(); - } - } - return new ItemWrapper(item); - } - - @GET - @Produces(MediaType.APPLICATION_JSON) - @Path("items/{id}") - @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) - public ItemWrapper getItem(@PathParam("id") String id) { - InnerMethodName.instance.set("getItemAdmin"); - - Item item =null; - Session session = null; - try{ - session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - Node node = session.getNodeByIdentifier(id); - - item = node2Item.getItem(node, Collections.emptyList()); - - }catch(RepositoryException re ){ - log.error("jcr error getting item admin", re); - GXOutboundErrorResponse.throwException(new BackendGenericError(re)); - }catch(StorageHubException she ){ - log.error(she.getErrorMessage(), she); - GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); - } finally{ - if (session!=null) { - session.logout(); - } - } - return new ItemWrapper(item); - } - - @DELETE - @Produces(MediaType.APPLICATION_JSON) - @Path("items/{id}") - @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) - public void deleteItem(@PathParam("id") String id) { - InnerMethodName.instance.set("deleteAdmin"); - - Session session = null; - try{ - session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - Node node = session.getNodeByIdentifier(id); - - Item item = node2Item.getItem(node, Excludes.GET_ONLY_CONTENT); - - trashHandler.removeNodes(session, Collections.singletonList(item)); - - }catch(RepositoryException re ){ - log.error("jcr error deleting item admin", re); - GXOutboundErrorResponse.throwException(new BackendGenericError(re)); - }catch(StorageHubException she ){ - log.error(she.getErrorMessage(), she); - GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); - } finally{ - if (session!=null) { - session.logout(); - } - } - } - - - - @GET - @Produces(MediaType.APPLICATION_JSON) - @Path("items/{id}/children") - @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) - public ItemList getChildren(@PathParam("id") String id) { - InnerMethodName.instance.set("getChildrenAdmin"); - - List items =null; - Session session = null; - try{ - session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - Node node = session.getNodeByIdentifier(id); - - items = Utils.getItemList(node, Collections.emptyList(), null, true, null); - - }catch(RepositoryException re ){ - log.error("jcr error getting children admin", re); - GXOutboundErrorResponse.throwException(new BackendGenericError(re)); - }catch(StorageHubException she ){ - log.error(she.getErrorMessage(), she); - GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus())); - } finally{ - if (session!=null) { - session.logout(); - } - } - return new ItemList(items); - } - - @PUT - @Consumes(MediaType.APPLICATION_OCTET_STREAM) - @Path("items/{id}/{propertyName}") - @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) - public void setProperty(@PathParam("id") String id, @QueryParam("path") String subPath, @PathParam("propertyName") String propertyName, String value) { - InnerMethodName.instance.set("setPropertyAdmin"); - - Session session = null; - try{ - session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - Node node = session.getNodeByIdentifier(id); - if (subPath!=null) - node = node.getNode(subPath); - boolean checkedIn = false; - if (!node.isCheckedOut()) { - checkedIn=true; - versionHandler.checkoutContentNode(node, session); - } - - Values internalValue = Item2NodeConverter.getObjectValue(value.getClass(), value); - node.setProperty(propertyName, internalValue.getValue()); - session.save(); - - if (checkedIn) { - versionHandler.checkinContentNode(node, session); - List versions = versionHandler.getContentVersionHistory(node, session); - if (versions.size()>1) { - - log.info("removing version {} ",versions.get(versions.size()-2).getName()); - session.removeItem(versions.get(versions.size()-2).getPath()); - - } - } - - }catch(Exception re ){ - log.error("jcr error setting prop admin", re); - GXOutboundErrorResponse.throwException(new BackendGenericError(re)); - } finally{ - if (session!=null) { - session.logout(); - } - } - - } - - @GET - @Path("items/{id}/acls") - @Produces(MediaType.APPLICATION_JSON) - public ACLList getACL(@PathParam("id") String id) { - InnerMethodName.instance.set("getACLByIdAdmin"); - Session ses = null; - List acls = new ArrayList<>(); - try{ - ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); - String path = ses.getNodeByIdentifier(id).getPath(); - log.info("checking acces for path {}",path); - JackrabbitAccessControlList accessControlList = AccessControlUtils.getAccessControlList(ses, path ); - 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); - } - - }catch(RepositoryException re){ - log.error("jcr error getting acl", re); - GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting acl", re)); - }finally{ - if (ses!=null) - ses.logout(); - } - return new ACLList(acls); - - } - -} diff --git a/src/main/java/org/gcube/data/access/storagehub/services/admin/NodeManagerAdmin.java b/src/main/java/org/gcube/data/access/storagehub/services/admin/NodeManagerAdmin.java index b614913..c5b9214 100644 --- a/src/main/java/org/gcube/data/access/storagehub/services/admin/NodeManagerAdmin.java +++ b/src/main/java/org/gcube/data/access/storagehub/services/admin/NodeManagerAdmin.java @@ -12,6 +12,7 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.servlet.ServletContext; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -114,4 +115,5 @@ public class NodeManagerAdmin { return node.getIdentifier()+" "+node.getName()+" "+node.getPrimaryNodeType().getName(); } + } diff --git a/src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptManager.java b/src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptManager.java new file mode 100644 index 0000000..f367abd --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptManager.java @@ -0,0 +1,205 @@ +package org.gcube.data.access.storagehub.services.admin; + +import static org.gcube.data.access.storagehub.Roles.INFRASTRUCTURE_MANAGER_ROLE; + +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.jcr.Node; +import javax.servlet.ServletContext; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +import org.apache.cxf.io.ReaderInputStream; +import org.apache.jackrabbit.api.JackrabbitSession; +import org.gcube.common.authorization.control.annotations.AuthorizationControl; +import org.gcube.common.authorization.library.AuthorizedTasks; +import org.gcube.common.authorization.library.provider.AuthorizationProvider; +import org.gcube.common.storagehub.model.Paths; +import org.gcube.data.access.storagehub.AuthorizationChecker; +import org.gcube.data.access.storagehub.PathUtil; +import org.gcube.data.access.storagehub.StorageHubAppllicationManager; +import org.gcube.data.access.storagehub.accounting.AccountingHandler; +import org.gcube.data.access.storagehub.exception.MyAuthException; +import org.gcube.data.access.storagehub.handlers.CredentialHandler; +import org.gcube.data.access.storagehub.handlers.items.ItemHandler; +import org.gcube.data.access.storagehub.handlers.items.builders.FileCreationParameters; +import org.gcube.data.access.storagehub.handlers.items.builders.ItemsParameterBuilder; +import org.gcube.data.access.storagehub.scripting.AbstractScript; +import org.gcube.data.access.storagehub.scripting.ScriptUtil; +import org.gcube.data.access.storagehub.services.RepositoryInitializer; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("admin/script") +public class ScriptManager { + + + private static Logger log = LoggerFactory.getLogger(ScriptManager.class); + + private RepositoryInitializer repository = StorageHubAppllicationManager.repository; + + @Inject + AccountingHandler accountingHandler; + + @Context + ServletContext context; + + AuthorizationChecker authChecker; + + @RequestScoped + @Inject + public void setAuthChecker(AuthorizationChecker authChecker) { + this.authChecker = authChecker; + log.info("auth checker initialized with login {}",this.authChecker.getUserToCheck()); + } + + @Inject + ScriptUtil scriptUtil; + + @Inject + ItemHandler itemHandler; + + @Inject + PathUtil pathUtil; + + @POST + @Path("execute") + @AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class) + @Consumes(MediaType.MULTIPART_FORM_DATA) + public String run( @FormDataParam("name") String name, + @FormDataParam("asynch") Boolean asynch, + @FormDataParam("destinationFolderId") String destinationFolderId, + @FormDataParam("file") InputStream stream, + @FormDataParam("file") FormDataContentDisposition fileDetail) { + try { + ScriptClassLoader scriptClassLoader = new ScriptClassLoader(Thread.currentThread().getContextClassLoader()); + Class scriptClass = uploadClass(stream, scriptClassLoader, name); + return run(scriptClass, name, destinationFolderId, asynch!=null? asynch : false); + }catch(Throwable e) { + log.error("error executing script {}", name,e); + throw new WebApplicationException("error loading class",e); + } + } + + + private Class uploadClass(InputStream stream, ScriptClassLoader classLoader, String name) throws Throwable { + try(ByteArrayOutputStream buffer = new ByteArrayOutputStream()){ + int nRead; + byte[] data = new byte[1024]; + while ((nRead = stream.read(data, 0, data.length)) != -1) + buffer.write(data, 0, nRead); + + buffer.flush(); + byte[] byteArray = buffer.toByteArray(); + return classLoader.findClass(name, byteArray); + } + + } + + private String run(Class clazz, String name, String destinationFolderId, boolean asynch) throws Throwable { + String login = AuthorizationProvider.instance.get().getClient().getId(); + log.info("script {} called by {}", clazz.getSimpleName(), login); + JackrabbitSession ses = null; + + try { + ses = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context)); + + String parentId = destinationFolderId!=null ? destinationFolderId : ses.getNode(pathUtil.getWorkspacePath(login).toPath()).getIdentifier(); + Node parentNode = ses.getNodeByIdentifier(parentId); + String parentPath = parentNode.getPath(); + + if (AbstractScript.class.isAssignableFrom(clazz)) { + AbstractScript scriptInstance = (AbstractScript) clazz.newInstance(); + + RealRun realRun = new RealRun(ses, scriptInstance, login, parentId, name); + if (asynch) { + new Thread(AuthorizedTasks.bind(realRun)).start(); + }else realRun.run(); + + } else throw new Exception("class "+clazz.getSimpleName()+" not implements AbstractScript"); + + return Paths.append(Paths.getPath(parentPath), name).toPath(); + + }catch (Throwable e) { + if (ses !=null && ses.isLive()) + ses.logout(); + throw e; + } + + + } + + + class RealRun implements Runnable{ + + private JackrabbitSession ses; + AbstractScript instance; + String login; + String parentId; + String name; + + public RealRun(JackrabbitSession ses, AbstractScript instance, String login, String parentId, String name) { + super(); + this.ses = ses; + this.instance = instance; + this.login = login; + this.parentId = parentId; + this.name = name; + } + + + @Override + public void run() { + try{ + String result =""; + try { + result = instance.run(ses, null, scriptUtil); + log.info("result is {}",result); + }catch(Throwable t) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw, true); + t.printStackTrace(pw); + result+= "\n"+sw.toString(); + } + + try( InputStream stream = new ReaderInputStream(new StringReader(result))){ + ItemsParameterBuilder builder = FileCreationParameters.builder().name(name).description("result of script execution "+name) + .stream(stream).on(parentId).with(ses).author(login); + itemHandler.create(builder.build(), authChecker); + } catch (Throwable e) { + log.error("error saving script result {} in the Workspace",name); + } + + } finally { + if (ses!=null) + ses.logout(); + } + + } + + } + + class ScriptClassLoader extends ClassLoader{ + + public ScriptClassLoader(ClassLoader parent) { + super(parent); + } + + public Class findClass(String name, byte[] b) { + return defineClass(name, b, 0, b.length); + } + } + +} diff --git a/src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptUtilImpl.java b/src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptUtilImpl.java new file mode 100644 index 0000000..a44a479 --- /dev/null +++ b/src/main/java/org/gcube/data/access/storagehub/services/admin/ScriptUtilImpl.java @@ -0,0 +1,33 @@ +package org.gcube.data.access.storagehub.services.admin; + +import java.util.List; +import java.util.function.Predicate; + +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.gcube.common.storagehub.model.exceptions.BackendGenericError; +import org.gcube.common.storagehub.model.items.Item; +import org.gcube.data.access.storagehub.Range; +import org.gcube.data.access.storagehub.Utils; +import org.gcube.data.access.storagehub.handlers.items.Node2ItemConverter; +import org.gcube.data.access.storagehub.scripting.ScriptUtil; + +@Singleton +public class ScriptUtilImpl implements ScriptUtil { + + @Inject Node2ItemConverter node2Item; + + @Override + public List getChildren(Predicate checker, Node parent, List excludes, boolean showHidden, Class nodeTypeToInclude) throws RepositoryException, BackendGenericError { + return Utils.getItemList(checker, parent, excludes, new Range(0, 100), showHidden, nodeTypeToInclude); + } + + @Override + public Item getItem(Node node, List excludes) throws RepositoryException, BackendGenericError { + return node2Item.getItem(node, excludes); + } + +} diff --git a/src/main/webapp/WEB-INF/README b/src/main/webapp/WEB-INF/README index 705dedc..c4b3588 100644 --- a/src/main/webapp/WEB-INF/README +++ b/src/main/webapp/WEB-INF/README @@ -25,7 +25,7 @@ The projects leading to this software have received funding from a series of Version -------------------------------------------------- -1.2.5-SNAPSHOT (20210315-104913) +1.3.0-SNAPSHOT (20210331-113723) Please see the file named "changelog.xml" in this directory for the release notes. diff --git a/src/main/webapp/WEB-INF/gcube-app.xml b/src/main/webapp/WEB-INF/gcube-app.xml index fcdcb1f..52098e5 100644 --- a/src/main/webapp/WEB-INF/gcube-app.xml +++ b/src/main/webapp/WEB-INF/gcube-app.xml @@ -1,7 +1,7 @@ StorageHub DataAccess - 1.2.5-SNAPSHOT + 1.3.0-SNAPSHOT Storage Hub webapp \ No newline at end of file