diff --git a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java index b70ecb7..e6e2638 100644 --- a/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java +++ b/geoportal-common/src/main/java/org/gcube/application/geoportal/common/rest/InterfaceConstants.java @@ -29,6 +29,8 @@ public class InterfaceConstants { public static final String STEP="step"; public static final String RELATIONSHIP="relationship"; + public static final String FORCE_UNLOCK="forceUnlock"; + public static final String SET_PROJECT_ACCESS_POLICY="setAccess"; } diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/MongoManagerI.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/MongoManagerI.java index e13adfc..2590473 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/MongoManagerI.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/MongoManagerI.java @@ -7,6 +7,7 @@ import org.gcube.application.cms.plugins.faults.InsufficientPrivileges; import org.gcube.application.cms.plugins.faults.StepException; import org.gcube.application.geoportal.common.faults.StorageException; import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.document.access.Access; import org.gcube.application.geoportal.common.model.rest.QueryRequest; import org.gcube.application.geoportal.common.model.rest.RegisterFileSetRequest; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; @@ -48,5 +49,9 @@ public interface MongoManagerI { public T registerFileSet(String id, RegisterFileSetRequest request) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess; public T deleteFileSet(String id, String destination, Boolean force) throws ConfigurationException, StorageHubException, StorageException, StepException, JsonProcessingException, DeletionException, EventException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess; + public T forceUnlock(String id) throws InvalidUserRoleException, ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException, InvalidLockException; + public T setAccessPolicy(String id, Access access) throws InvalidUserRoleException, ProjectLockedException, ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException, InvalidLockException, EventException; + + public Configuration getConfiguration()throws ConfigurationException; } diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java index 057f2a4..09e64ee 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/engine/mongo/ProfiledMongoManager.java @@ -673,6 +673,49 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< } } + @Override + public Project forceUnlock(String id) throws InvalidUserRoleException, ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException, InvalidLockException { + Project toUnlock = null; + try{ + toUnlock = lock(id,"Check locked for force unlock"); + throw new WebApplicationException("Project "+id+" not locked", Response.Status.EXPECTATION_FAILED); + }catch (ProjectLockedException e){ + // expected exception + toUnlock = getByID(id); + }finally { + if(toUnlock!=null) unlock(toUnlock); + else throw new WebApplicationException("Unable to get Project "+id, Response.Status.EXPECTATION_FAILED); + } + return null; + } + + @Override + public Project setAccessPolicy(String id, Access access) throws InvalidUserRoleException, ProjectLockedException, ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException, InvalidLockException, EventException { + log.trace("UCD {}, Project {} : Setting Access {}",useCaseDescriptor.getId(),id,access); + Project toUpdate=lock(id,"Set Access policy"); + try { + + User u = UserUtils.getCurrent().asInfo().getUser(); + final DataAccessPolicy policy = useCaseDescriptor.getMatching(u); + + if(policy == null) { + log.warn("No policy found for {}. Returning empty ", u); + throw new InvalidUserRoleException("No policy defined for current user roles " + u.getRoles()); + } + if(!policy.canWrite(toUpdate,u)) throw new UnauthorizedAccess("No edit rights on project "+id); + + + toUpdate.getInfo().setAccess(access); + toUpdate.getLifecycleInformation().cleanState(); + toUpdate = onUpdate(toUpdate); + return unlockAndUpdate(toUpdate); + }catch(Throwable t){ + log.error("Unexpected exception ",t); + unlock(toUpdate); + throw t; + } + } + private Project deleteFileSetRoutine(Project doc,Boolean force, String path) throws ConfigurationException, StorageHubException { JSONPathWrapper wrapper = new JSONPathWrapper(doc.getTheDocument().toJson()); diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java index 069eeee..a73f3ab 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/ProfiledDocuments.java @@ -5,6 +5,7 @@ import org.bson.Document; import org.gcube.application.cms.implementations.ImplementationProvider; import org.gcube.application.geoportal.common.model.document.Project; import org.gcube.application.geoportal.common.model.configuration.Configuration; +import org.gcube.application.geoportal.common.model.document.access.Access; import org.gcube.application.geoportal.common.model.document.relationships.Relationship; import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject; import org.gcube.application.geoportal.common.model.rest.QueryRequest; @@ -156,6 +157,34 @@ public class ProfiledDocuments { }.execute().getResult(); } + @PUT + @Path("/"+InterfaceConstants.Methods.FORCE_UNLOCK+"/{"+InterfaceConstants.Parameters.PROJECT_ID+"}") + public Project forceUnlock( + @PathParam(InterfaceConstants.Parameters.PROJECT_ID) String id){ + return new GuardedMethod(){ + + @Override + protected Project run() throws Exception, WebApplicationException { + log.warn("UCD {}, forcing unlock for Project ID {}",manager.getUseCaseDescriptor().getId(),id); + return manager.forceUnlock(id); + } + }.execute().getResult(); + } + + @PUT + @Path("/"+InterfaceConstants.Methods.SET_PROJECT_ACCESS_POLICY+"/{"+InterfaceConstants.Parameters.PROJECT_ID+"}") + public Project setAccessPolicy( + @PathParam(InterfaceConstants.Parameters.PROJECT_ID) String id, Access toSet){ + return new GuardedMethod(){ + + @Override + protected Project run() throws Exception, WebApplicationException { + log.warn("UCD {}, setting Policy {} Project ID {}",manager.getUseCaseDescriptor().getId(),toSet,id); + return manager.setAccessPolicy(id,toSet); + } + }.execute().getResult(); + } + //********************************** READ @GET