methdo for administrator management added

This commit is contained in:
lucio 2020-01-15 19:11:07 +01:00
parent 2dc02aa194
commit 67fe556a4f
7 changed files with 284 additions and 80 deletions

View File

@ -22,11 +22,15 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
import javax.jcr.query.Query;
import javax.jcr.version.Version;
import org.apache.commons.io.FilenameUtils;
import org.apache.jackrabbit.util.Text;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.scope.impl.ScopeBean;
import org.gcube.common.scope.impl.ScopeBean.Type;
import org.gcube.common.storagehub.model.Excludes;
import org.gcube.common.storagehub.model.Paths;
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
@ -39,15 +43,13 @@ 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.common.storagehub.model.types.NodeProperty;
import org.gcube.contentmanager.storageclient.wrapper.AccessType;
import org.gcube.contentmanager.storageclient.wrapper.MemoryType;
import org.gcube.contentmanager.storageclient.wrapper.StorageClient;
import org.gcube.data.access.storagehub.accounting.AccountingHandler;
import org.gcube.data.access.storagehub.handlers.Item2NodeConverter;
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter;
import org.gcube.data.access.storagehub.handlers.StorageBackendHandler;
import org.gcube.data.access.storagehub.handlers.VRE;
import org.gcube.data.access.storagehub.handlers.VREManager;
import org.gcube.data.access.storagehub.handlers.VersionHandler;
import org.gcube.data.access.storagehub.storage.backend.impl.GCubeStorageBackend;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -323,8 +325,10 @@ public class Utils {
//item.setHidden(destinationItem.isHidden());
Node newNode = new Item2NodeConverter().getNode(destinationNode, item);
if (accountingHandler!=null)
accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, newNode, false);
if (accountingHandler!=null) {
accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false);
accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false);
}
return newNode;
}
@ -349,8 +353,10 @@ public class Utils {
//item.setHidden(destinationItem.isHidden());
Node newNode = new Item2NodeConverter().getNode(destinationNode, item);
if (accountingHandler!=null)
accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, newNode, false);
if (accountingHandler!=null) {
accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), null, ses, destinationNode, false);
accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false);
}
return newNode;
}
@ -380,4 +386,43 @@ public class Utils {
node.setProperty(NodeProperty.LAST_MODIFIED_BY.toString(), login);
node.setProperty(NodeProperty.LAST_ACTION.toString(), action.name());
}
public static synchronized VRE getVreFolderItem(Session ses, Node2ItemConverter node2Item, VREManager vreManager, List<String> excludes ) throws RepositoryException, BackendGenericError{
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(), Constants.VRE_FOLDER_PARENT_NAME);
ScopeBean bean = new ScopeBean(ScopeProvider.instance.get());
if (!bean.is(Type.VRE)) throw new BackendGenericError("the current scope is not a VRE");
String entireScopeName= bean.toString().replaceAll("^/(.*)/?$", "$1").replaceAll("/", "-");
VRE vre = vreManager.getVRE(entireScopeName);
if (vre!=null) return vre;
else {
String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",entireScopeName, vrePath.toPath());
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE);
NodeIterator it = jcrQuery.execute().getNodes();
if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+entireScopeName);
Node folder = it.nextNode();
Item vreFolder = node2Item.getItem(folder, excludes);
return vreManager.putVRE(vreFolder);
}
}
public static synchronized VRE getVreFolderItemByGroupNameAndUser(Session ses, String goupName, String userId, Node2ItemConverter node2Item, VREManager vreManager, List<String> excludes ) throws RepositoryException, BackendGenericError{
org.gcube.common.storagehub.model.Path vrePath = Paths.append(Utils.getWorkspacePath(userId), Constants.VRE_FOLDER_PARENT_NAME);
VRE vre = vreManager.getVRE(goupName);
if (vre!=null) return vre;
else {
String query = String.format("SELECT * FROM [nthl:workspaceItem] As node WHERE node.[jcr:title] like '%s' AND ISDESCENDANTNODE('%s')",goupName, vrePath.toPath());
Query jcrQuery = ses.getWorkspace().getQueryManager().createQuery(query, Constants.QUERY_LANGUAGE);
NodeIterator it = jcrQuery.execute().getNodes();
if (!it.hasNext()) throw new BackendGenericError("vre folder not found for context "+goupName);
Node folder = it.nextNode();
Item vreFolder = node2Item.getItem(folder, excludes);
return vreManager.putVRE(vreFolder);
}
}
}

