diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractLifeCycleManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractLifeCycleManager.java index bd8eb26..742e4d5 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractLifeCycleManager.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/AbstractLifeCycleManager.java @@ -1,5 +1,6 @@ package org.gcube.application.cms.plugins.implementations; +import com.sun.xml.internal.ws.client.HandlerConfiguration; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.gcube.application.cms.plugins.LifecycleManager; @@ -110,22 +111,28 @@ public abstract class AbstractLifeCycleManager extends AbstractPlugin implements @Override public StepExecutionReport performStep(StepExecutionRequest request) throws StepException, InvalidPluginRequestException, InvalidProfileException, ConfigurationException, InsufficientPrivileges { log.info("Serving Request {}",request); - StepExecutionReport report=new StepExecutionReport(request); - report.setStatus(Report.Status.OK); - LifecycleInformation info=report.getToSetLifecycleInformation(); - info.setLastOperationStatus(LifecycleInformation.Status.OK); - info.setLastInvokedStep(request.getStep()); - - if(!canInvokeStep(request.getStep(),request.getCaller(), - getConfigurationFromProfile(request.getUseCaseDescriptor()))) - throw new InsufficientPrivileges("User is not allowed to invoke "+request.getStep()); + log.debug("Checking is STEP {} is supported by {}",request.getStep(),DESCRIPTOR.getId()); if(!registeredSteps.containsKey(request.getStep())) throw new UnrecognizedStepException(("Invalid Step " + request.getStep())); + HandlerDeclaration handlerDeclaration= getConfigurationFromProfile(request.getUseCaseDescriptor()); + log.debug("Checking user role {} against config {} ",request.getCaller(),handlerDeclaration); + if(!canInvokeStep(request.getStep(),request.getCaller(), handlerDeclaration)) + throw new InsufficientPrivileges("User is not allowed to invoke "+request.getStep()); + + StepExecutionReport report=new StepExecutionReport(request); + LifecycleInformation info=report.getToSetLifecycleInformation(); + report.setStatus(Report.Status.OK); + info.setLastOperationStatus(LifecycleInformation.Status.OK); + info.setLastInvokedStep(request.getStep()); + try { - return registeredSteps.get(request.getStep()) - .setTheReport(report).execute(); + GuardedStepExecution exec=registeredSteps.get(request.getStep()); + exec.setTheReport(report); + exec.setHandlerConfiguration(handlerDeclaration); + log.debug("Actually executing Step with {} ",exec); + return exec.execute(); }catch (StepException | InvalidPluginRequestException e){ throw e; }catch (Throwable t) { diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/RoleManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/RoleManager.java index 09f548a..c62133e 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/RoleManager.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/RoleManager.java @@ -33,7 +33,10 @@ public class RoleManager { public boolean canInvokeStep(String stepID,User u) throws ConfigurationException { if(!accessMap.containsKey(stepID)) throw new ConfigurationException("Missing step "+stepID+" access definition"); - for (String role : accessMap.get(stepID).getRoles()) + List roles=accessMap.get(stepID).getRoles(); + if(roles.isEmpty()) return true; + + for (String role : roles) if (u.getRoles().contains(role)) return true; diff --git a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java index f3ca3ea..66993c6 100644 --- a/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java +++ b/cms-plugin-framework/src/main/java/org/gcube/application/cms/plugins/implementations/SimpleLifeCycleManager.java @@ -229,6 +229,12 @@ public class SimpleLifeCycleManager extends AbstractLifeCycleManager implements info.setLastOperationStatus(LifecycleInformation.Status.OK); if(toHandle instanceof IndexDocumentReport) toUpdate.setToSetSpatialReference(((IndexDocumentReport)toHandle).getToSetSpatialReference()); + // Propagate changes for further processings + toUpdate.getTheRequest().getDocument().setTheDocument(toHandle.getResultingDocument()); + toUpdate.setToSetLifecycleInformation(toHandle.getToSetLifecycleInformation()); + +// if(toHandle instanceof MaterializationReport) +// toUpdate.setToSetSpatialReference(((IndexDocumentReport)toHandle).getToSetSpatialReference()); break; } case ERROR : { 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 fdd9aa5..a9c0dc3 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 @@ -3,6 +3,7 @@ package org.gcube.application.geoportal.service.engine.mongo; import com.fasterxml.jackson.core.JsonProcessingException; import org.bson.Document; import org.gcube.application.cms.plugins.faults.EventException; +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; @@ -37,7 +38,7 @@ public interface MongoManagerI { public Iterable query(QueryRequest request) throws InvalidUserRoleException; public Iterable filter(QueryRequest request) throws InvalidUserRoleException; - public T performStep(String id, String step, Document options) throws IOException, StepException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess; + public T performStep(String id, String step, Document options) throws IOException, StepException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess, ConfigurationException, InsufficientPrivileges; 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; 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 a2bbee2..7d44c0b 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 @@ -15,6 +15,7 @@ import org.gcube.application.cms.plugins.LifecycleManager; import org.gcube.application.cms.plugins.faults.EventException; import org.gcube.application.cms.plugins.faults.InsufficientPrivileges; import org.gcube.application.cms.plugins.faults.StepException; +import org.gcube.application.cms.plugins.faults.UnrecognizedStepException; import org.gcube.application.geoportal.common.model.plugins.LifecycleManagerDescriptor; import org.gcube.application.geoportal.common.model.plugins.PluginDescriptor; import org.gcube.application.cms.plugins.reports.DocumentHandlingReport; @@ -167,7 +168,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< } @Getter(lazy = true) - private final LifecycleManager manager=getLCManager(); + private final LifecycleManager manager=getLCManager(); private LifecycleManager getLCManager() { try{ @@ -287,7 +288,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< } - @Override + @Override public void delete(String id,boolean force) throws DeletionException, InvalidUserRoleException, ProjectLockedException, ProjectNotFoundException, UnauthorizedAccess, JsonProcessingException, InvalidLockException { log.info("Deleting by ID {}, force {}",id,force); Project doc =lock(id,"Deletion { force : "+force+"}"); @@ -417,8 +418,10 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< @Override - public Project performStep(String id, String step, Document options) throws StepException, JsonProcessingException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess { + public Project performStep(String id, String step, Document options) throws StepException, JsonProcessingException, ProjectLockedException, ProjectNotFoundException, InvalidLockException, InvalidUserRoleException, UnauthorizedAccess, ConfigurationException, InsufficientPrivileges { Project document = lock(id,"Step "+step+" execution"); + Boolean store = true; + try { User u = UserUtils.getCurrent().asInfo().getUser(); @@ -434,7 +437,15 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< document.getLifecycleInformation().cleanState(); document = step(document, step, options); - }catch (InsufficientPrivileges | ConfigurationException e){ + + }catch (UnrecognizedStepException e){ + store = false; + throw e; + }catch (ConfigurationException e){ + store = false; + throw e; + }catch (InsufficientPrivileges e){ + store = false; throw e; } catch(Throwable t){ log.error("[UseCaseDescriptor {} ] ERROR Invoking Step {} on document {}" , useCaseDescriptor.getId(),step,id,t); @@ -445,12 +456,14 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< info.setLastInvokedStep(step); document.setLifecycleInformation(info); }finally{ - log.info("Storing {} [UseCaseDescriptor {}] After Step {}, Status : {} " ,id, useCaseDescriptor.getId(), - step,document.getLifecycleInformation().getLastOperationStatus()); - log.debug("LifecycleInformation is {} ",document.getLifecycleInformation()); - if(log.isTraceEnabled())log.trace("Document is {} ",Serialization.write(document)); - return unlockAndUpdate(document); + if (store) { + log.info("Storing {} [UseCaseDescriptor {}] After Step {}, Status : {} " ,id, useCaseDescriptor.getId(), + step,document.getLifecycleInformation().getLastOperationStatus()); + log.debug("LifecycleInformation is {} ",document.getLifecycleInformation()); + if(log.isTraceEnabled())log.trace("Document is {} ",Serialization.write(document)); + } } + return unlockAndUpdate(document); } @@ -666,12 +679,12 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< AccountingInfo user = UserUtils.getCurrent().asInfo(); try{ Configuration lcConfig = getLCManager().getCurrentConfiguration(new BaseRequest(useCaseDescriptor,user.getUser(),user.getContext())); - log.info("Configuration is {} ",lcConfig); - if(lcConfig.getArchives()!=null) - archives.addAll(lcConfig.getArchives()); + log.info("Configuration is {} ",lcConfig); + if(lcConfig.getArchives()!=null) + archives.addAll(lcConfig.getArchives()); - if(lcConfig.getIndexes()!=null) - indexes.addAll(lcConfig.getIndexes()); + if(lcConfig.getIndexes()!=null) + indexes.addAll(lcConfig.getIndexes()); }catch(Throwable e){ toReturn.addErrorMessage("Unable to get Lifecycle info "+e.getMessage()); log.error("Unable to get Lifecycle info ",e); @@ -684,13 +697,14 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< - private Project step(Project theDocument, String step, Document callParameters) throws InsufficientPrivileges, ConfigurationException { + private Project step(Project theDocument, String step, Document callParameters) throws InsufficientPrivileges, ConfigurationException, StepException { try { log.info("[UseCaseDescriptor {}] Invoking Step {} on {}", useCaseDescriptor.getId(), step, getManager().getDescriptor()); AccountingInfo user = UserUtils.getCurrent().asInfo(); StepExecutionRequest request = new StepExecutionRequest(useCaseDescriptor, user.getUser(), user.getContext(), theDocument, step); + request.setCallParameters(callParameters); log.debug("Requesting Step Execution {}", request); StepExecutionReport report = getManager().performStep(request); @@ -718,7 +732,7 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< } } return report.prepareResult(); - }catch (InsufficientPrivileges | ConfigurationException e){ + }catch (InsufficientPrivileges | ConfigurationException | UnrecognizedStepException e){ throw e; }catch(Throwable t){ log.error("Unable to perform step "+step,t); @@ -730,12 +744,12 @@ public class ProfiledMongoManager extends MongoManager implements MongoManagerI< private Project triggerEvent(Project project, String event, Document parameters) { try{ - log.info("[UseCaseDescriptor {}] triggering event {} on {}" , useCaseDescriptor.getId(),event,getManager().getDescriptor()); + log.info("[UseCaseDescriptor {}] triggering event {} on {}" , useCaseDescriptor.getId(),event,getManager().getDescriptor()); AccountingInfo user= UserUtils.getCurrent().asInfo(); - EventExecutionRequest request= new EventExecutionRequest(useCaseDescriptor,user.getUser(),user.getContext(),project,event); - log.debug("Triggering {}",request); - DocumentHandlingReport report = getManager().onEvent(request); - return report.prepareResult(); + EventExecutionRequest request= new EventExecutionRequest(useCaseDescriptor,user.getUser(),user.getContext(),project,event); + log.debug("Triggering {}",request); + DocumentHandlingReport report = getManager().onEvent(request); + return report.prepareResult(); } catch (Throwable t){ log.error("Unable to trigger event "+event,t); project.getLifecycleInformation().addErrorMessage("Unable to trigger "+event+" cause : "+ t.getMessage()); diff --git a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/GuardedMethod.java b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/GuardedMethod.java index 8feb970..6293f5c 100644 --- a/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/GuardedMethod.java +++ b/geoportal-service/src/main/java/org/gcube/application/geoportal/service/rest/GuardedMethod.java @@ -2,8 +2,11 @@ package org.gcube.application.geoportal.service.rest; import lombok.extern.slf4j.Slf4j; import org.gcube.application.cms.plugins.faults.InsufficientPrivileges; +import org.gcube.application.cms.plugins.faults.UnrecognizedStepException; +import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation; import org.gcube.application.geoportal.common.model.rest.ConfigurationException; import org.gcube.application.geoportal.service.model.internal.faults.InvalidLockException; +import org.gcube.application.geoportal.service.model.internal.faults.InvalidUserRoleException; import org.gcube.application.geoportal.service.model.internal.faults.ProjectLockedException; import org.gcube.application.geoportal.service.model.internal.faults.ProjectNotFoundException; @@ -36,16 +39,26 @@ public abstract class GuardedMethod { log.trace("Executing actual method.."); result = run(); return this; + }catch (InvalidUserRoleException e){ + log.error("Returning exception ",e); + throw new WebApplicationException("Invalid Step ID ", e,Status.FORBIDDEN); + }catch (UnrecognizedStepException e){ + log.error("Returning exception ",e); + throw new WebApplicationException("Invalid Step ID ", e,Status.BAD_REQUEST); }catch (ConfigurationException e){ + log.error("Returning exception ",e); throw new WebApplicationException("Environment is not properly configured", e,Status.EXPECTATION_FAILED); }catch (InsufficientPrivileges e){ + log.error("Returning exception ",e); throw new WebApplicationException("User has insufficient privileges for requested action", e,Status.FORBIDDEN); }catch(WebApplicationException e) { log.error("Throwing Web Application Exception ", e); throw e; }catch(ProjectNotFoundException e){ + log.error("Returning exception ",e); throw new WebApplicationException("Project not found", e,Status.NOT_FOUND); }catch(ProjectLockedException e){ + log.error("Returning exception ",e); throw new WebApplicationException("Project is currently locked", e,Status.PRECONDITION_FAILED); }catch(InvalidLockException e){ log.error("Lock exception ",e); diff --git a/geoportal-service/src/test/java/org/gcube/application/geoportal/service/engine/mongo/LockTests.java b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/engine/mongo/LockTests.java index f60ceda..c9891cc 100644 --- a/geoportal-service/src/test/java/org/gcube/application/geoportal/service/engine/mongo/LockTests.java +++ b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/engine/mongo/LockTests.java @@ -2,6 +2,7 @@ package org.gcube.application.geoportal.service.engine.mongo; import org.bson.Document; import org.gcube.application.cms.plugins.faults.EventException; +import org.gcube.application.cms.plugins.faults.InsufficientPrivileges; import org.gcube.application.cms.plugins.faults.StepException; import org.gcube.application.cms.tests.TokenSetter; import org.gcube.application.cms.tests.model.concessioni.TestConcessioniModel; @@ -88,7 +89,7 @@ public class LockTests extends BasicServiceTestUnit { } @Test - public void testUnlock() throws StepException, EventException, IOException, ProjectNotFoundException, ProjectLockedException, InvalidLockException, DeletionException, ConfigurationException, StorageHubException, StorageException, InvalidUserRoleException, UnauthorizedAccess { + public void testUnlock() throws StepException, EventException, IOException, ProjectNotFoundException, ProjectLockedException, InvalidLockException, DeletionException, ConfigurationException, StorageHubException, StorageException, InvalidUserRoleException, UnauthorizedAccess, InsufficientPrivileges { assumeTrue(GCubeTest.isTestInfrastructureEnabled()); MongoManagerI managerInterface = manager; // create diff --git a/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/DummyProjectTest.java b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/DummyProjectTest.java index cd2fff0..e6baeee 100644 --- a/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/DummyProjectTest.java +++ b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/DummyProjectTest.java @@ -27,7 +27,7 @@ public class DummyProjectTest extends AbstractProfiledDocumentsTests{ @Override protected WebTarget baseTarget() { - String testProfileId="profiledConcessioni"; + String testProfileId="basic"; return target(InterfaceConstants.Methods.PROJECTS).path(testProfileId); } diff --git a/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/ProfiledConcessioniTests.java b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/ProfiledConcessioniTests.java index 8cf6068..f5f6529 100644 --- a/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/ProfiledConcessioniTests.java +++ b/geoportal-service/src/test/java/org/gcube/application/geoportal/service/profiledDocuments/ProfiledConcessioniTests.java @@ -63,7 +63,7 @@ public class ProfiledConcessioniTests extends AbstractProfiledDocumentsTests{ // invoke step Publish StepExecutionRequest approveDraftReq=new StepExecutionRequest(); - approveDraftReq.setStepID("APPROVE DRAFT"); + approveDraftReq.setStepID("APPROVE-SUBMITTED"); doc=step(doc.getId(),approveDraftReq); System.out.println(doc); assertTrue(doc.getLifecycleInformation().getLastOperationStatus().equals(LifecycleInformation.Status.OK));