This commit is contained in:
Lucio Lelii 2018-12-17 13:55:43 +00:00
parent daeaaf9299
commit 250fce291f
14 changed files with 779 additions and 328 deletions

24
pom.xml
View File

@ -52,18 +52,23 @@
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<scope>provided</scope>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-smartgears</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-control-library</artifactId>
<version>[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)</version>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>common-authorization</artifactId>
@ -84,6 +89,11 @@
<artifactId>common-scope</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-encryption</artifactId>
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>storagehub-model</artifactId>
@ -331,7 +341,7 @@
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<versionRange>[1.0,)</versionRange>
<goals>
<goal>test-compile</goal>
@ -357,7 +367,7 @@
<aspectLibraries>
<aspectLibrary>
<groupId>org.gcube.common</groupId>
<artifactId>common-authorization</artifactId>
<artifactId>authorization-control-library</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>

View File

@ -34,7 +34,6 @@ public class AuthorizationChecker {
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.isPublicItem()) return;
if (item.isShared()) {
@ -105,7 +104,7 @@ public class AuthorizationChecker {
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();
if (item==null) throw new UserNotAuthorizedException("Insufficent Provileges for user "+login+": it's not a valid StorageHub node");

View File

@ -28,6 +28,7 @@ public class StorageHub extends Application {
classes.add(ACLManager.class);
classes.add(ItemSharing.class);
classes.add(UserManager.class);
//classes.add(AuthorizationExceptionMapper.class);
return classes;
}

View File

@ -112,14 +112,18 @@ public class Utils {
(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()));
}
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));
}
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){
return new StorageClient(SERVICE_CLASS, SERVICE_NAME, login, AccessType.SHARED, MemoryType.PERSISTENT);

View File

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

View File

@ -49,7 +49,7 @@ public class TrashHandler {
public void removeNodes(Session ses, List<Item> itemsToDelete) throws RepositoryException{
log.debug("defnitively removing nodes with ids {}",itemsToDelete);
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();
try {
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{
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();

View File

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

View File

@ -1,6 +1,5 @@
package org.gcube.data.access.storagehub.services;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -15,11 +14,9 @@ import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;

View File

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

View File

@ -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.Item2NodeConverter;
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.smartgears.utils.InnerMethodName;
import org.glassfish.jersey.media.multipart.FormDataParam;
@ -75,7 +76,7 @@ public class ItemSharing {
AuthorizationChecker authChecker;
@Inject
VersionHandler versionHandler;
UnshareHandler unshareHandler;
@Inject Node2ItemConverter node2Item;
@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{
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 );
Node usersNode =null;
if (sharedFolderNode.hasNode(NodeConstants.USERS_NAME))
@ -208,25 +209,8 @@ public class ItemSharing {
try {
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
Node sharedNode = ses.getNodeByIdentifier(id);
Item item = node2Item.getItem(sharedNode, Excludes.ALL);
if (!(item instanceof FolderItem) || !((FolderItem) item).isShared() || ((SharedFolder) item).isVreFolder())
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());
}
toReturn = unshareHandler.unshare(ses, users, sharedNode, login);
if(toReturn == null ) throw new InvalidItemException("item with id "+id+" cannot be unshared");
}catch(RepositoryException re){
log.error("jcr unsharing", 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;
}
}

View File

@ -37,8 +37,13 @@ import javax.ws.rs.core.Response;
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.StringEncrypter;
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.NodeConstants;
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.InvalidItemException;
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.FolderItem;
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.Utils;
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.CredentialHandler;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.gcube.common.storagehub.model.Constants.*;
@Path("items")
public class ItemsManager {
@ -231,6 +240,73 @@ public class ItemsManager {
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
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}/publiclink")
@ -239,17 +315,15 @@ public class ItemsManager {
Session ses = null;
URL toReturn = null;
try{
String login = AuthorizationProvider.instance.get().getClient().getId();
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
authChecker.checkReadAuthorizationControl(ses, id);
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 (version!=null) {
boolean versionFound = false;
VersionList versions = getVersions();
@ -260,16 +334,38 @@ public class ItemsManager {
}
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);
try {
selectedNode.setProperty(NodeProperty.IS_PUBLIC.toString(), true);
ses.save();
}finally {
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();
}
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);
}
String url = createPublicLink(version, id);
toReturn = new URL(url);
@ -287,12 +383,10 @@ public class ItemsManager {
return toReturn;
}
private String createPublicLink(String version, String id) {
private String createPublicLink(String enchriptedString) {
String basepath = context.getInitParameter("resolver-basepath");
String filePublicUrl = String.format("%s/%s",basepath, id);
if (version!=null)
filePublicUrl = String.format("%s/%s", filePublicUrl, version);
String filePublicUrl = String.format("%s/%s%s",basepath, enchriptedPrefix, id);
return filePublicUrl;
}
@ -308,12 +402,12 @@ public class ItemsManager {
authChecker.checkReadAuthorizationControl(ses, id);
Node currentNode =ses.getNodeByIdentifier(id);
log.trace("current node is {}",currentNode.getPath());
Node sharedParentNode = getSharedParentNode(currentNode);
if (sharedParentNode==null)
throw new InvalidCallParameters("item is not shared");
sharedParent = node2Item.getItem(sharedParentNode, excludes);
}catch(RepositoryException re ){
@ -338,7 +432,7 @@ public class ItemsManager {
currentNode = currentNode.getParent();
return currentNode;
}
@GET
@Path("{id}/versions")
@Produces(MediaType.APPLICATION_JSON)
@ -349,15 +443,15 @@ public class ItemsManager {
try{
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
authChecker.checkReadAuthorizationControl(ses, id);
Node node = ses.getNodeByIdentifier(id);
Item currentItem = node2Item.getItem(node, Excludes.GET_ONLY_CONTENT);
if (!(currentItem instanceof AbstractFileItem))
throw new InvalidItemException("this item is not versioned");
List<Version> jcrVersions = versionHandler.getContentVersionHistory(node, ses);
for (Version version: jcrVersions) {
boolean currentVersion = ((AbstractFileItem)currentItem).getContent().getStorageId().equals(version.getFrozenNode().getProperty(NodeProperty.STORAGE_ID.toString()).getString());
versions.add(new org.gcube.common.storagehub.model.service.Version(version.getIdentifier(), version.getName(), version.getCreated(), currentVersion));
@ -377,7 +471,6 @@ public class ItemsManager {
@GET
@Path("{id}/versions/{version}/download")
@Produces(MediaType.APPLICATION_JSON)
public Response downloadVersion(@PathParam("version") String versionName){
InnerMethodName.instance.set("downloadSpecificVersion");
Session ses = null;
@ -385,42 +478,9 @@ public class ItemsManager {
String login = AuthorizationProvider.instance.get().getClient().getId();
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
authChecker.checkReadAuthorizationControl(ses, id);
Node node = ses.getNodeByIdentifier(id);
Item currentItem = node2Item.getItem(node, Excludes.ALL);
if (!(currentItem instanceof AbstractFileItem))
throw new InvalidItemException("this item is not a file");
List<Version> jcrVersions = versionHandler.getContentVersionHistory(ses.getNodeByIdentifier(id), ses);
for (Version version: jcrVersions) {
log.debug("retrieved version id {}, name {}", version.getIdentifier(), version.getName());
if (version.getName().equals(versionName)) {
long size = version.getFrozenNode().getProperty(NodeProperty.SIZE.toString()).getLong();
String mimeType = version.getFrozenNode().getProperty(NodeProperty.MIME_TYPE.toString()).getString();
String storageId = version.getFrozenNode().getProperty(NodeProperty.STORAGE_ID.toString()).getString();
final InputStream streamToWrite = Utils.getStorageClient(login).getClient().get().RFileAsInputStream(storageId);
String oldfilename = FilenameUtils.getBaseName(currentItem.getTitle());
String ext = FilenameUtils.getExtension(currentItem.getTitle());
String fileName = String.format("%s_v%s.%s", oldfilename, version.getName(), ext);
accountingHandler.createReadObj(fileName, ses, node, true);
StreamingOutput so = new SingleFileStreamingOutput(streamToWrite);
return Response
.ok(so)
.header("content-disposition","attachment; filename = "+fileName)
.header("Content-Length", size)
.header("Content-Type", mimeType)
.build();
}
}
return downloadVersionInternal(ses, login, id, versionName, true);
}catch(RepositoryException re ){
log.error("jcr error downloading version", re);
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
@ -433,13 +493,51 @@ public class ItemsManager {
}
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);
Item currentItem = node2Item.getItem(node, Excludes.ALL);
if (!(currentItem instanceof AbstractFileItem))
throw new InvalidItemException("this item is not a file");
List<Version> jcrVersions = versionHandler.getContentVersionHistory(ses.getNodeByIdentifier(id), ses);
for (Version version: jcrVersions) {
log.debug("retrieved version id {}, name {}", version.getIdentifier(), version.getName());
if (version.getName().equals(versionName)) {
long size = version.getFrozenNode().getProperty(NodeProperty.SIZE.toString()).getLong();
String mimeType = version.getFrozenNode().getProperty(NodeProperty.MIME_TYPE.toString()).getString();
String storageId = version.getFrozenNode().getProperty(NodeProperty.STORAGE_ID.toString()).getString();
final InputStream streamToWrite = Utils.getStorageClient(login).getClient().get().RFileAsInputStream(storageId);
String oldfilename = FilenameUtils.getBaseName(currentItem.getTitle());
String ext = FilenameUtils.getExtension(currentItem.getTitle());
String fileName = String.format("%s_v%s.%s", oldfilename, version.getName(), ext);
if (withAccounting)
accountingHandler.createReadObj(fileName, ses, node, true);
StreamingOutput so = new SingleFileStreamingOutput(streamToWrite);
return Response
.ok(so)
.header("content-disposition","attachment; filename = "+fileName)
.header("Content-Length", size)
.header("Content-Type", mimeType)
.build();
}
}
throw new InvalidItemException("the version is not valid");
}
@GET
@Path("{id}/anchestors")
@Produces(MediaType.APPLICATION_JSON)
public ItemList getAnchestors(@QueryParam("exclude") List<String> excludes){
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;
List<Item> toReturn = new LinkedList<>();
try{
@ -498,21 +596,7 @@ public class ItemsManager {
authChecker.checkReadAuthorizationControl(ses, id);
final Item item = node2Item.getItem(node, null);
if (item instanceof AbstractFileItem){
AbstractFileItem fileItem =(AbstractFileItem) item;
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();
return downloadFileInternal(ses, (AbstractFileItem) item, login, true);
} else if (item instanceof FolderItem){
try {
@ -559,19 +643,37 @@ public class ItemsManager {
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
@Path("{id}/move")
public String move(@FormParam("destinationId") String destinationId){
InnerMethodName.instance.set("move");
Session ses = null;
try{
final String login = AuthorizationProvider.instance.get().getClient().getId();
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
authChecker.checkMoveOpsForProtectedFolders(ses, id);
authChecker.checkWriteAuthorizationControl(ses, destinationId, true);
authChecker.checkWriteAuthorizationControl(ses, id, false);
@ -579,36 +681,36 @@ public class ItemsManager {
final Node nodeToMove = ses.getNodeByIdentifier(id);
final Node destination = ses.getNodeByIdentifier(destinationId);
Node originalParent = nodeToMove.getParent();
Item destinationItem = node2Item.getItem(destination,null);
final Item item = node2Item.getItem(nodeToMove, null);
if (item instanceof SharedFolder)
throw new InvalidItemException("shared folder cannot be moved");
if (item instanceof FolderItem && Utils.hasSharedChildren(nodeToMove))
throw new InvalidItemException("folder item with shared children cannot be moved");
if (Constants.FOLDERS_TO_EXLUDE.contains(item.getTitle()) || Constants.FOLDERS_TO_EXLUDE.contains(destinationItem.getTitle()))
throw new InvalidItemException("protected folder cannot be moved");
if (!(destinationItem instanceof FolderItem))
throw new InvalidItemException("destination item is not a folder");
if (item.isShared() && (!destinationItem.isShared() || !getSharedParentNode(nodeToMove).getIdentifier().equals(getSharedParentNode(destination).getIdentifier())))
throw new InvalidCallParameters("shared Item cannot be moved in a different shared folder or in a private folder");
ses.getWorkspace().getLockManager().lock(destination.getPath(), false, true, 0,login);
ses.getWorkspace().getLockManager().lock(nodeToMove.getPath(), true, true, 0,login);
try {
String uniqueName =(Utils.checkExistanceAndGetUniqueName(ses, destination, nodeToMove.getName()));
String newPath = String.format("%s/%s",destination.getPath(), uniqueName);
ses.getWorkspace().move(nodeToMove.getPath(), newPath);
Utils.setPropertyOnChangeNode(ses.getNode(newPath), login, ItemAction.MOVED);
String mimeTypeForAccounting = (item instanceof AbstractFileItem)? ((AbstractFileItem) item).getContent().getMimeType(): null;
accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting , ses, destination, false);
accountingHandler.createFolderRemoveObj(item.getTitle(), item.getClass().getSimpleName(), mimeTypeForAccounting, ses, originalParent, false);
ses.save();
@ -616,7 +718,7 @@ public class ItemsManager {
ses.getWorkspace().getLockManager().unlock(nodeToMove.getPath());
ses.getWorkspace().getLockManager().unlock(destination.getPath());
}
}catch(RepositoryException re ){
log.error("jcr error moving item", re);
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
@ -665,7 +767,7 @@ public class ItemsManager {
ses.getWorkspace().copy(nodeToCopy.getPath(), newPath);
Node newNode = ses.getNode(newPath);
newFileIdentifier = newNode.getIdentifier();
if (item instanceof AbstractFileItem) {
String oldStorageId = ((AbstractFileItem)item).getContent().getStorageId();
String newStorageID = Utils.getStorageClient(login).getClient().copyFile(true).from(oldStorageId).to(newPath);
@ -674,15 +776,15 @@ public class ItemsManager {
((AbstractFileItem) item).getContent().setRemotePath(newPath);
item2Node.replaceContent(ses, newNode, (AbstractFileItem) item, ItemAction.CLONED);
}
Utils.setPropertyOnChangeNode(newNode, login, ItemAction.CLONED);
newNode.setProperty(NodeProperty.PORTAL_LOGIN.toString(), login);
newNode.setProperty(NodeProperty.IS_PUBLIC.toString(), false);
String mimeTypeForAccounting = (item instanceof AbstractFileItem)? ((AbstractFileItem) item).getContent().getMimeType(): null;
accountingHandler.createFolderAddObj(uniqueName, item.getClass().getSimpleName(), mimeTypeForAccounting, ses, destination, false);
ses.save();
}finally {
@ -714,7 +816,7 @@ public class ItemsManager {
final String login = AuthorizationProvider.instance.get().getClient().getId();
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
authChecker.checkMoveOpsForProtectedFolders(ses, id);
authChecker.checkWriteAuthorizationControl(ses, id, false);
@ -744,7 +846,7 @@ public class ItemsManager {
ses.getWorkspace().getLockManager().unlock(nodeToMove.getPath());
ses.getWorkspace().getLockManager().unlock(nodeToMove.getParent().getPath());
}
}catch(RepositoryException re ){
log.error("jcr error moving item", re);
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
@ -777,7 +879,7 @@ public class ItemsManager {
final Node nodeToUpdate = ses.getNodeByIdentifier(id);
ses.getWorkspace().getLockManager().lock(nodeToUpdate.getPath(), false, true, 0,login);
try {
item2Node.updateMetadataNode(ses, nodeToUpdate, metadata.getMap(), login);
@ -786,7 +888,7 @@ public class ItemsManager {
ses.getWorkspace().getLockManager().unlock(nodeToUpdate.getPath());
}
//TODO: UPDATE accounting
}catch(RepositoryException re ){
log.error("jcr error moving item", re);
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
@ -802,13 +904,13 @@ public class ItemsManager {
return Response.ok(id).build();
}
@DELETE
@Path("{id}")
public Response deleteItem(){
InnerMethodName.instance.set("deleteItem");
//TODO: check also that is not already trashed
Session ses = null;
try{
@ -848,5 +950,5 @@ public class ItemsManager {
return Response.ok().build();
}
}

View File

@ -1,12 +1,14 @@
package org.gcube.data.access.storagehub.services;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.Session;
import javax.jcr.NodeIterator;
import javax.jcr.query.QueryResult;
import javax.servlet.ServletContext;
import javax.ws.rs.DELETE;
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.QueryBuilder;
import org.apache.jackrabbit.api.security.user.User;
import org.gcube.common.authorization.library.annotations.AuthorizationControl;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
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.exceptions.BackendGenericError;
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.exception.MyAuthException;
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
import org.gcube.data.access.storagehub.handlers.UnshareHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -43,10 +48,13 @@ public class UserManager {
@Inject
RepositoryInitializer repository;
@Inject
UnshareHandler unshareHandler;
@GET
@Path("")
@Produces(MediaType.APPLICATION_JSON)
@AuthorizationControl(allowed={"lucio.lelii"})
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
public List<String> getUsers(){
JackrabbitSession session = null;
@ -64,7 +72,7 @@ public class UserManager {
while (result.hasNext()) {
Authorizable user = result.next();
log.info("user {} found",user.getPrincipal().getName());
log.debug("user {} found",user.getPrincipal().getName());
users.add(user.getPrincipal().getName());
}
}catch(Exception e) {
@ -79,7 +87,7 @@ public class UserManager {
@POST
@Path("")
@AuthorizationControl(allowed={"lucio.lelii"})
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
public String createUser(@FormParam("user") String user, @FormParam("password") String password){
JackrabbitSession session = null;
@ -95,13 +103,16 @@ public class UserManager {
Node homeNode = session.getNode("/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 trashFolder = Utils.createFolderInternally(session, workspaceFolder, Constants.TRASH_ROOT_FOLDER_NAME, "trash of "+user, false, user, null);
Node specialFolder = Utils.createFolderInternally(session, workspaceFolder, Constants.VRE_FOLDER_PARENT_NAME, "special folder container of "+user, false, user, null);
//creating thrash folder
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();
}catch(Exception e) {
log.error("jcr error getting users", e);
log.error("jcr error creating user {}", user, e);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
} finally {
if (session!=null)
@ -113,7 +124,7 @@ public class UserManager {
@DELETE
@Path("{id}")
@AuthorizationControl(allowed={"lucio.lelii"})
@AuthorizationControl(allowed={"lucio.lelii"}, exception=MyAuthException.class)
public String deleteUser(@PathParam("id") String id){
JackrabbitSession session = null;
@ -122,10 +133,31 @@ public class UserManager {
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
org.apache.jackrabbit.api.security.user.UserManager usrManager = session.getUserManager();
org.gcube.common.storagehub.model.Path path = Utils.getWorkspacePath(id);
String sql2Query = String.format("SELECT * FROM [nthl:workspaceSharedItem] AS node WHERE ISDESCENDANTNODE('%s')", path.toPath());
Authorizable authorizable = usrManager.getAuthorizable(id);
if (!authorizable.isGroup())
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();
}
session.save();
}catch(Exception e) {
log.error("jcr error getting users", e);

View File

@ -98,8 +98,8 @@ public class WorkspaceManager {
Session ses = null;
org.gcube.common.storagehub.model.Path absolutePath;
if (relPath==null)
absolutePath = Utils.getHomePath();
else absolutePath = Paths.append(Utils.getHomePath(), relPath);
absolutePath = Utils.getWorkspacePath();
else absolutePath = Paths.append(Utils.getWorkspacePath(), relPath);
Item toReturn = null;
try{
@ -124,7 +124,7 @@ public class WorkspaceManager {
}
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());
if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE");
String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-");
@ -208,7 +208,7 @@ public class WorkspaceManager {
InnerMethodName.instance.set("getTrashRootFolder");
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;
try{
long start = System.currentTimeMillis();
@ -237,7 +237,7 @@ public class WorkspaceManager {
public String emptyTrash(){
InnerMethodName.instance.set("emptyTrash");
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;
try{
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
@ -307,7 +307,7 @@ public class WorkspaceManager {
InnerMethodName.instance.set("getVreFolders");
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;
try{
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){
InnerMethodName.instance.set("getVreFoldersPaged");
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;
try{
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
@ -365,7 +365,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.getHomePath()), expression));
String stringExpression = evaluator.evaluate(new And(new ISDescendant(Utils.getWorkspacePath()), expression));
String orderBy = "";
if (orderField!=null && orderField.size()>0)
@ -376,7 +376,7 @@ public class WorkspaceManager {
log.info("query sent is {}",sql2Query);
String login = AuthorizationProvider.instance.get().getClient().getId();
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(sql2Query, Constants.QUERY_LANGUAGE);

View File

@ -3,5 +3,12 @@
<group>DataAccess</group>
<version>1.0.0-SNAPSHOT</version>
<description>Storage Hub webapp</description>
<!-- <proxy protocol="https">
<hostname>workspace-repository.dev.d4science.org</hostname>
<port>443</port>
</proxy> -->
<local-persistence location='target' />
</application>