git-svn-id: https://svn.d4science-ii.research-infrastructures.eu/gcube/branches/data-access/storagehub-webapp/1.0@174931 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
daeaaf9299
commit
250fce291f
14
pom.xml
14
pom.xml
|
@ -56,7 +56,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.aspectj</groupId>
|
<groupId>org.aspectj</groupId>
|
||||||
<artifactId>aspectjrt</artifactId>
|
<artifactId>aspectjrt</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -64,6 +63,12 @@
|
||||||
<artifactId>common-smartgears</artifactId>
|
<artifactId>common-smartgears</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.common</groupId>
|
||||||
|
<artifactId>authorization-control-library</artifactId>
|
||||||
|
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.common</groupId>
|
<groupId>org.gcube.common</groupId>
|
||||||
<artifactId>common-authorization</artifactId>
|
<artifactId>common-authorization</artifactId>
|
||||||
|
@ -84,6 +89,11 @@
|
||||||
<artifactId>common-scope</artifactId>
|
<artifactId>common-scope</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.gcube.core</groupId>
|
||||||
|
<artifactId>common-encryption</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.common</groupId>
|
<groupId>org.gcube.common</groupId>
|
||||||
<artifactId>storagehub-model</artifactId>
|
<artifactId>storagehub-model</artifactId>
|
||||||
|
@ -357,7 +367,7 @@
|
||||||
<aspectLibraries>
|
<aspectLibraries>
|
||||||
<aspectLibrary>
|
<aspectLibrary>
|
||||||
<groupId>org.gcube.common</groupId>
|
<groupId>org.gcube.common</groupId>
|
||||||
<artifactId>common-authorization</artifactId>
|
<artifactId>authorization-control-library</artifactId>
|
||||||
</aspectLibrary>
|
</aspectLibrary>
|
||||||
</aspectLibraries>
|
</aspectLibraries>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -34,7 +34,6 @@ public class AuthorizationChecker {
|
||||||
Item item = node2Item.getItem(node, Excludes.ALL);
|
Item item = node2Item.getItem(node, Excludes.ALL);
|
||||||
|
|
||||||
if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node");
|
if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+" to read node with id "+id+": it's not a valid StorageHub node");
|
||||||
|
|
||||||
if (item.isPublicItem()) return;
|
if (item.isPublicItem()) return;
|
||||||
|
|
||||||
if (item.isShared()) {
|
if (item.isShared()) {
|
||||||
|
@ -105,7 +104,7 @@ public class AuthorizationChecker {
|
||||||
|
|
||||||
|
|
||||||
public void checkAdministratorControl(Session session, SharedFolder item) throws UserNotAuthorizedException, BackendGenericError, RepositoryException {
|
public void checkAdministratorControl(Session session, SharedFolder item) throws UserNotAuthorizedException, BackendGenericError, RepositoryException {
|
||||||
//TODO: riguardare qeusto pezzo di codice
|
//TODO: riguardare questo pezzo di codice
|
||||||
String login = AuthorizationProvider.instance.get().getClient().getId();
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
||||||
|
|
||||||
if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+": it's not a valid StorageHub node");
|
if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+": it's not a valid StorageHub node");
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class StorageHub extends Application {
|
||||||
classes.add(ACLManager.class);
|
classes.add(ACLManager.class);
|
||||||
classes.add(ItemSharing.class);
|
classes.add(ItemSharing.class);
|
||||||
classes.add(UserManager.class);
|
classes.add(UserManager.class);
|
||||||
|
//classes.add(AuthorizationExceptionMapper.class);
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,14 +112,18 @@ public class Utils {
|
||||||
(node.getPrimaryNodeType().getName().equals(FOLDERS_TYPE) && Constants.FOLDERS_TO_EXLUDE.contains(node.getName())));
|
(node.getPrimaryNodeType().getName().equals(FOLDERS_TYPE) && Constants.FOLDERS_TO_EXLUDE.contains(node.getName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static org.gcube.common.storagehub.model.Path getHomePath(){
|
public static org.gcube.common.storagehub.model.Path getWorkspacePath(){
|
||||||
return Paths.getPath(String.format("/Home/%s/Workspace",AuthorizationProvider.instance.get().getClient().getId()));
|
return Paths.getPath(String.format("/Home/%s/Workspace",AuthorizationProvider.instance.get().getClient().getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static org.gcube.common.storagehub.model.Path getHomePath(String login){
|
public static org.gcube.common.storagehub.model.Path getWorkspacePath(String login){
|
||||||
return Paths.getPath(String.format("/Home/%s/Workspace",login));
|
return Paths.getPath(String.format("/Home/%s/Workspace",login));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static org.gcube.common.storagehub.model.Path getHome(String login){
|
||||||
|
return Paths.getPath(String.format("/Home/%s",login));
|
||||||
|
}
|
||||||
|
|
||||||
public static StorageClient getStorageClient(String login){
|
public static StorageClient getStorageClient(String login){
|
||||||
return new StorageClient(SERVICE_CLASS, SERVICE_NAME, login, AccessType.SHARED, MemoryType.PERSISTENT);
|
return new StorageClient(SERVICE_CLASS, SERVICE_NAME, login, AccessType.SHARED, MemoryType.PERSISTENT);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.gcube.data.access.storagehub.exception;
|
||||||
|
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
public class MyAuthException extends WebApplicationException {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public MyAuthException(Throwable cause) {
|
||||||
|
super(cause, Status.FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -49,7 +49,7 @@ public class TrashHandler {
|
||||||
public void removeNodes(Session ses, List<Item> itemsToDelete) throws RepositoryException{
|
public void removeNodes(Session ses, List<Item> itemsToDelete) throws RepositoryException{
|
||||||
log.debug("defnitively removing nodes with ids {}",itemsToDelete);
|
log.debug("defnitively removing nodes with ids {}",itemsToDelete);
|
||||||
final String login = AuthorizationProvider.instance.get().getClient().getId();
|
final String login = AuthorizationProvider.instance.get().getClient().getId();
|
||||||
final Node trashFolder = ses.getNode(Paths.append(Utils.getHomePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath());
|
final Node trashFolder = ses.getNode(Paths.append(Utils.getWorkspacePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath());
|
||||||
//String parentPath = itemToDelete.getParentPath();
|
//String parentPath = itemToDelete.getParentPath();
|
||||||
try {
|
try {
|
||||||
ses.getWorkspace().getLockManager().lock(trashFolder.getPath(), true, true, 0,login);
|
ses.getWorkspace().getLockManager().lock(trashFolder.getPath(), true, true, 0,login);
|
||||||
|
@ -95,7 +95,7 @@ public class TrashHandler {
|
||||||
|
|
||||||
public void moveToTrash(Session ses, Node nodeToDelete, Item item) throws RepositoryException, BackendGenericError{
|
public void moveToTrash(Session ses, Node nodeToDelete, Item item) throws RepositoryException, BackendGenericError{
|
||||||
log.debug("moving node {} to trash ",item.getId());
|
log.debug("moving node {} to trash ",item.getId());
|
||||||
final Node trashFolder = ses.getNode(Paths.append(Utils.getHomePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath());
|
final Node trashFolder = ses.getNode(Paths.append(Utils.getWorkspacePath(),Constants.TRASH_ROOT_FOLDER_NAME).toPath());
|
||||||
|
|
||||||
final String login = AuthorizationProvider.instance.get().getClient().getId();
|
final String login = AuthorizationProvider.instance.get().getClient().getId();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,251 @@
|
||||||
|
package org.gcube.data.access.storagehub.handlers;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.jcr.Node;
|
||||||
|
import javax.jcr.RepositoryException;
|
||||||
|
import javax.jcr.Session;
|
||||||
|
import javax.jcr.security.AccessControlEntry;
|
||||||
|
import javax.jcr.security.AccessControlManager;
|
||||||
|
|
||||||
|
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
|
||||||
|
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
|
||||||
|
import org.gcube.common.storagehub.model.Excludes;
|
||||||
|
import org.gcube.common.storagehub.model.NodeConstants;
|
||||||
|
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
|
||||||
|
import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters;
|
||||||
|
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
|
||||||
|
import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException;
|
||||||
|
import org.gcube.common.storagehub.model.items.FolderItem;
|
||||||
|
import org.gcube.common.storagehub.model.items.Item;
|
||||||
|
import org.gcube.common.storagehub.model.items.SharedFolder;
|
||||||
|
import org.gcube.common.storagehub.model.types.ItemAction;
|
||||||
|
import org.gcube.data.access.storagehub.AuthorizationChecker;
|
||||||
|
import org.gcube.data.access.storagehub.Utils;
|
||||||
|
import org.gcube.data.access.storagehub.accounting.AccountingHandler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class UnshareHandler {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(UnshareHandler.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AccountingHandler accountingHandler;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Node2ItemConverter node2Item;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AuthorizationChecker authChecker;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Item2NodeConverter item2Node;
|
||||||
|
|
||||||
|
public String unshare(Session ses, Set<String> users, Node sharedNode, String login) throws RepositoryException, StorageHubException{
|
||||||
|
Item item = node2Item.getItem(sharedNode, Excludes.ALL);
|
||||||
|
if (!(item instanceof FolderItem) || !((FolderItem) item).isShared() || ((SharedFolder) item).isVreFolder())
|
||||||
|
return null;
|
||||||
|
SharedFolder sharedItem =(SharedFolder) item;
|
||||||
|
|
||||||
|
Set<String> usersInSharedFolder = new HashSet<>(sharedItem.getUsers().getMap().keySet());
|
||||||
|
usersInSharedFolder.removeAll(users);
|
||||||
|
|
||||||
|
if (users==null || users.size()==0 || usersInSharedFolder.size()<=1)
|
||||||
|
return unshareAll(login, ses, sharedItem);
|
||||||
|
|
||||||
|
ses.getWorkspace().getLockManager().lock(sharedNode.getPath(), true, true, 0,login);
|
||||||
|
try {
|
||||||
|
if (users.size()==1 && users.contains(login))
|
||||||
|
return unshareCaller(login, ses, sharedItem);
|
||||||
|
else return unsharePartial(users, login, ses, sharedItem);
|
||||||
|
}finally {
|
||||||
|
ses.getWorkspace().getLockManager().unlock(sharedNode.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String unshareAll(String login, Session ses, SharedFolder item) throws StorageHubException, BackendGenericError, RepositoryException{
|
||||||
|
|
||||||
|
authChecker.checkAdministratorControl(ses, item);
|
||||||
|
if (!login.equals(item.getOwner()))
|
||||||
|
throw new UserNotAuthorizedException("user "+login+" not authorized to unshare all");
|
||||||
|
|
||||||
|
Node sharedItemNode = ses.getNodeByIdentifier(item.getId());
|
||||||
|
|
||||||
|
ses.getWorkspace().getLockManager().lock(sharedItemNode.getPath(), true, true, 0,login);
|
||||||
|
Node unsharedNode;
|
||||||
|
try {
|
||||||
|
log.debug("user list is empty, I'm going to remove also the shared dir");
|
||||||
|
//TODO: take the admin folder and remove his clone then move the shared folder from share to the user home and change the folder type
|
||||||
|
String adminDirPath = (String)item.getUsers().getMap().get(login);
|
||||||
|
String[] splitString = adminDirPath.split("/");
|
||||||
|
String parentDirectoryId = splitString[0];
|
||||||
|
String directoryName = splitString[1];
|
||||||
|
Node parentNode = ses.getNodeByIdentifier(parentDirectoryId);
|
||||||
|
log.debug("parent node path is {}/{}",parentNode.getPath(), directoryName);
|
||||||
|
|
||||||
|
Node adminNode = ses.getNode(String.format("%s/%s",parentNode.getPath(), directoryName));
|
||||||
|
adminNode.removeShare();
|
||||||
|
|
||||||
|
unsharedNode = createUnsharedFolder(ses, parentNode, directoryName, item.getDescription(), login);
|
||||||
|
|
||||||
|
List<Item> itemsToCopy = Utils.getItemList(sharedItemNode, Excludes.ALL, null, true, null);
|
||||||
|
|
||||||
|
for (Item itemCopy: itemsToCopy) {
|
||||||
|
Node itemToCopyNode = ses.getNodeByIdentifier(itemCopy.getId());
|
||||||
|
log.debug("copying {} to {}", itemToCopyNode.getPath(), unsharedNode.getPath());
|
||||||
|
ses.move(itemToCopyNode.getPath(), String.format("%s/%s",unsharedNode.getPath(), itemToCopyNode.getName()));
|
||||||
|
}
|
||||||
|
ses.save();
|
||||||
|
}finally {
|
||||||
|
ses.getWorkspace().getLockManager().unlock(sharedItemNode.getPath());
|
||||||
|
}
|
||||||
|
sharedItemNode.removeSharedSet();
|
||||||
|
ses.save();
|
||||||
|
log.debug("all the users have been removed, the folder is totally unshared");
|
||||||
|
|
||||||
|
return unsharedNode.getIdentifier();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String unshareCaller(String login, Session ses, SharedFolder item) throws StorageHubException, RepositoryException{
|
||||||
|
|
||||||
|
if (login.equals(item.getOwner()))
|
||||||
|
throw new InvalidCallParameters("the callor is the owner, the folder cannot be unshared");
|
||||||
|
|
||||||
|
if (item.getUsers().getMap().get(login)==null)
|
||||||
|
throw new InvalidCallParameters("the folder is not shared with user "+login);
|
||||||
|
|
||||||
|
Node sharedFolderNode =ses.getNodeByIdentifier(item.getId());
|
||||||
|
|
||||||
|
String parentId = removeSharingForUser(login, ses, item);
|
||||||
|
|
||||||
|
AccessControlManager acm = ses.getAccessControlManager();
|
||||||
|
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, sharedFolderNode.getPath());
|
||||||
|
|
||||||
|
AccessControlEntry entryToDelete= null;
|
||||||
|
for (AccessControlEntry ace :acls.getAccessControlEntries()) {
|
||||||
|
if (ace.getPrincipal().getName().equals(login)) {
|
||||||
|
entryToDelete = ace;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (entryToDelete!=null)
|
||||||
|
acls.removeAccessControlEntry(entryToDelete);
|
||||||
|
|
||||||
|
log.debug("removed Access control entry for user {}",login);
|
||||||
|
Node sharedItemNode = ses.getNodeByIdentifier(item.getId());
|
||||||
|
Node usersNode = sharedItemNode.getNode(NodeConstants.USERS_NAME);
|
||||||
|
usersNode.remove();
|
||||||
|
Node newUsersNode = sharedItemNode.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());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("error adding property to shared node users node under "+item.getId());
|
||||||
|
}});
|
||||||
|
|
||||||
|
acm.setPolicy(sharedFolderNode.getPath(), acls);
|
||||||
|
|
||||||
|
ses.save();
|
||||||
|
|
||||||
|
return parentId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String unsharePartial(Set<String> usersToUnshare, String login, Session ses, SharedFolder item) throws StorageHubException, RepositoryException {
|
||||||
|
authChecker.checkAdministratorControl(ses, (SharedFolder)item);
|
||||||
|
if (usersToUnshare.contains(item.getOwner()))
|
||||||
|
throw new UserNotAuthorizedException("user "+login+" not authorized to unshare owner");
|
||||||
|
|
||||||
|
Node sharedFolderNode =ses.getNodeByIdentifier(item.getId());
|
||||||
|
|
||||||
|
AccessControlManager acm = ses.getAccessControlManager();
|
||||||
|
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, sharedFolderNode.getPath());
|
||||||
|
|
||||||
|
for (String user : usersToUnshare) {
|
||||||
|
removeSharingForUser(user, ses, item);
|
||||||
|
|
||||||
|
AccessControlEntry entryToDelete= null;
|
||||||
|
for (AccessControlEntry ace :acls.getAccessControlEntries()) {
|
||||||
|
if (ace.getPrincipal().getName().equals(login)) {
|
||||||
|
entryToDelete = ace;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (entryToDelete!=null)
|
||||||
|
acls.removeAccessControlEntry(entryToDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("removed Access control entry for user {}",login);
|
||||||
|
Node sharedItemNode = ses.getNodeByIdentifier(item.getId());
|
||||||
|
Node usersNode = sharedItemNode.getNode(NodeConstants.USERS_NAME);
|
||||||
|
usersNode.remove();
|
||||||
|
Node newUsersNode = sharedItemNode.addNode(NodeConstants.USERS_NAME);
|
||||||
|
|
||||||
|
item.getUsers().getMap().entrySet().stream().filter(entry -> !usersToUnshare.contains(entry.getKey())).forEach(entry-> {try {
|
||||||
|
newUsersNode.setProperty(entry.getKey(), (String)entry.getValue());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("error adding property to shared node users node under "+item.getId());
|
||||||
|
}});
|
||||||
|
|
||||||
|
acm.setPolicy(sharedFolderNode.getPath(), acls);
|
||||||
|
|
||||||
|
ses.save();
|
||||||
|
|
||||||
|
return item.getId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String removeSharingForUser(String user, Session ses, SharedFolder item) throws RepositoryException {
|
||||||
|
String userDirPath = (String)item.getUsers().getMap().get(user);
|
||||||
|
if (userDirPath==null) return null;
|
||||||
|
String[] splitString = userDirPath.split("/");
|
||||||
|
String parentDirectoryId = splitString[0];
|
||||||
|
String directoryName = splitString[1];
|
||||||
|
Node parentNode = ses.getNodeByIdentifier(parentDirectoryId);
|
||||||
|
Node userNode = ses.getNode(String.format("%s/%s",parentNode.getPath(), directoryName));
|
||||||
|
userNode.removeShare();
|
||||||
|
accountingHandler.createUnshareFolder(directoryName, ses, parentNode, false);
|
||||||
|
log.debug("directory removed for user {}",user);
|
||||||
|
return parentDirectoryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Node createUnsharedFolder(Session ses, Node destinationNode, String name, String description, String login) {
|
||||||
|
FolderItem item = new FolderItem();
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
item.setName(name);
|
||||||
|
item.setTitle(name);
|
||||||
|
item.setDescription(description);
|
||||||
|
//item.setCreationTime(now);
|
||||||
|
item.setHidden(false);
|
||||||
|
item.setLastAction(ItemAction.CREATED);
|
||||||
|
item.setLastModificationTime(now);
|
||||||
|
item.setLastModifiedBy(login);
|
||||||
|
item.setOwner(login);
|
||||||
|
|
||||||
|
//to inherit hidden property
|
||||||
|
//item.setHidden(destinationItem.isHidden());
|
||||||
|
|
||||||
|
Node newNode = item2Node.getNode(ses, destinationNode, item);
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package org.gcube.data.access.storagehub.services;
|
package org.gcube.data.access.storagehub.services;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -15,11 +14,9 @@ import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.WebApplicationException;
|
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.apache.commons.compress.archivers.ArchiveException;
|
|
||||||
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
|
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
|
||||||
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
|
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
|
||||||
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
||||||
|
|
|
@ -0,0 +1,222 @@
|
||||||
|
package org.gcube.data.access.storagehub.services;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.FormParam;
|
||||||
|
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.core.Context;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.apache.jackrabbit.api.JackrabbitSession;
|
||||||
|
import org.apache.jackrabbit.api.security.user.Authorizable;
|
||||||
|
import org.apache.jackrabbit.api.security.user.Group;
|
||||||
|
import org.apache.jackrabbit.api.security.user.Query;
|
||||||
|
import org.apache.jackrabbit.api.security.user.QueryBuilder;
|
||||||
|
import org.apache.jackrabbit.api.security.user.User;
|
||||||
|
import org.gcube.common.authorization.control.annotations.AuthorizationControl;
|
||||||
|
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
||||||
|
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
|
||||||
|
import org.gcube.data.access.storagehub.exception.MyAuthException;
|
||||||
|
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@Path("groups")
|
||||||
|
public class GroupManager {
|
||||||
|
|
||||||
|
@Context ServletContext context;
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GroupManager.class);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RepositoryInitializer repository;
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
|
public List<String> getGroups(){
|
||||||
|
|
||||||
|
JackrabbitSession session = null;
|
||||||
|
List<String> groups= new ArrayList<>();
|
||||||
|
try {
|
||||||
|
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
|
||||||
|
Iterator<Authorizable> result = session.getUserManager().findAuthorizables(new Query() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> void build(QueryBuilder<T> builder) {
|
||||||
|
builder.setSelector(Group.class);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
while (result.hasNext()) {
|
||||||
|
Authorizable group = result.next();
|
||||||
|
log.info("group {} found",group.getPrincipal().getName());
|
||||||
|
groups.add(group.getPrincipal().getName());
|
||||||
|
}
|
||||||
|
}catch(Exception e) {
|
||||||
|
log.error("jcr error getting users", e);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
|
} finally {
|
||||||
|
if (session!=null)
|
||||||
|
session.logout();
|
||||||
|
}
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("")
|
||||||
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
|
public String createGroup(@FormParam("group") String group){
|
||||||
|
|
||||||
|
JackrabbitSession session = null;
|
||||||
|
String groupId = null;
|
||||||
|
try {
|
||||||
|
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
|
||||||
|
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
|
||||||
|
|
||||||
|
Group createdGroup = usrManager.createGroup(group);
|
||||||
|
groupId = createdGroup.getID();
|
||||||
|
session.save();
|
||||||
|
}catch(Exception e) {
|
||||||
|
log.error("jcr error creating group {}", group, e);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
|
} finally {
|
||||||
|
if (session!=null)
|
||||||
|
session.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{id}")
|
||||||
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
|
public String deleteGroup(@PathParam("id") String id){
|
||||||
|
|
||||||
|
JackrabbitSession session = null;
|
||||||
|
String userId = null;
|
||||||
|
try {
|
||||||
|
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
|
||||||
|
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
|
||||||
|
|
||||||
|
Authorizable authorizable = usrManager.getAuthorizable(id);
|
||||||
|
if (authorizable.isGroup())
|
||||||
|
authorizable.remove();
|
||||||
|
session.save();
|
||||||
|
}catch(Exception e) {
|
||||||
|
log.error("jcr error getting users", e);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
|
} finally {
|
||||||
|
if (session!=null)
|
||||||
|
session.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{id}")
|
||||||
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
|
public boolean addUserToGroup(@PathParam("id") String groupId, @FormParam("userId") String userId){
|
||||||
|
|
||||||
|
JackrabbitSession session = null;
|
||||||
|
boolean success = false;
|
||||||
|
try {
|
||||||
|
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
|
||||||
|
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
|
||||||
|
|
||||||
|
Group group = (Group)usrManager.getAuthorizable(groupId);
|
||||||
|
User user = (User)usrManager.getAuthorizable(userId);
|
||||||
|
|
||||||
|
success = group.addMember(user);
|
||||||
|
|
||||||
|
session.save();
|
||||||
|
}catch(Exception e) {
|
||||||
|
log.error("jcr error adding user {} to group {}", userId, groupId, e);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
|
} finally {
|
||||||
|
if (session!=null)
|
||||||
|
session.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{groupId}/users/{userId}")
|
||||||
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
|
public boolean removeUserFromGroup(@PathParam("groupId") String groupId, @PathParam("userId") String userId){
|
||||||
|
|
||||||
|
JackrabbitSession session = null;
|
||||||
|
boolean success = false;
|
||||||
|
try {
|
||||||
|
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
|
||||||
|
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
|
||||||
|
|
||||||
|
Group group = (Group)usrManager.getAuthorizable(groupId);
|
||||||
|
User user = (User)usrManager.getAuthorizable(userId);
|
||||||
|
|
||||||
|
success = group.removeMember(user);
|
||||||
|
|
||||||
|
session.save();
|
||||||
|
}catch(Exception e) {
|
||||||
|
log.error("jcr error adding user {} to group {}", userId, groupId, e);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
|
} finally {
|
||||||
|
if (session!=null)
|
||||||
|
session.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{groupId}/users")
|
||||||
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
|
public List<String> getUsersOfGroup(@PathParam("groupId") String groupId){
|
||||||
|
|
||||||
|
JackrabbitSession session = null;
|
||||||
|
List<String> users = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
|
||||||
|
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
|
||||||
|
|
||||||
|
Group group = (Group)usrManager.getAuthorizable(groupId);
|
||||||
|
|
||||||
|
Iterator<Authorizable> it = group.getMembers();
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Authorizable user = it.next();
|
||||||
|
users.add(user.getPrincipal().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}catch(Exception e) {
|
||||||
|
log.error("jcr error getting users of group {}", groupId, e);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
|
} finally {
|
||||||
|
if (session!=null)
|
||||||
|
session.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -47,6 +47,7 @@ import org.gcube.data.access.storagehub.accounting.AccountingHandler;
|
||||||
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
|
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
|
||||||
import org.gcube.data.access.storagehub.handlers.Item2NodeConverter;
|
import org.gcube.data.access.storagehub.handlers.Item2NodeConverter;
|
||||||
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter;
|
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter;
|
||||||
|
import org.gcube.data.access.storagehub.handlers.UnshareHandler;
|
||||||
import org.gcube.data.access.storagehub.handlers.VersionHandler;
|
import org.gcube.data.access.storagehub.handlers.VersionHandler;
|
||||||
import org.gcube.smartgears.utils.InnerMethodName;
|
import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
|
@ -75,7 +76,7 @@ public class ItemSharing {
|
||||||
AuthorizationChecker authChecker;
|
AuthorizationChecker authChecker;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
VersionHandler versionHandler;
|
UnshareHandler unshareHandler;
|
||||||
|
|
||||||
@Inject Node2ItemConverter node2Item;
|
@Inject Node2ItemConverter node2Item;
|
||||||
@Inject Item2NodeConverter item2Node;
|
@Inject Item2NodeConverter item2Node;
|
||||||
|
@ -185,7 +186,7 @@ public class ItemSharing {
|
||||||
|
|
||||||
private void addUserToSharing(Node sharedFolderNode, Session ses, String user, Privilege[] userPrivileges, JackrabbitAccessControlList acls) throws RepositoryException{
|
private void addUserToSharing(Node sharedFolderNode, Session ses, String user, Privilege[] userPrivileges, JackrabbitAccessControlList acls) throws RepositoryException{
|
||||||
ses.getWorkspace().clone(ses.getWorkspace().getName(), sharedFolderNode.getPath(), sharedFolderNode.getProperty(NodeProperty.TITLE.toString()).getString(), false);
|
ses.getWorkspace().clone(ses.getWorkspace().getName(), sharedFolderNode.getPath(), sharedFolderNode.getProperty(NodeProperty.TITLE.toString()).getString(), false);
|
||||||
String userRootWSId = ses.getNode(Utils.getHomePath(user).toPath()).getIdentifier();
|
String userRootWSId = ses.getNode(Utils.getWorkspacePath(user).toPath()).getIdentifier();
|
||||||
acls.addAccessControlEntry(AccessControlUtils.getPrincipal(ses, user), userPrivileges );
|
acls.addAccessControlEntry(AccessControlUtils.getPrincipal(ses, user), userPrivileges );
|
||||||
Node usersNode =null;
|
Node usersNode =null;
|
||||||
if (sharedFolderNode.hasNode(NodeConstants.USERS_NAME))
|
if (sharedFolderNode.hasNode(NodeConstants.USERS_NAME))
|
||||||
|
@ -208,25 +209,8 @@ public class ItemSharing {
|
||||||
try {
|
try {
|
||||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
Node sharedNode = ses.getNodeByIdentifier(id);
|
Node sharedNode = ses.getNodeByIdentifier(id);
|
||||||
Item item = node2Item.getItem(sharedNode, Excludes.ALL);
|
toReturn = unshareHandler.unshare(ses, users, sharedNode, login);
|
||||||
if (!(item instanceof FolderItem) || !((FolderItem) item).isShared() || ((SharedFolder) item).isVreFolder())
|
if(toReturn == null ) throw new InvalidItemException("item with id "+id+" cannot be unshared");
|
||||||
throw new InvalidItemException("item with id "+id+" cannot be unshared");
|
|
||||||
SharedFolder sharedItem =(SharedFolder) item;
|
|
||||||
|
|
||||||
Set<String> usersInSharedFolder = new HashSet<>(sharedItem.getUsers().getMap().keySet());
|
|
||||||
usersInSharedFolder.removeAll(users);
|
|
||||||
|
|
||||||
if (users==null || users.size()==0 || usersInSharedFolder.size()<=1)
|
|
||||||
return unshareAll(login, ses, sharedItem);
|
|
||||||
|
|
||||||
ses.getWorkspace().getLockManager().lock(sharedNode.getPath(), true, true, 0,login);
|
|
||||||
try {
|
|
||||||
if (users.size()==1 && users.contains(login))
|
|
||||||
toReturn = unshareCaller(login, ses, sharedItem);
|
|
||||||
else toReturn = unsharePartial(users, login, ses, sharedItem);
|
|
||||||
}finally {
|
|
||||||
ses.getWorkspace().getLockManager().unlock(sharedNode.getPath());
|
|
||||||
}
|
|
||||||
}catch(RepositoryException re){
|
}catch(RepositoryException re){
|
||||||
log.error("jcr unsharing", re);
|
log.error("jcr unsharing", re);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error extracting archive", re));
|
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error extracting archive", re));
|
||||||
|
@ -244,182 +228,5 @@ public class ItemSharing {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String unshareAll(String login, Session ses, SharedFolder item) throws StorageHubException, BackendGenericError, RepositoryException{
|
|
||||||
|
|
||||||
authChecker.checkAdministratorControl(ses, item);
|
|
||||||
if (!login.equals(item.getOwner()))
|
|
||||||
throw new UserNotAuthorizedException("user "+login+" not authorized to unshare all");
|
|
||||||
|
|
||||||
Node sharedItemNode = ses.getNodeByIdentifier(item.getId());
|
|
||||||
|
|
||||||
ses.getWorkspace().getLockManager().lock(sharedItemNode.getPath(), true, true, 0,login);
|
|
||||||
Node unsharedNode;
|
|
||||||
try {
|
|
||||||
log.debug("user list is empty, I'm going to remove also the shared dir");
|
|
||||||
//TODO: take the admin folder and remove his clone then move the shared folder from share to the user home and change the folder type
|
|
||||||
String adminDirPath = (String)item.getUsers().getMap().get(login);
|
|
||||||
String[] splitString = adminDirPath.split("/");
|
|
||||||
String parentDirectoryId = splitString[0];
|
|
||||||
String directoryName = splitString[1];
|
|
||||||
Node parentNode = ses.getNodeByIdentifier(parentDirectoryId);
|
|
||||||
log.debug("parent node path is {}/{}",parentNode.getPath(), directoryName);
|
|
||||||
|
|
||||||
Node adminNode = ses.getNode(String.format("%s/%s",parentNode.getPath(), directoryName));
|
|
||||||
adminNode.removeShare();
|
|
||||||
|
|
||||||
unsharedNode = createUnsharedFolder(ses, parentNode, directoryName, item.getDescription(), login);
|
|
||||||
|
|
||||||
List<Item> itemsToCopy = Utils.getItemList(sharedItemNode, Excludes.ALL, null, true, null);
|
|
||||||
|
|
||||||
for (Item itemCopy: itemsToCopy) {
|
|
||||||
Node itemToCopyNode = ses.getNodeByIdentifier(itemCopy.getId());
|
|
||||||
log.debug("copying {} to {}", itemToCopyNode.getPath(), unsharedNode.getPath());
|
|
||||||
ses.move(itemToCopyNode.getPath(), String.format("%s/%s",unsharedNode.getPath(), itemToCopyNode.getName()));
|
|
||||||
}
|
|
||||||
ses.save();
|
|
||||||
}finally {
|
|
||||||
ses.getWorkspace().getLockManager().unlock(sharedItemNode.getPath());
|
|
||||||
}
|
|
||||||
sharedItemNode.removeSharedSet();
|
|
||||||
ses.save();
|
|
||||||
log.debug("all the users have been removed, the folder is totally unshared");
|
|
||||||
|
|
||||||
return unsharedNode.getIdentifier();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String unshareCaller(String login, Session ses, SharedFolder item) throws StorageHubException, RepositoryException{
|
|
||||||
|
|
||||||
if (login.equals(item.getOwner()))
|
|
||||||
throw new InvalidCallParameters("the callor is the owner, the folder cannot be unshared");
|
|
||||||
|
|
||||||
if (item.getUsers().getMap().get(login)==null)
|
|
||||||
throw new InvalidCallParameters("the folder is not shared with user "+login);
|
|
||||||
|
|
||||||
Node sharedFolderNode =ses.getNodeByIdentifier(item.getId());
|
|
||||||
|
|
||||||
String parentId = removeSharingForUser(login, ses, item);
|
|
||||||
|
|
||||||
AccessControlManager acm = ses.getAccessControlManager();
|
|
||||||
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, sharedFolderNode.getPath());
|
|
||||||
|
|
||||||
AccessControlEntry entryToDelete= null;
|
|
||||||
for (AccessControlEntry ace :acls.getAccessControlEntries()) {
|
|
||||||
if (ace.getPrincipal().getName().equals(login)) {
|
|
||||||
entryToDelete = ace;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (entryToDelete!=null)
|
|
||||||
acls.removeAccessControlEntry(entryToDelete);
|
|
||||||
|
|
||||||
log.debug("removed Access control entry for user {}",login);
|
|
||||||
Node sharedItemNode = ses.getNodeByIdentifier(item.getId());
|
|
||||||
Node usersNode = sharedItemNode.getNode(NodeConstants.USERS_NAME);
|
|
||||||
usersNode.remove();
|
|
||||||
Node newUsersNode = sharedItemNode.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());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("error adding property to shared node users node under "+item.getId());
|
|
||||||
}});
|
|
||||||
|
|
||||||
acm.setPolicy(sharedFolderNode.getPath(), acls);
|
|
||||||
|
|
||||||
ses.save();
|
|
||||||
|
|
||||||
return parentId;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String unsharePartial(Set<String> usersToUnshare, String login, Session ses, SharedFolder item) throws StorageHubException, RepositoryException {
|
|
||||||
authChecker.checkAdministratorControl(ses, (SharedFolder)item);
|
|
||||||
if (usersToUnshare.contains(item.getOwner()))
|
|
||||||
throw new UserNotAuthorizedException("user "+login+" not authorized to unshare owner");
|
|
||||||
|
|
||||||
Node sharedFolderNode =ses.getNodeByIdentifier(item.getId());
|
|
||||||
|
|
||||||
AccessControlManager acm = ses.getAccessControlManager();
|
|
||||||
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, sharedFolderNode.getPath());
|
|
||||||
|
|
||||||
for (String user : usersToUnshare) {
|
|
||||||
removeSharingForUser(user, ses, item);
|
|
||||||
|
|
||||||
AccessControlEntry entryToDelete= null;
|
|
||||||
for (AccessControlEntry ace :acls.getAccessControlEntries()) {
|
|
||||||
if (ace.getPrincipal().getName().equals(login)) {
|
|
||||||
entryToDelete = ace;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (entryToDelete!=null)
|
|
||||||
acls.removeAccessControlEntry(entryToDelete);
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("removed Access control entry for user {}",login);
|
|
||||||
Node sharedItemNode = ses.getNodeByIdentifier(item.getId());
|
|
||||||
Node usersNode = sharedItemNode.getNode(NodeConstants.USERS_NAME);
|
|
||||||
usersNode.remove();
|
|
||||||
Node newUsersNode = sharedItemNode.addNode(NodeConstants.USERS_NAME);
|
|
||||||
|
|
||||||
item.getUsers().getMap().entrySet().stream().filter(entry -> !usersToUnshare.contains(entry.getKey())).forEach(entry-> {try {
|
|
||||||
newUsersNode.setProperty(entry.getKey(), (String)entry.getValue());
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("error adding property to shared node users node under "+item.getId());
|
|
||||||
}});
|
|
||||||
|
|
||||||
acm.setPolicy(sharedFolderNode.getPath(), acls);
|
|
||||||
|
|
||||||
ses.save();
|
|
||||||
|
|
||||||
return item.getId();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String removeSharingForUser(String user, Session ses, SharedFolder item) throws RepositoryException {
|
|
||||||
String userDirPath = (String)item.getUsers().getMap().get(user);
|
|
||||||
if (userDirPath==null) return null;
|
|
||||||
String[] splitString = userDirPath.split("/");
|
|
||||||
String parentDirectoryId = splitString[0];
|
|
||||||
String directoryName = splitString[1];
|
|
||||||
Node parentNode = ses.getNodeByIdentifier(parentDirectoryId);
|
|
||||||
Node userNode = ses.getNode(String.format("%s/%s",parentNode.getPath(), directoryName));
|
|
||||||
userNode.removeShare();
|
|
||||||
accountingHandler.createUnshareFolder(directoryName, ses, parentNode, false);
|
|
||||||
log.debug("directory removed for user {}",user);
|
|
||||||
return parentDirectoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Node createUnsharedFolder(Session ses, Node destinationNode, String name, String description, String login) {
|
|
||||||
FolderItem item = new FolderItem();
|
|
||||||
Calendar now = Calendar.getInstance();
|
|
||||||
item.setName(name);
|
|
||||||
item.setTitle(name);
|
|
||||||
item.setDescription(description);
|
|
||||||
//item.setCreationTime(now);
|
|
||||||
item.setHidden(false);
|
|
||||||
item.setLastAction(ItemAction.CREATED);
|
|
||||||
item.setLastModificationTime(now);
|
|
||||||
item.setLastModifiedBy(login);
|
|
||||||
item.setOwner(login);
|
|
||||||
|
|
||||||
//to inherit hidden property
|
|
||||||
//item.setHidden(destinationItem.isHidden());
|
|
||||||
|
|
||||||
Node newNode = item2Node.getNode(ses, destinationNode, item);
|
|
||||||
return newNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,13 @@ import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.StreamingOutput;
|
import javax.ws.rs.core.StreamingOutput;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
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.authorization.library.provider.AuthorizationProvider;
|
||||||
|
import org.gcube.common.encryption.StringEncrypter;
|
||||||
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
||||||
|
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.Excludes;
|
||||||
import org.gcube.common.storagehub.model.NodeConstants;
|
import org.gcube.common.storagehub.model.NodeConstants;
|
||||||
import org.gcube.common.storagehub.model.Paths;
|
import org.gcube.common.storagehub.model.Paths;
|
||||||
|
@ -46,6 +51,7 @@ import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
|
||||||
import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters;
|
import org.gcube.common.storagehub.model.exceptions.InvalidCallParameters;
|
||||||
import org.gcube.common.storagehub.model.exceptions.InvalidItemException;
|
import org.gcube.common.storagehub.model.exceptions.InvalidItemException;
|
||||||
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
|
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
|
||||||
|
import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException;
|
||||||
import org.gcube.common.storagehub.model.items.AbstractFileItem;
|
import org.gcube.common.storagehub.model.items.AbstractFileItem;
|
||||||
import org.gcube.common.storagehub.model.items.FolderItem;
|
import org.gcube.common.storagehub.model.items.FolderItem;
|
||||||
import org.gcube.common.storagehub.model.items.Item;
|
import org.gcube.common.storagehub.model.items.Item;
|
||||||
|
@ -62,6 +68,7 @@ import org.gcube.data.access.storagehub.Range;
|
||||||
import org.gcube.data.access.storagehub.SingleFileStreamingOutput;
|
import org.gcube.data.access.storagehub.SingleFileStreamingOutput;
|
||||||
import org.gcube.data.access.storagehub.Utils;
|
import org.gcube.data.access.storagehub.Utils;
|
||||||
import org.gcube.data.access.storagehub.accounting.AccountingHandler;
|
import org.gcube.data.access.storagehub.accounting.AccountingHandler;
|
||||||
|
import org.gcube.data.access.storagehub.exception.MyAuthException;
|
||||||
import org.gcube.data.access.storagehub.handlers.ClassHandler;
|
import org.gcube.data.access.storagehub.handlers.ClassHandler;
|
||||||
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
|
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
|
||||||
import org.gcube.data.access.storagehub.handlers.Item2NodeConverter;
|
import org.gcube.data.access.storagehub.handlers.Item2NodeConverter;
|
||||||
|
@ -71,6 +78,8 @@ import org.gcube.data.access.storagehub.handlers.VersionHandler;
|
||||||
import org.gcube.smartgears.utils.InnerMethodName;
|
import org.gcube.smartgears.utils.InnerMethodName;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import static org.gcube.common.storagehub.model.Constants.*;
|
||||||
|
|
||||||
|
|
||||||
@Path("items")
|
@Path("items")
|
||||||
public class ItemsManager {
|
public class ItemsManager {
|
||||||
|
@ -231,6 +240,73 @@ public class ItemsManager {
|
||||||
return new ItemList(toReturn);
|
return new ItemList(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("publiclink/{id}")
|
||||||
|
@AuthorizationControl(allowed={"URIResolver"}, exception=MyAuthException.class)
|
||||||
|
public Response resolvePublicLink() {
|
||||||
|
InnerMethodName.instance.set("resolvePubliclink");
|
||||||
|
Session ses = null;
|
||||||
|
try{
|
||||||
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
||||||
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
|
||||||
|
String complexId = id;
|
||||||
|
|
||||||
|
if (id.startsWith(enchriptedPrefix)) {
|
||||||
|
String currentScope = ScopeProvider.instance.get();
|
||||||
|
try {
|
||||||
|
ScopeBean bean= new ScopeBean(currentScope);
|
||||||
|
while (!bean.is(Type.INFRASTRUCTURE)) {
|
||||||
|
bean = bean.enclosingScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopeProvider.instance.set(bean.toString());
|
||||||
|
complexId = StringEncrypter.getEncrypter().encrypt(id.replace(enchriptedPrefix, ""));
|
||||||
|
}catch(Exception e){
|
||||||
|
throw new BackendGenericError("invalid public url",e);
|
||||||
|
}finally {
|
||||||
|
ScopeProvider.instance.set(currentScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
String itemId = complexId;
|
||||||
|
String versionName = null;
|
||||||
|
|
||||||
|
if (complexId.contains(versionPrefix)) {
|
||||||
|
String[] split = complexId.split(versionPrefix);
|
||||||
|
itemId = split[0];
|
||||||
|
versionName = split[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Node selectedNode = ses.getNodeByIdentifier(id);
|
||||||
|
|
||||||
|
Item item = node2Item.getItem(selectedNode, Arrays.asList(NodeConstants.ACCOUNTING_NAME, NodeConstants.METADATA_NAME));
|
||||||
|
|
||||||
|
if (!(item instanceof AbstractFileItem)) throw new InvalidCallParameters("the choosen item is not a File");
|
||||||
|
|
||||||
|
if (!(item.isPublicItem())) throw new UserNotAuthorizedException("the item requested is not public");
|
||||||
|
|
||||||
|
if (versionName!=null)
|
||||||
|
return downloadVersionInternal(ses, login, itemId, versionName, false);
|
||||||
|
else
|
||||||
|
return downloadFileInternal(ses, (AbstractFileItem) item, login, true);
|
||||||
|
|
||||||
|
|
||||||
|
}catch(RepositoryException re ){
|
||||||
|
log.error("jcr error getting public link", re);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
||||||
|
}catch(StorageHubException she ){
|
||||||
|
log.error("error getting public link", she);
|
||||||
|
GXOutboundErrorResponse.throwException(she);
|
||||||
|
}finally{
|
||||||
|
if (ses!=null)
|
||||||
|
ses.logout();
|
||||||
|
}
|
||||||
|
return Response.serverError().build();
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Path("{id}/publiclink")
|
@Path("{id}/publiclink")
|
||||||
|
@ -239,7 +315,6 @@ public class ItemsManager {
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
URL toReturn = null;
|
URL toReturn = null;
|
||||||
try{
|
try{
|
||||||
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
||||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
authChecker.checkReadAuthorizationControl(ses, id);
|
authChecker.checkReadAuthorizationControl(ses, id);
|
||||||
|
|
||||||
|
@ -249,7 +324,6 @@ public class ItemsManager {
|
||||||
|
|
||||||
if (!(item instanceof AbstractFileItem)) throw new InvalidCallParameters("the choosen item is not a File");
|
if (!(item instanceof AbstractFileItem)) throw new InvalidCallParameters("the choosen item is not a File");
|
||||||
|
|
||||||
|
|
||||||
if (version!=null) {
|
if (version!=null) {
|
||||||
boolean versionFound = false;
|
boolean versionFound = false;
|
||||||
VersionList versions = getVersions();
|
VersionList versions = getVersions();
|
||||||
|
@ -261,15 +335,37 @@ public class ItemsManager {
|
||||||
if (!versionFound) throw new InvalidCallParameters("the selected file has no version "+version);
|
if (!versionFound) throw new InvalidCallParameters("the selected file has no version "+version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NOT SETTING THE PUBLIC ATTRIBUTE FOR SOME STRANGE REASON
|
||||||
ses.getWorkspace().getLockManager().lock(selectedNode.getPath(), false, true, 0,login);
|
ses.getWorkspace().getLockManager().lock(selectedNode.getPath(), false, true, 0,login);
|
||||||
try {
|
try {
|
||||||
selectedNode.setProperty(NodeProperty.IS_PUBLIC.toString(), true);
|
selectedNode.setProperty(NodeProperty.IS_PUBLIC.toString(), true);
|
||||||
ses.save();
|
ses.save();
|
||||||
}finally {
|
}finally {
|
||||||
ses.getWorkspace().getLockManager().unlock(selectedNode.getPath());
|
ses.getWorkspace().getLockManager().unlock(selectedNode.getPath());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
String url = null;
|
||||||
|
String currentScope = ScopeProvider.instance.get();
|
||||||
|
try {
|
||||||
|
ScopeBean bean= new ScopeBean(currentScope);
|
||||||
|
while (!bean.is(Type.INFRASTRUCTURE)) {
|
||||||
|
bean = bean.enclosingScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = createPublicLink(version, id);
|
ScopeProvider.instance.set(bean.toString());
|
||||||
|
|
||||||
|
String toEnchript;
|
||||||
|
if(version!=null) toEnchript = String.format("%s%s%s",id, versionPrefix, version);
|
||||||
|
else toEnchript = id;
|
||||||
|
|
||||||
|
String enchriptedQueryString = StringEncrypter.getEncrypter().encrypt(toEnchript);
|
||||||
|
|
||||||
|
url = createPublicLink(enchriptedQueryString);
|
||||||
|
}catch(Exception e){
|
||||||
|
throw new BackendGenericError(e);
|
||||||
|
}finally {
|
||||||
|
ScopeProvider.instance.set(currentScope);
|
||||||
|
}
|
||||||
|
|
||||||
toReturn = new URL(url);
|
toReturn = new URL(url);
|
||||||
|
|
||||||
|
@ -288,11 +384,9 @@ public class ItemsManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String createPublicLink(String version, String id) {
|
private String createPublicLink(String enchriptedString) {
|
||||||
String basepath = context.getInitParameter("resolver-basepath");
|
String basepath = context.getInitParameter("resolver-basepath");
|
||||||
String filePublicUrl = String.format("%s/%s",basepath, id);
|
String filePublicUrl = String.format("%s/%s%s",basepath, enchriptedPrefix, id);
|
||||||
if (version!=null)
|
|
||||||
filePublicUrl = String.format("%s/%s", filePublicUrl, version);
|
|
||||||
return filePublicUrl;
|
return filePublicUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +471,6 @@ public class ItemsManager {
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/versions/{version}/download")
|
@Path("{id}/versions/{version}/download")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
|
||||||
public Response downloadVersion(@PathParam("version") String versionName){
|
public Response downloadVersion(@PathParam("version") String versionName){
|
||||||
InnerMethodName.instance.set("downloadSpecificVersion");
|
InnerMethodName.instance.set("downloadSpecificVersion");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
|
@ -385,6 +478,23 @@ public class ItemsManager {
|
||||||
String login = AuthorizationProvider.instance.get().getClient().getId();
|
String login = AuthorizationProvider.instance.get().getClient().getId();
|
||||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
authChecker.checkReadAuthorizationControl(ses, id);
|
authChecker.checkReadAuthorizationControl(ses, id);
|
||||||
|
|
||||||
|
return downloadVersionInternal(ses, login, id, versionName, true);
|
||||||
|
|
||||||
|
}catch(RepositoryException re ){
|
||||||
|
log.error("jcr error downloading version", re);
|
||||||
|
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
||||||
|
}catch(StorageHubException she ){
|
||||||
|
log.error("error downloading version", she);
|
||||||
|
GXOutboundErrorResponse.throwException(she);
|
||||||
|
}finally{
|
||||||
|
if (ses!=null)
|
||||||
|
ses.logout();
|
||||||
|
}
|
||||||
|
return Response.serverError().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response downloadVersionInternal(Session ses, String login, String id, String versionName, boolean withAccounting) throws RepositoryException, StorageHubException{
|
||||||
Node node = ses.getNodeByIdentifier(id);
|
Node node = ses.getNodeByIdentifier(id);
|
||||||
Item currentItem = node2Item.getItem(node, Excludes.ALL);
|
Item currentItem = node2Item.getItem(node, Excludes.ALL);
|
||||||
if (!(currentItem instanceof AbstractFileItem))
|
if (!(currentItem instanceof AbstractFileItem))
|
||||||
|
@ -406,7 +516,7 @@ public class ItemsManager {
|
||||||
|
|
||||||
String fileName = String.format("%s_v%s.%s", oldfilename, version.getName(), ext);
|
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, true);
|
||||||
|
|
||||||
StreamingOutput so = new SingleFileStreamingOutput(streamToWrite);
|
StreamingOutput so = new SingleFileStreamingOutput(streamToWrite);
|
||||||
|
@ -419,19 +529,7 @@ public class ItemsManager {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
throw new InvalidItemException("the version is not valid");
|
||||||
|
|
||||||
}catch(RepositoryException re ){
|
|
||||||
log.error("jcr error downloading version", re);
|
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
|
|
||||||
}catch(StorageHubException she ){
|
|
||||||
log.error("error downloading version", she);
|
|
||||||
GXOutboundErrorResponse.throwException(she);
|
|
||||||
}finally{
|
|
||||||
if (ses!=null)
|
|
||||||
ses.logout();
|
|
||||||
}
|
|
||||||
return Response.serverError().build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@ -439,7 +537,7 @@ public class ItemsManager {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public ItemList getAnchestors(@QueryParam("exclude") List<String> excludes){
|
public ItemList getAnchestors(@QueryParam("exclude") List<String> excludes){
|
||||||
InnerMethodName.instance.set("getAnchestors");
|
InnerMethodName.instance.set("getAnchestors");
|
||||||
org.gcube.common.storagehub.model.Path absolutePath = Utils.getHomePath();
|
org.gcube.common.storagehub.model.Path absolutePath = Utils.getWorkspacePath();
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
List<Item> toReturn = new LinkedList<>();
|
List<Item> toReturn = new LinkedList<>();
|
||||||
try{
|
try{
|
||||||
|
@ -498,21 +596,7 @@ public class ItemsManager {
|
||||||
authChecker.checkReadAuthorizationControl(ses, id);
|
authChecker.checkReadAuthorizationControl(ses, id);
|
||||||
final Item item = node2Item.getItem(node, null);
|
final Item item = node2Item.getItem(node, null);
|
||||||
if (item instanceof AbstractFileItem){
|
if (item instanceof AbstractFileItem){
|
||||||
AbstractFileItem fileItem =(AbstractFileItem) item;
|
return downloadFileInternal(ses, (AbstractFileItem) item, login, true);
|
||||||
|
|
||||||
final InputStream streamToWrite = Utils.getStorageClient(login).getClient().get().RFileAsInputStream(fileItem.getContent().getStorageId());
|
|
||||||
|
|
||||||
accountingHandler.createReadObj(fileItem.getTitle(), ses, node, true);
|
|
||||||
|
|
||||||
StreamingOutput so = new SingleFileStreamingOutput(streamToWrite);
|
|
||||||
|
|
||||||
response = Response
|
|
||||||
.ok(so)
|
|
||||||
.header("content-disposition","attachment; filename = "+fileItem.getName())
|
|
||||||
.header("Content-Length", fileItem.getContent().getSize())
|
|
||||||
.header("Content-Type", fileItem.getContent().getMimeType())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
} else if (item instanceof FolderItem){
|
} else if (item instanceof FolderItem){
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -560,6 +644,24 @@ public class ItemsManager {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Response downloadFileInternal(Session ses, AbstractFileItem fileItem, String login, boolean withAccounting) throws RepositoryException {
|
||||||
|
|
||||||
|
final InputStream streamToWrite = Utils.getStorageClient(login).getClient().get().RFileAsInputStream(fileItem.getContent().getStorageId());
|
||||||
|
|
||||||
|
if (withAccounting)
|
||||||
|
accountingHandler.createReadObj(fileItem.getTitle(), ses, ses.getNodeByIdentifier(fileItem.getId()), true);
|
||||||
|
|
||||||
|
StreamingOutput so = new SingleFileStreamingOutput(streamToWrite);
|
||||||
|
|
||||||
|
return Response
|
||||||
|
.ok(so)
|
||||||
|
.header("content-disposition","attachment; filename = "+fileItem.getName())
|
||||||
|
.header("Content-Length", fileItem.getContent().getSize())
|
||||||
|
.header("Content-Type", fileItem.getContent().getMimeType())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("{id}/move")
|
@Path("{id}/move")
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package org.gcube.data.access.storagehub.services;
|
package org.gcube.data.access.storagehub.services;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.jcr.Node;
|
import javax.jcr.Node;
|
||||||
import javax.jcr.Session;
|
import javax.jcr.NodeIterator;
|
||||||
|
import javax.jcr.query.QueryResult;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
|
@ -23,13 +25,16 @@ import org.apache.jackrabbit.api.security.user.Authorizable;
|
||||||
import org.apache.jackrabbit.api.security.user.Query;
|
import org.apache.jackrabbit.api.security.user.Query;
|
||||||
import org.apache.jackrabbit.api.security.user.QueryBuilder;
|
import org.apache.jackrabbit.api.security.user.QueryBuilder;
|
||||||
import org.apache.jackrabbit.api.security.user.User;
|
import org.apache.jackrabbit.api.security.user.User;
|
||||||
import org.gcube.common.authorization.library.annotations.AuthorizationControl;
|
import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
|
||||||
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
|
import org.gcube.common.authorization.control.annotations.AuthorizationControl;
|
||||||
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
|
||||||
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
|
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
|
||||||
|
import org.gcube.common.storagehub.model.types.NodeProperty;
|
||||||
import org.gcube.data.access.storagehub.Constants;
|
import org.gcube.data.access.storagehub.Constants;
|
||||||
import org.gcube.data.access.storagehub.Utils;
|
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.CredentialHandler;
|
||||||
|
import org.gcube.data.access.storagehub.handlers.UnshareHandler;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -43,10 +48,13 @@ public class UserManager {
|
||||||
@Inject
|
@Inject
|
||||||
RepositoryInitializer repository;
|
RepositoryInitializer repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
UnshareHandler unshareHandler;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("")
|
@Path("")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@AuthorizationControl(allowed={"lucio.lelii"})
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
public List<String> getUsers(){
|
public List<String> getUsers(){
|
||||||
|
|
||||||
JackrabbitSession session = null;
|
JackrabbitSession session = null;
|
||||||
|
@ -64,7 +72,7 @@ public class UserManager {
|
||||||
|
|
||||||
while (result.hasNext()) {
|
while (result.hasNext()) {
|
||||||
Authorizable user = result.next();
|
Authorizable user = result.next();
|
||||||
log.info("user {} found",user.getPrincipal().getName());
|
log.debug("user {} found",user.getPrincipal().getName());
|
||||||
users.add(user.getPrincipal().getName());
|
users.add(user.getPrincipal().getName());
|
||||||
}
|
}
|
||||||
}catch(Exception e) {
|
}catch(Exception e) {
|
||||||
|
@ -79,7 +87,7 @@ public class UserManager {
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("")
|
@Path("")
|
||||||
@AuthorizationControl(allowed={"lucio.lelii"})
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
public String createUser(@FormParam("user") String user, @FormParam("password") String password){
|
public String createUser(@FormParam("user") String user, @FormParam("password") String password){
|
||||||
|
|
||||||
JackrabbitSession session = null;
|
JackrabbitSession session = null;
|
||||||
|
@ -95,13 +103,16 @@ public class UserManager {
|
||||||
Node homeNode = session.getNode("/Home");
|
Node homeNode = session.getNode("/Home");
|
||||||
Node userHome = homeNode.addNode(user, "nthl:home");
|
Node userHome = homeNode.addNode(user, "nthl:home");
|
||||||
|
|
||||||
|
//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, userHome, Constants.WORKSPACE_ROOT_FOLDER_NAME, "workspace of "+user, false, user, null);
|
||||||
Node trashFolder = Utils.createFolderInternally(session, workspaceFolder, Constants.TRASH_ROOT_FOLDER_NAME, "trash of "+user, false, user, null);
|
//creating thrash folder
|
||||||
Node specialFolder = Utils.createFolderInternally(session, workspaceFolder, Constants.VRE_FOLDER_PARENT_NAME, "special folder container of "+user, false, user, null);
|
Utils.createFolderInternally(session, workspaceFolder, Constants.TRASH_ROOT_FOLDER_NAME, "trash of "+user, false, user, null);
|
||||||
|
//creating Vre container folder
|
||||||
|
Utils.createFolderInternally(session, workspaceFolder, Constants.VRE_FOLDER_PARENT_NAME, "special folder container of "+user, false, user, null);
|
||||||
|
|
||||||
session.save();
|
session.save();
|
||||||
}catch(Exception e) {
|
}catch(Exception e) {
|
||||||
log.error("jcr error getting users", e);
|
log.error("jcr error creating user {}", user, e);
|
||||||
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
|
||||||
} finally {
|
} finally {
|
||||||
if (session!=null)
|
if (session!=null)
|
||||||
|
@ -113,7 +124,7 @@ public class UserManager {
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@AuthorizationControl(allowed={"lucio.lelii"})
|
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
|
||||||
public String deleteUser(@PathParam("id") String id){
|
public String deleteUser(@PathParam("id") String id){
|
||||||
|
|
||||||
JackrabbitSession session = null;
|
JackrabbitSession session = null;
|
||||||
|
@ -123,9 +134,30 @@ public class UserManager {
|
||||||
|
|
||||||
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
|
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
|
||||||
|
|
||||||
Authorizable authorizable = usrManager.getAuthorizable(id);
|
org.gcube.common.storagehub.model.Path path = Utils.getWorkspacePath(id);
|
||||||
if (!authorizable.isGroup())
|
|
||||||
|
|
||||||
|
String sql2Query = String.format("SELECT * FROM [nthl:workspaceSharedItem] AS node WHERE ISDESCENDANTNODE('%s')", path.toPath());
|
||||||
|
|
||||||
|
log.info("query sent is {}",sql2Query);
|
||||||
|
|
||||||
|
|
||||||
|
javax.jcr.query.Query jcrQuery = session.getWorkspace().getQueryManager().createQuery(sql2Query, Constants.QUERY_LANGUAGE);
|
||||||
|
|
||||||
|
QueryResult result = jcrQuery.execute();
|
||||||
|
NodeIterator nodeIt = result.getNodes();
|
||||||
|
while (nodeIt.hasNext()) {
|
||||||
|
Node rNode = nodeIt.nextNode();
|
||||||
|
String title = rNode.hasProperty(NodeProperty.TITLE.toString()) ? rNode.getProperty(NodeProperty.TITLE.toString()).getString():"unknown";
|
||||||
|
log.debug("removing sharing for folder name {} with title {} and path {} ",rNode.getName(), title, rNode.getPath());
|
||||||
|
unshareHandler.unshare(session, Collections.singleton(id), rNode, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Authorizable authorizable = usrManager.getAuthorizable(new PrincipalImpl(id));
|
||||||
|
if (!authorizable.isGroup()) {
|
||||||
|
log.info("removing user {}", id);
|
||||||
authorizable.remove();
|
authorizable.remove();
|
||||||
|
}
|
||||||
session.save();
|
session.save();
|
||||||
}catch(Exception e) {
|
}catch(Exception e) {
|
||||||
log.error("jcr error getting users", e);
|
log.error("jcr error getting users", e);
|
||||||
|
|
|
@ -98,8 +98,8 @@ public class WorkspaceManager {
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
org.gcube.common.storagehub.model.Path absolutePath;
|
org.gcube.common.storagehub.model.Path absolutePath;
|
||||||
if (relPath==null)
|
if (relPath==null)
|
||||||
absolutePath = Utils.getHomePath();
|
absolutePath = Utils.getWorkspacePath();
|
||||||
else absolutePath = Paths.append(Utils.getHomePath(), relPath);
|
else absolutePath = Paths.append(Utils.getWorkspacePath(), relPath);
|
||||||
|
|
||||||
Item toReturn = null;
|
Item toReturn = null;
|
||||||
try{
|
try{
|
||||||
|
@ -124,7 +124,7 @@ public class WorkspaceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized VRE getVreFolderItem(Session ses) throws RepositoryException, BackendGenericError{
|
private synchronized VRE getVreFolderItem(Session ses) throws RepositoryException, BackendGenericError{
|
||||||
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
||||||
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
|
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
|
||||||
if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE");
|
if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE");
|
||||||
String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-");
|
String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-");
|
||||||
|
@ -208,7 +208,7 @@ public class WorkspaceManager {
|
||||||
InnerMethodName.instance.set("getTrashRootFolder");
|
InnerMethodName.instance.set("getTrashRootFolder");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
|
|
||||||
org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getHomePath(), Constants.TRASH_ROOT_FOLDER_NAME);
|
org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getWorkspacePath(), Constants.TRASH_ROOT_FOLDER_NAME);
|
||||||
Item item = null;
|
Item item = null;
|
||||||
try{
|
try{
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
@ -237,7 +237,7 @@ public class WorkspaceManager {
|
||||||
public String emptyTrash(){
|
public String emptyTrash(){
|
||||||
InnerMethodName.instance.set("emptyTrash");
|
InnerMethodName.instance.set("emptyTrash");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getHomePath(), Constants.TRASH_ROOT_FOLDER_NAME);
|
org.gcube.common.storagehub.model.Path trashPath = Paths.append(Utils.getWorkspacePath(), Constants.TRASH_ROOT_FOLDER_NAME);
|
||||||
String toReturn = null;
|
String toReturn = null;
|
||||||
try{
|
try{
|
||||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
@ -307,7 +307,7 @@ public class WorkspaceManager {
|
||||||
InnerMethodName.instance.set("getVreFolders");
|
InnerMethodName.instance.set("getVreFolders");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
|
|
||||||
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
||||||
List<? extends Item> toReturn = null;
|
List<? extends Item> toReturn = null;
|
||||||
try{
|
try{
|
||||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
@ -332,7 +332,7 @@ public class WorkspaceManager {
|
||||||
public ItemList getVreFoldersPaged(@QueryParam("start") Integer start, @QueryParam("limit") Integer limit){
|
public ItemList getVreFoldersPaged(@QueryParam("start") Integer start, @QueryParam("limit") Integer limit){
|
||||||
InnerMethodName.instance.set("getVreFoldersPaged");
|
InnerMethodName.instance.set("getVreFoldersPaged");
|
||||||
Session ses = null;
|
Session ses = null;
|
||||||
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getHomePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME);
|
||||||
List<? extends Item> toReturn = null;
|
List<? extends Item> toReturn = null;
|
||||||
try{
|
try{
|
||||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
|
@ -365,7 +365,7 @@ public class WorkspaceManager {
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
Expression<Boolean> expression = mapper.readValue(jsonExpr, Expression.class);
|
Expression<Boolean> expression = mapper.readValue(jsonExpr, Expression.class);
|
||||||
String stringExpression = evaluator.evaluate(new And(new ISDescendant(Utils.getHomePath()), expression));
|
String stringExpression = evaluator.evaluate(new And(new ISDescendant(Utils.getWorkspacePath()), expression));
|
||||||
|
|
||||||
String orderBy = "";
|
String orderBy = "";
|
||||||
if (orderField!=null && orderField.size()>0)
|
if (orderField!=null && orderField.size()>0)
|
||||||
|
@ -376,7 +376,7 @@ public class WorkspaceManager {
|
||||||
log.info("query sent is {}",sql2Query);
|
log.info("query sent is {}",sql2Query);
|
||||||
|
|
||||||
|
|
||||||
String login = AuthorizationProvider.instance.get().getClient().getId();
|
|
||||||
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
|
||||||
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(sql2Query, Constants.QUERY_LANGUAGE);
|
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(sql2Query, Constants.QUERY_LANGUAGE);
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,12 @@
|
||||||
<group>DataAccess</group>
|
<group>DataAccess</group>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
<description>Storage Hub webapp</description>
|
<description>Storage Hub webapp</description>
|
||||||
|
|
||||||
|
<!-- <proxy protocol="https">
|
||||||
|
<hostname>workspace-repository.dev.d4science.org</hostname>
|
||||||
|
<port>443</port>
|
||||||
|
</proxy> -->
|
||||||
|
|
||||||
|
|
||||||
<local-persistence location='target' />
|
<local-persistence location='target' />
|
||||||
</application>
|
</application>
|
Loading…
Reference in New Issue