storagehub/src/main/java/org/gcube/data/access/storagehub/services/GroupManager.java

345 lines
12 KiB
Java

package org.gcube.data.access.storagehub.services;
import static org.gcube.data.access.storagehub.Roles.INFRASTRUCTURE_MANAGER_ROLE;
import static org.gcube.data.access.storagehub.Roles.VREMANAGER_ROLE;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.jcr.RepositoryException;
import org.apache.jackrabbit.api.JackrabbitSession;
import org.gcube.common.authorization.control.annotations.AuthorizationControl;
import org.gcube.common.gxrest.response.outbound.GXOutboundErrorResponse;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.common.storagehub.model.acls.AccessType;
import org.gcube.common.storagehub.model.exceptions.BackendGenericError;
import org.gcube.common.storagehub.model.exceptions.StorageHubException;
import org.gcube.common.storagehub.model.exceptions.UserNotAuthorizedException;
import org.gcube.data.access.storagehub.Constants;
import org.gcube.data.access.storagehub.PathUtil;
import org.gcube.data.access.storagehub.StorageHubAppllicationManager;
import org.gcube.data.access.storagehub.services.delegates.GroupManagerDelegate;
import org.gcube.smartgears.annotations.ManagedBy;
import org.gcube.smartgears.utils.InnerMethodName;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webcohesion.enunciate.metadata.rs.RequestHeader;
import com.webcohesion.enunciate.metadata.rs.RequestHeaders;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@Path("groups")
@Singleton
@ManagedBy(StorageHubAppllicationManager.class)
@RequestHeaders({
@RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources"),
})
public class GroupManager {
private static final Logger log = LoggerFactory.getLogger(GroupManager.class);
RepositoryInitializer repository = StorageHubAppllicationManager.getRepository();
@Inject
GroupManagerDelegate groupHandler;
@Inject
PathUtil pathUtil;
@GET
@Path("")
@Produces(MediaType.APPLICATION_JSON)
public List<String> getGroups(){
InnerMethodName.set("getGroups");
JackrabbitSession session = null;
List<String> groups= new ArrayList<>();
try {
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
groups = groupHandler.getGroups(session);
}catch(RepositoryException re ){
log.error("jcr error creating item", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
} finally {
if (session!=null)
session.logout();
}
return groups;
}
@POST
@Path("")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE})
public String createGroup(@FormDataParam("group") String group, @FormDataParam("accessType") AccessType accessType, @FormDataParam("folderOwner") String folderOwner, @FormDataParam("useDefaultStorage") @DefaultValue("true") boolean useDefaultStorage){
InnerMethodName.set("createGroup");
JackrabbitSession session = null;
try {
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
groupHandler.createGroup(session, group, accessType, folderOwner, useDefaultStorage);
session.save();
}catch(StorageHubException se) {
log.error("error creating group {}", group, se);
GXOutboundErrorResponse.throwException(se);
}catch(Throwable e) {
log.error("jcr error creating group {}", group, e);
GXOutboundErrorResponse.throwException(new BackendGenericError(e));
} finally {
if (session!=null)
session.logout();
}
return group;
}
@DELETE
@Path("{group}")
@AuthorizationControl(allowedRoles={INFRASTRUCTURE_MANAGER_ROLE})
public String deleteGroup(@PathParam("group") String group){
InnerMethodName.set("deleteGroup");
JackrabbitSession session = null;
try {
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
groupHandler.deleteGroup(session, group);
session.save();
}catch(RepositoryException re ){
log.error("jcr error creating item", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
} finally {
if (session!=null)
session.logout();
}
return group;
}
public boolean isInfraManager() { return SecretManagerProvider.get().getOwner().getRoles().contains(INFRASTRUCTURE_MANAGER_ROLE); }
public boolean isVREManager() { return SecretManagerProvider.get().getOwner().getRoles().contains(VREMANAGER_ROLE); }
@PUT
@Path("{id}/admins")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void addAdmin(@PathParam("id") String groupId, @FormParam("userId") String userId){
InnerMethodName.set("addAdmin");
JackrabbitSession session = null;
try {
Objects.nonNull(groupId);
Objects.nonNull(userId);
String currentUser = SecretManagerProvider.get().getOwner().getId();
if (!isInfraManager() && !(isVREManager() && isValidGroupForContext(groupId)) &&
!groupHandler.getGroupAdministators(session, groupId).contains(currentUser))
throw new UserNotAuthorizedException();
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
groupHandler.addAdministratorToGroup(session, groupId, userId);
session.save();
}catch(StorageHubException she ){
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(Throwable 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)
public void removeAdmin(@PathParam("id") String groupId, @PathParam("userId") String userId){
InnerMethodName.set("removeAdmin");
JackrabbitSession session = null;
try {
Objects.nonNull(groupId);
Objects.nonNull(userId);
String currentUser = SecretManagerProvider.get().getOwner().getId();
if (!isInfraManager() && !(isVREManager() && isValidGroupForContext(groupId)) &&
!groupHandler.getGroupAdministators(session, groupId).contains(currentUser))
throw new UserNotAuthorizedException();
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
groupHandler.removeAdministratorFromGroup(session, groupId, userId);
session.save();
}catch(StorageHubException she ){
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(Throwable re ){
log.error("jcr error creating item", 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.set("getAdmins");
List<String> users = new ArrayList<>();
JackrabbitSession session = null;
try {
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
users = groupHandler.getGroupAdministators(session, groupId);
}catch(StorageHubException she ){
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(Throwable re ){
log.error("jcr error getting admins", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting admins", re));
} finally {
if (session!=null)
session.logout();
}
return users;
}
@PUT
@Path("{id}/users")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE})
public boolean addUserToGroup(@PathParam("id") String groupId, @FormParam("userId") String userId){
InnerMethodName.set("addUserToGroup");
JackrabbitSession session = null;
boolean success = false;
try {
if (!isInfraManager() && !(isVREManager() && isValidGroupForContext(groupId)))
throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation");
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
groupHandler.addUserToGroup(session, userId, groupId);
success = true;
session.save();
}catch(StorageHubException she ){
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
log.error("jcr error adding user to group", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error adding user to group", re));
} finally {
if (session!=null)
session.logout();
}
return success;
}
@DELETE
@Path("{groupId}/users/{userId}")
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE})
public boolean removeUserFromGroup(@PathParam("groupId") String groupId, @PathParam("userId") String userId){
InnerMethodName.set("removeUserFromGroup");
JackrabbitSession session = null;
boolean success = false;
try {
if (!isInfraManager() && !(isVREManager() && isValidGroupForContext(groupId)))
throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation");
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
success = groupHandler.removeUserFromGroup(session, groupId, userId);
session.save();
}catch(StorageHubException she ){
log.error(she.getErrorMessage(), she);
GXOutboundErrorResponse.throwException(she, Response.Status.fromStatusCode(she.getStatus()));
}catch(RepositoryException re ){
log.error("jcr error creating item", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error creating item", re));
} finally {
if (session!=null)
session.logout();
}
return success;
}
@GET
@Path("{groupId}/users")
@Produces(MediaType.APPLICATION_JSON)
@AuthorizationControl(allowedRoles={VREMANAGER_ROLE, INFRASTRUCTURE_MANAGER_ROLE})
public List<String> getUsersOfGroup(@PathParam("groupId") String groupId){
InnerMethodName.set("getUsersOfGroup");
JackrabbitSession session = null;
List<String> users = new ArrayList<>();
try {
if (!isInfraManager() && !(isVREManager() && isValidGroupForContext(groupId)))
throw new UserNotAuthorizedException("only VREManager of the selected VRE can execute this operation");
session = (JackrabbitSession) repository.getRepository().login(Constants.JCR_CREDENTIALS);
users = groupHandler.getUsersBelongingToGroup(session, groupId);
}catch (StorageHubException e) {
log.error("error getting users", e);
GXOutboundErrorResponse.throwException(e);
}catch(RepositoryException re ){
log.error("jcr error getting users", re);
GXOutboundErrorResponse.throwException(new BackendGenericError("jcr error getting users", re));
} finally {
if (session!=null)
session.logout();
}
return users;
}
private boolean isValidGroupForContext(String group){
String currentContext = SecretManagerProvider.get().getContext();
String expectedGroupId= currentContext.replace("/", "-").substring(1);
return group.equals(expectedGroupId);
}
}