View File

@ -70,6 +70,25 @@ public class AccountingHandler {
}
}
public void createEntryCreate(String title, Session ses, Node node, boolean saveHistory ) {
try {
if (!node.hasNode(NodeProperty.ACCOUNTING.toString())){
node.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString());
}
Node accountingNodeParent = node.getNode(NodeProperty.ACCOUNTING.toString());
Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.CREATE.getNodeTypeDefinition());
accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId());
accountingNode.setProperty(DATE, Calendar.getInstance());
accountingNode.setProperty(ITEM_NAME, title);
if (saveHistory) ses.save();
} catch (RepositoryException e) {
logger.warn("error trying to retrieve accountign node",e);
}
}
public void createFileUpdated(String title, Session ses, Node node, boolean saveHistory ) {
try {
@ -107,15 +126,15 @@ public class AccountingHandler {
}
public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node node, boolean saveHistory ) {
public void createFolderAddObj(String title, String itemType, String mimeType, Session ses, Node parentNode, boolean saveHistory ) {
try {
Node directoryNode = node.getParent();
if (!directoryNode.hasNode(NodeProperty.ACCOUNTING.toString())){
directoryNode.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString());
if (!parentNode.hasNode(NodeProperty.ACCOUNTING.toString())){
parentNode.addNode(NodeProperty.ACCOUNTING.toString(), NodeProperty.NT_ACCOUNTING.toString());
}
Node accountingNodeParent = directoryNode.getNode(NodeProperty.ACCOUNTING.toString());
Node accountingNodeParent = parentNode.getNode(NodeProperty.ACCOUNTING.toString());
Node accountingNode = accountingNodeParent.addNode(UUID.randomUUID().toString(),AccountingEntryType.ADD.getNodeTypeDefinition());
accountingNode.setProperty(USER, AuthorizationProvider.instance.get().getClient().getId());
accountingNode.setProperty(DATE, Calendar.getInstance());

View File

@ -116,6 +116,8 @@ public class UnshareHandler {
unsharedNode = createUnsharedFolder(ses, parentNode, directoryName, item.getDescription(), login);
List<Item> itemsToCopy = Utils.getItemList(sharedItemNode, Excludes.ALL, null, true, null);
for (Item itemCopy: itemsToCopy) {
@ -124,11 +126,15 @@ public class UnshareHandler {
ses.move(itemToCopyNode.getPath(), String.format("%s/%s",unsharedNode.getPath(), itemToCopyNode.getName()));
}
unsharedNode.getNode(NodeProperty.ACCOUNTING.toString()).remove();
ses.move(sharedItemNode.getNode(NodeProperty.ACCOUNTING.toString()).getPath(), String.format("%s/%s",unsharedNode.getPath(), NodeProperty.ACCOUNTING.toString()));
accountingHandler.createUnshareFolder(sharedItemNode.getProperty(NodeProperty.TITLE.toString()).getString(), "ALL", ses, unsharedNode, false);
ses.save();
}catch(Throwable t) {
log.error("erro unsharing all",t);
throw t;
}finally {
ses.getWorkspace().getLockManager().unlock(sharedItemNode.getPath());
}

View File

@ -2,7 +2,6 @@ package org.gcube.data.access.storagehub.services;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.enterprise.context.RequestScoped;
@ -22,7 +21,6 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@ -161,27 +159,7 @@ public class ACLManager {
SharedFolder folder = ((SharedFolder)item);
if (folder.isVreFolder()) {
if (accessType!=AccessType.ADMINISTRATOR)
throw new InvalidCallParameters("acls in vreFolder cannot be changed, only new admin can be set");
org.apache.jackrabbit.api.security.user.UserManager usrManager = ((JackrabbitSession)ses).getUserManager();
String groupId = folder.getTitle();
Group group = (Group)usrManager.getAuthorizable(groupId);
User authUser = (User)usrManager.getAuthorizable(user);
if (!group.isMember(authUser))
throw new InvalidCallParameters("user "+user+" is not in the group "+groupId);
String path = node.getPath();
AccessControlManager acm = ses.getAccessControlManager();
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, path);
Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) };
Principal principal = AccessControlUtils.getPrincipal(ses, user);
acls.addAccessControlEntry(principal, userPrivileges);
acm.setPolicy(path, acls);
ses.save();
throw new InvalidCallParameters("acls in vreFolder cannot be changed with this method");
} else {
@ -254,9 +232,13 @@ public class ACLManager {
Item item = node2Item.getItem(node, Excludes.ALL);
if (!(item instanceof SharedFolder))
throw new InvalidItemException("the item is not a shared folder");
if (item instanceof VreFolder)
throw new InvalidCallParameters("acls in vreFolder cannot be changed with this method");
authChecker.checkAdministratorControl(ses, (SharedFolder) item);
SharedFolder folder = ((SharedFolder)item);

View File

@ -1,5 +1,6 @@
package org.gcube.data.access.storagehub.services;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -8,6 +9,8 @@ import javax.inject.Inject;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege;
import javax.servlet.ServletContext;
@ -22,6 +25,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
@ -35,17 +39,23 @@ import org.gcube.common.authorization.control.annotations.AuthorizationControl;
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.storagehub.model.Excludes;
import org.gcube.common.storagehub.model.acls.AccessType;
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.types.NodeProperty;
import org.gcube.common.storagehub.model.types.PrimaryNodeType;
import org.gcube.data.access.storagehub.AuthorizationChecker;
import org.gcube.data.access.storagehub.Constants;
import org.gcube.data.access.storagehub.Utils;
import org.gcube.data.access.storagehub.exception.MyAuthException;
import org.gcube.data.access.storagehub.handlers.CredentialHandler;
import org.gcube.data.access.storagehub.handlers.Node2ItemConverter;
import org.gcube.data.access.storagehub.handlers.VRE;
import org.gcube.data.access.storagehub.handlers.VREManager;
import org.gcube.smartgears.utils.InnerMethodName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -63,6 +73,15 @@ public class GroupManager {
@Inject
RepositoryInitializer repository;
@Inject
VREManager vreManager;
@Inject
Node2ItemConverter node2Item;
@Inject
AuthorizationChecker authChecker;
@GET
@Path("")
@Produces(MediaType.APPLICATION_JSON)
@ -171,11 +190,142 @@ public class GroupManager {
}
public boolean isAdmin() { return AuthorizationProvider.instance.get().getClient().getRoles().contains(INFRASTRUCTURE_MANAGER_ROLE); }
public boolean isInfraManager() { return AuthorizationProvider.instance.get().getClient().getRoles().contains(INFRASTRUCTURE_MANAGER_ROLE); }
@PUT
@Path("{id}/admins")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class)
public void addAdmin(@PathParam("id") String groupId, @FormParam("userId") String userId){
InnerMethodName.instance.set("addAddmin");
JackrabbitSession session = null;
try {
if (!isInfraManager() && !isValidGroupForContext(groupId) )
throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation");
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, userId, node2Item, vreManager, Excludes.ALL);
org.apache.jackrabbit.api.security.user.UserManager usrManager = ((JackrabbitSession)session).getUserManager();
Group group = (Group)usrManager.getAuthorizable(groupId);
User authUser = (User)usrManager.getAuthorizable(userId);
if (!group.isMember(authUser))
throw new InvalidCallParameters("user "+userId+" is not in the group "+groupId);
Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId());
AccessControlManager acm = session.getAccessControlManager();
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath());
Privilege[] userPrivileges = new Privilege[] { acm.privilegeFromName(AccessType.ADMINISTRATOR.getValue()) };
Principal principal = AccessControlUtils.getPrincipal(session, userId);
acls.addAccessControlEntry(principal, userPrivileges);
acm.setPolicy(node.getPath(), acls);
session.save();
}catch(StorageHubException she ){
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
log.error("adding admin to VREFolder", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error adding admin to VREFolder", re));
} finally {
if (session!=null)
session.logout();
}
}
@DELETE
@Path("{id}/admins/{userId}")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class)
public void removeAdmin(@PathParam("id") String groupId, @PathParam("userId") String userId){
InnerMethodName.instance.set("removeAdmin");
JackrabbitSession session = null;
try {
if (!isValidGroupForContext(groupId) && !isInfraManager())
throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation");
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, userId, node2Item, vreManager, Excludes.ALL);
Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId());
AccessControlManager acm = session.getAccessControlManager();
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath());
AccessControlEntry toRemove = null;
for (AccessControlEntry acl: acls.getAccessControlEntries())
if (acl.getPrincipal().getName().equals(userId)) {
toRemove = acl;
break;
}
acls.removeAccessControlEntry(toRemove);
acm.setPolicy(node.getPath(), acls);
session.save();
}catch(StorageHubException she ){
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
log.error("removing admin to VREFolder", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error removing admin to VREFolder", re));
} finally {
if (session!=null)
session.logout();
}
}
@GET
@Path("{groupId}/admins")
@Produces(MediaType.APPLICATION_JSON)
public List<String> getAdmins(@PathParam("groupId") String groupId){
InnerMethodName.instance.set("getAdmins");
JackrabbitSession session = null;
List<String> users = new ArrayList<>();
try {
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
VRE vreFolder = Utils.getVreFolderItemByGroupNameAndUser(session, groupId, AuthorizationProvider.instance.get().getClient().getId(), node2Item, vreManager, Excludes.ALL);
AccessControlManager acm = session.getAccessControlManager();
//authChecker.checkAdministratorControl(session, (VreFolder)vreFolder.getVreFolder());
Node node = session.getNodeByIdentifier(vreFolder.getVreFolder().getId());
JackrabbitAccessControlList acls = AccessControlUtils.getAccessControlList(acm, node.getPath());
for (AccessControlEntry acl: acls.getAccessControlEntries())
for (Privilege pr: acl.getPrivileges()) {
if (pr.getName().equals(AccessType.ADMINISTRATOR.getValue())){
users.add(acl.getPrincipal().getName());
}
}
}catch(Exception e) {
log.error("jcr error getting admins of group {}", groupId, e);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
} finally {
if (session!=null)
session.logout();
}
return users;
}
@PUT
@Path("{id}")
@Path("{id}/users")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE}, exception=MyAuthException.class)
public boolean addUserToGroup(@PathParam("id") String groupId, @FormParam("userId") String userId){
@ -186,7 +336,7 @@ public class GroupManager {
boolean success = false;
try {
if (!isValidGroupForContext(groupId) && !isAdmin())
if (!isValidGroupForContext(groupId) && !isInfraManager())
throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation");
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
@ -231,7 +381,7 @@ public class GroupManager {
boolean success = false;
try {
if (!isValidGroupForContext(groupId) && !isAdmin())
if (!isValidGroupForContext(groupId) && !isInfraManager())
throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation");
session = (JackrabbitSession) repository.getRepository().login(CredentialHandler.getAdminCredentials(context));

View File

@ -192,6 +192,7 @@ public class ItemsCreator {
ses.getWorkspace().getLockManager().unlock(destination.getPath());
}
log.info("item with id {} correctly created",newNode.getIdentifier());
toReturn = newNode.getIdentifier();
}catch(StorageHubException she ){
@ -354,12 +355,13 @@ public class ItemsCreator {
}
try {
newNode = item2Node.getNode(destinationNode, item);
accountingHandler.createEntryCreate(item.getTitle(), ses, newNode, false);
ses.save();
}finally {
if (withLock) ses.getWorkspace().getLockManager().unlock(destinationNode.getPath());
}
versionHandler.makeVersionableContent(newNode, ses);
accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), item.getContent().getMimeType(), ses, newNode, false);
accountingHandler.createFolderAddObj(name, item.getClass().getSimpleName(), item.getContent().getMimeType(), ses, destinationNode, false);
}
return newNode;

View File

@ -136,7 +136,7 @@ public class WorkspaceManager {
return new ItemWrapper<Item>(toReturn);
}
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.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");
@ -155,7 +155,7 @@ public class WorkspaceManager {
return vreManager.putVRE(vreFolder);
}
}
}*/
@Path("vrefolder")
@ -167,7 +167,7 @@ public class WorkspaceManager {
Item vreItem = null;
try {
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
vreItem = getVreFolderItem(ses).getVreFolder();
vreItem = Utils.getVreFolderItem(ses, node2Item, vreManager, excludes).getVreFolder();
}catch(RepositoryException re ){
log.error("jcr error getting vrefolder", re);
GXOutboundErrorResponse.throwException(new BackendGenericError(re));
@ -192,7 +192,7 @@ public class WorkspaceManager {
String login = AuthorizationProvider.instance.get().getClient().getId();
ses = repository.getRepository().login(CredentialHandler.getAdminCredentials(context));
VRE vre = getVreFolderItem(ses);
VRE vre = Utils.getVreFolderItem(ses, node2Item, vreManager, excludes);
log.trace("VRE retrieved {}",vre.getVreFolder().getTitle());
recentItems = vre.getRecents();
log.trace("recents retrieved {}",vre.getVreFolder().getTitle());