- possibility to impersonate people added
This commit is contained in:
parent
64952442ed
commit
a2613dc1a7
|
@ -13,15 +13,15 @@
|
|||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -16,7 +19,10 @@
|
|||
|
||||
|
||||
<wb-module deploy-name="storagehub">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -33,7 +39,10 @@
|
|||
|
||||
|
||||
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -50,7 +59,10 @@
|
|||
|
||||
|
||||
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -67,7 +79,10 @@
|
|||
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -84,7 +99,16 @@
|
|||
|
||||
|
||||
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||
|
||||
<dependent-module archiveName="storagehub-model-1.0.10-SNASPHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/storagehub-model/storagehub-model">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
<dependent-module archiveName="storagehub-scripting-util-1.0.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/storagehub-scripting-util/storagehub-scripting-util">
|
||||
<dependency-type>uses</dependency-type>
|
||||
</dependent-module>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -101,7 +125,10 @@
|
|||
|
||||
|
||||
<property name="context-root" value="storagehub"/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -118,7 +145,10 @@
|
|||
|
||||
|
||||
<property name="java-output-path" value="/storagehub-webapp_BRANCH/target/classes"/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -135,7 +165,10 @@
|
|||
|
||||
|
||||
</wb-module>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
17
pom.xml
17
pom.xml
|
@ -12,7 +12,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.gcube.data.access</groupId>
|
||||
<artifactId>storagehub</artifactId>
|
||||
<version>1.2.5</version>
|
||||
<version>1.3.0-SNAPSHOT</version>
|
||||
<name>storagehub</name>
|
||||
|
||||
<scm>
|
||||
|
@ -107,6 +107,12 @@
|
|||
<version>[1.0.0,2.0.0-SNAPSHOT)</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.gcube.data.access</groupId>
|
||||
<artifactId>storagehub-scripting-util</artifactId>
|
||||
<version>[1.0.0-SNAPSHOT,2.0.0)</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>itextpdf</artifactId>
|
||||
|
@ -192,7 +198,7 @@
|
|||
<artifactId>javamelody-core</artifactId>
|
||||
<version>1.82.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- jersey & weld -->
|
||||
<dependency>
|
||||
|
@ -200,21 +206,21 @@
|
|||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/javax.interceptor/javax.interceptor-api -->
|
||||
<dependency>
|
||||
<groupId>javax.interceptor</groupId>
|
||||
<artifactId>javax.interceptor-api</artifactId>
|
||||
<version>1.2.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
<artifactId>cdi-api</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
|
@ -436,7 +442,6 @@
|
|||
<pluginExecutionFilter>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
|
||||
<versionRange>[1.0,)</versionRange>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
|
|
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String> FOLDERS_TO_EXLUDE = Arrays.asList(Constants.VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME);
|
||||
public static final List<String> FOLDERS_TO_EXLUDE = Arrays.asList(Constants.OLD_VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME);
|
||||
|
||||
public static final List<String> WRITE_PROTECTED_FOLDER = Arrays.asList(Constants.VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME);
|
||||
public static final List<String> WRITE_PROTECTED_FOLDER = Arrays.asList(Constants.OLD_VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME);
|
||||
|
||||
public static final List<String> PROTECTED_FOLDER = Arrays.asList(Constants.WORKSPACE_ROOT_FOLDER_NAME, Constants.VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME);
|
||||
public static final List<String> PROTECTED_FOLDER = Arrays.asList(Constants.WORKSPACE_ROOT_FOLDER_NAME, Constants.OLD_VRE_FOLDER_PARENT_NAME, Constants.TRASH_ROOT_FOLDER_NAME);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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<Class<?>> getClasses() {
|
||||
final Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
// 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;
|
||||
|
|
|
@ -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<Item> getAllNodesForZip(FolderItem directory, Session session, AccountingHandler accountingHandler, List<String> excludes) throws RepositoryException, BackendGenericError{
|
||||
public static Deque<Item> getAllNodesForZip(FolderItem directory, Session session, String login, AccountingHandler accountingHandler, List<String> excludes) throws RepositoryException, BackendGenericError{
|
||||
Deque<Item> queue = new LinkedList<Item>();
|
||||
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<String> 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<String> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String> users, Session ses, Node sharedNode, boolean saveHistory ) {
|
||||
public void createShareFolder(String title, Set<String> 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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<String> 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<String> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 <T extends CreateParameters> String create(T parameters) throws Exception{
|
||||
public <T extends CreateParameters> 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;
|
||||
|
|
|
@ -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<Class, Map<String, Class>> typeToSubtypeMap = new HashMap<>();
|
||||
|
||||
private static HashMap<Class<?>, Map<String, Class>> typeToSubtypeMap = new HashMap<>();
|
||||
|
||||
public <T extends Item> T getFilteredItem(Node node, List<String> excludes, Class<? extends Item> 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){
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<ACL> 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;
|
||||
}
|
||||
|
|
|
@ -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<String> getAdmins(@PathParam("groupId") String groupId){
|
||||
|
||||
|
||||
InnerMethodName.instance.set("getAdmins");
|
||||
|
||||
String login = AuthorizationProvider.instance.get().getClient().getId();
|
||||
|
||||
JackrabbitSession session = null;
|
||||
List<String> 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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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<String> 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);
|
||||
|
|
|
@ -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<FolderCreationParameters> builder = FolderCreationParameters.builder().name(name).description(description).hidden(hidden).on(id).with(ses).author(login);
|
||||
toReturn = itemHandler.create(builder.build());
|
||||
ItemsParameterBuilder<FolderCreationParameters> 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<URLCreationParameters> builder = URLCreationParameters.builder().name(name).description(description).url(value).on(id).with(ses).author(login);
|
||||
ItemsParameterBuilder<URLCreationParameters> 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<GCubeItemCreationParameters> builder = GCubeItemCreationParameters.builder().item(item).on(id).with(ses).author(login);
|
||||
ItemsParameterBuilder<GCubeItemCreationParameters> 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<FileCreationParameters> 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<ArchiveStructureCreationParameter> 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);
|
||||
|
|
|
@ -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<String> 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<Item> 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<Item> allNodes = Utils.getAllNodesForZip((FolderItem)item, ses, accountingHandler, excludes);
|
||||
final Deque<Item> 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));
|
||||
|
||||
|
|
|
@ -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<Node> sharedWithUserChecker = new Predicate<Node>() {
|
||||
|
||||
@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());
|
||||
|
|
|
@ -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<Item> 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<Item> 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>(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<? extends Item> 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<? extends Item> toReturn = null;
|
||||
try{
|
||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||
|
@ -397,7 +390,7 @@ public class WorkspaceManager {
|
|||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
Expression<Boolean> 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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Item> 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<Item> 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>(item);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("items/{id}")
|
||||
@AuthorizationControl(allowedRoles = {INFRASTRUCTURE_MANAGER_ROLE},exception=MyAuthException.class)
|
||||
public ItemWrapper<Item> 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>(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<Item> 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<Version> 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<ACL> 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<AccessType> 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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<FileCreationParameters> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Item> getChildren(Predicate<Node> checker, Node parent, List<String> excludes, boolean showHidden, Class<? extends Item> nodeTypeToInclude) throws RepositoryException, BackendGenericError {
|
||||
return Utils.getItemList(checker, parent, excludes, new Range(0, 100), showHidden, nodeTypeToInclude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getItem(Node node, List<String> excludes) throws RepositoryException, BackendGenericError {
|
||||
return node2Item.getItem(node, excludes);
|
||||
}
|
||||
|
||||
}
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<application mode='online'>
|
||||
<name>StorageHub</name>
|
||||
<group>DataAccess</group>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
<version>1.3.0-SNAPSHOT</version>
|
||||
<description>Storage Hub webapp</description>
|
||||
<local-persistence location='target' />
|
||||
</application>
|
Loading…
Reference in New Issue