diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java index 4949b04103e2e458b28fa3bf70c2565d942f6147..3f9a7ff90a46f00d2e0956fad3b6434c86830df4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/RelationshipService.java @@ -22,6 +22,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.DAOFactory; import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService; import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetRelationshipPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession; import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE; @@ -41,6 +42,9 @@ public class RelationshipService implements IRelationshipService private static final String ERR_SAMPLE_PARENT_RELATIONSHIP_NOT_FOUND = "Sample '%s' did not have parent '%s'"; + private static final String ERR_DATASET_PARENT_RELATIONSHIP_NOT_FOUND = + "DataSet '%s' did not have parent '%s'"; + private DAOFactory daoFactory; @Override @@ -161,6 +165,49 @@ public class RelationshipService implements IRelationshipService sample.setContainer(null); } + @Override + public void addParentToDataSet(IAuthSession session, DataPE data, DataPE parent) + { + PersonPE actor = session.tryGetPerson(); + data.addParentRelationship(new DataSetRelationshipPE(parent, data, actor)); + } + + @Override + public void removeParentFromDataSet(IAuthSession session, DataPE data, DataPE parent) + { + DataSetRelationshipPE remove = null; + for (DataSetRelationshipPE r : data.getParentRelationships()) + { + if (r.getParentDataSet().equals(parent)) + { + remove = r; + break; + } + } + + if (remove != null) + { + data.removeParentRelationship(remove); + } else + { + throw UserFailureException.fromTemplate(ERR_DATASET_PARENT_RELATIONSHIP_NOT_FOUND, data + .getCode(), parent.getCode()); + } + } + + @Override + public void assignDataSetToContainer(IAuthSession session, DataPE data, DataPE container) + { + PersonPE modifier = session.tryGetPerson(); + container.addComponent(data, modifier); + } + + @Override + public void removeDataSetFromContainer(IAuthSession session, DataPE sample) + { + sample.getContainer().removeComponent(sample); + } + public void setDaoFactory(DAOFactory daoFactory) { this.daoFactory = daoFactory; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java index ebf5d549087bc6f3f71482ece46a8f0a902caf91..55705f790a01bc8624e3af7f46da2a0484644684 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractDataSetBusinessObject.java @@ -52,7 +52,7 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdentifierBusinessObject { - private IRelationshipService relationshipService; + protected IRelationshipService relationshipService; public AbstractDataSetBusinessObject(IDAOFactory daoFactory, Session session, IRelationshipService relationshipService) @@ -185,8 +185,6 @@ public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdenti protected void replaceParents(DataPE child, Set<DataPE> newParents, boolean validate) { - PersonPE actor = findPerson(); - // quick check for deletions for (DataPE parent : newParents) { @@ -212,13 +210,13 @@ public abstract class AbstractDataSetBusinessObject extends AbstractSampleIdenti { if (false == newParents.contains(r.getParentDataSet())) { - child.removeParentRelationship(r); + relationshipService.removeParentFromDataSet(session, child, r.getParentDataSet()); } } for (DataPE newParent : newParents) { - child.addParentRelationship(new DataSetRelationshipPE(newParent, child, actor)); + relationshipService.addParentToDataSet(session, child, newParent); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java index db531395e2d126cb96b49e2e8066e032713f2993..57eb809783c63bf59b84ca36ef95f4c23cda30d8 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java @@ -653,10 +653,9 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO private void addComponents(Collection<DataPE> componentsToAdd) { - PersonPE modifier = findPerson(); for (DataPE component : componentsToAdd) { - data.addComponent(component, modifier); + relationshipService.assignDataSetToContainer(session, component, data); } } @@ -664,7 +663,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO { for (DataPE component : componentsToRemove) { - data.removeComponent(component); + relationshipService.removeDataSetFromContainer(session, component); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java index 7b849ae39b9959bae5c82590386605b292b162d8..a875a0d5a94cae3c2c304739ade8e085002752ab 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IRelationshipService.java @@ -167,4 +167,42 @@ public interface IRelationshipService @AuthorizationGuard(guardClass = SamplePEPredicate.class) SamplePE sample); + @Transactional(propagation = Propagation.MANDATORY) + @RolesAllowed(value = + { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER }) + @Capability("ADD_PARENT_TO_DATASET") + public void addParentToDataSet(IAuthSession session, + @AuthorizationGuard(guardClass = DataPEPredicate.class) + DataPE data, + @AuthorizationGuard(guardClass = DataPEPredicate.class) + DataPE parent); + + @Transactional(propagation = Propagation.MANDATORY) + @RolesAllowed(value = + { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER }) + @Capability("REMOVE_PARENT_FROM_DATASET") + public void removeParentFromDataSet(IAuthSession session, + @AuthorizationGuard(guardClass = DataPEPredicate.class) + DataPE data, + @AuthorizationGuard(guardClass = DataPEPredicate.class) + DataPE parent); + + @Transactional(propagation = Propagation.MANDATORY) + @RolesAllowed(value = + { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER }) + @Capability("ADD_CONTAINER_TO_DATASET") + public void assignDataSetToContainer(IAuthSession session, + @AuthorizationGuard(guardClass = DataPEPredicate.class) + DataPE data, + @AuthorizationGuard(guardClass = DataPEPredicate.class) + DataPE container); + + @Transactional(propagation = Propagation.MANDATORY) + @RolesAllowed(value = + { RoleWithHierarchy.SPACE_ETL_SERVER, RoleWithHierarchy.SPACE_POWER_USER }) + @Capability("REMOVE_CONTAINER_FROM_DATASET") + public void removeDataSetFromContainer(IAuthSession session, + @AuthorizationGuard(guardClass = DataPEPredicate.class) + DataPE sample); + } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java index ebdc64cffab906d4b136a4511aa16f11edcb3419..bff5f815a15d8416dcb31d55a4c2959274161ef0 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java @@ -55,6 +55,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataManagementSystemPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession; import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.NewContainerDataSet; import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; @@ -301,6 +302,9 @@ public class DataBOTest extends AbstractBOTest { one(dataDAO).tryToFindDataSetByCode(PARENT_CODE); will(returnValue(data)); + + one(relationshipService).addParentToDataSet(with(any(IAuthSession.class)), + with(any(DataPE.class)), with(any(DataPE.class))); } }); @@ -312,8 +316,6 @@ public class DataBOTest extends AbstractBOTest assertEquals(null, loadedData.tryGetSample()); assertSame(true, loadedData.isMeasured()); assertSame(dataStore, loadedData.getDataStore()); - assertEquals(1, loadedData.getParents().size()); - assertSame(data, loadedData.getParents().iterator().next()); context.assertIsSatisfied(); } @@ -347,6 +349,10 @@ public class DataBOTest extends AbstractBOTest will(returnValue(dataSetTypeUnknown)); one(dataDAO).createDataSet(parentData, EXAMPLE_PERSON); + + one(relationshipService).addParentToDataSet(with(any(IAuthSession.class)), + with(any(DataPE.class)), with(any(DataPE.class))); + } }); @@ -358,8 +364,6 @@ public class DataBOTest extends AbstractBOTest assertEquals(null, data.tryGetSample()); assertSame(true, data.isMeasured()); assertSame(dataStore, data.getDataStore()); - assertEquals(1, data.getParents().size()); - assertEquals(parentData, data.getParents().iterator().next()); context.assertIsSatisfied(); } @@ -394,6 +398,10 @@ public class DataBOTest extends AbstractBOTest will(returnValue(dataSetTypeUnknown)); one(dataDAO).createDataSet(parentData, EXAMPLE_PERSON); + + one(relationshipService).addParentToDataSet(with(any(IAuthSession.class)), + with(any(DataPE.class)), with(any(DataPE.class))); + } }); @@ -404,8 +412,6 @@ public class DataBOTest extends AbstractBOTest assertSame(null, data.tryGetSample()); assertSame(true, data.isMeasured()); assertSame(dataStore, data.getDataStore()); - assertEquals(1, data.getParents().size()); - assertEquals(parentData, data.getParents().iterator().next()); context.assertIsSatisfied(); } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java index 4e00a12f19d6abfe59a50f148f12dc60d47403e4..8fbafadf1825342b72af2815ee93b1286781be62 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/RelationshipServiceAuthorizationTest.java @@ -76,11 +76,9 @@ public class RelationshipServiceAuthorizationTest extends BaseTest Sample sharedSample; - Sample childSample; + ExternalData sourceDataSet; - Sample parentSample; - - ExternalData dataSet; + ExternalData destinationDataSet; @BeforeClass public void createFixture() throws Exception @@ -89,7 +87,6 @@ public class RelationshipServiceAuthorizationTest extends BaseTest sourceProject = create(aProject().inSpace(sourceSpace)); sourceExperiment = create(anExperiment().inProject(sourceProject)); sourceSample = create(aSample().inExperiment(sourceExperiment)); - dataSet = create(aDataSet().inSample(sourceSample)); destinationSpace = create(aSpace()); destinationProject = create(aProject().inSpace(destinationSpace)); @@ -98,8 +95,8 @@ public class RelationshipServiceAuthorizationTest extends BaseTest sharedSample = create(aSample()); - parentSample = create(aSample().inSpace(sourceSpace)); - childSample = create(aSample().inSpace(destinationSpace).withParent(parentSample)); + sourceDataSet = create(aDataSet().inSample(sourceSample)); + destinationDataSet = create(aDataSet().inSample(destinationSample)); unrelatedAdmin = create(aSpace()); unrelatedObserver = create(aSpace()); @@ -289,6 +286,104 @@ public class RelationshipServiceAuthorizationTest extends BaseTest removeParentFromSample(sourceSpaceRole, destinationSpaceRole, instanceRole); } + @Test(dataProvider = "rolesAllowedToAddContainerToSample", groups = "authorization") + public void addingContainerToSampleIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + addContainerToSample(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesNotAllowedToAddContainerToSample", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void addingContainerToSampleIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + addContainerToSample(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesAllowedToRemoveContainerFromSample", groups = "authorization") + public void removingContainerFromSampleIsAuthorizedFor(RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + removeContainerFromSample(spaceRole, instanceRole); + } + + @Test(dataProvider = "rolesNotAllowedToRemoveContainerFromSample", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void removingContainerFromSampleIsNotAuthorizedFor(RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + removeContainerFromSample(spaceRole, instanceRole); + } + + @Test(dataProvider = "rolesAllowedToAddParentToDataSet", groups = "authorization") + public void addingParentToDataSetIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + addParentToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesNotAllowedToAddParentToDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void addingParentToDataSetIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + addParentToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesAllowedToRemoveParentFromDataSet", groups = "authorization") + public void removingParentFromDataSetIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + removeParentFromDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesNotAllowedToRemoveParentFromDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void removingParentFromDataSetIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + removeParentFromDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesAllowedToAddContainerToDataSet", groups = "authorization") + public void addingContainerToDataSetIsAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + addContainerToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesNotAllowedToAddContainerToDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void addingContainerToDataSetIsNotAuthorizedFor(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + addContainerToDataSet(sourceSpaceRole, destinationSpaceRole, instanceRole); + } + + @Test(dataProvider = "rolesAllowedToRemoveContainerFromDataSet", groups = "authorization") + public void removingContainerFromDataSetIsAuthorizedFor(RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + removeContainerFromDataSet(spaceRole, instanceRole); + } + + @Test(dataProvider = "rolesNotAllowedToRemoveContainerFromDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void removingContainerFromDataSetIsNotAuthorizedFor(RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + removeContainerFromDataSet(spaceRole, instanceRole); + } + void assignExperimentToProject(RoleWithHierarchy sourceSpaceRole, RoleWithHierarchy destinationSpaceRole, RoleWithHierarchy instanceRole) throws Exception @@ -408,7 +503,7 @@ public class RelationshipServiceAuthorizationTest extends BaseTest .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); relationshipService.assignDataSetToExperiment(sessionManager.getSession(session), - pe(dataSet), pe(destinationExperiment)); + pe(sourceDataSet), pe(destinationExperiment)); } void assignDataSetToSample(RoleWithHierarchy sourceSpaceRole, @@ -425,7 +520,7 @@ public class RelationshipServiceAuthorizationTest extends BaseTest .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); relationshipService.assignDataSetToSample(sessionManager.getSession(session), - pe(dataSet), pe(destinationSample)); + pe(sourceDataSet), pe(destinationSample)); } void addParentToSample(RoleWithHierarchy sourceSpaceRole, @@ -458,7 +553,105 @@ public class RelationshipServiceAuthorizationTest extends BaseTest .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); relationshipService.removeParentFromSample(sessionManager.getSession(session), - pe(childSample), pe(parentSample)); + pe(sourceSample), pe(destinationSample)); + } + + void addContainerToSample(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + String session = + create(aSession() + .withSpaceRole(sourceSpaceRole, sourceSpace) + .withSpaceRole(destinationSpaceRole, destinationSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + relationshipService.assignSampleToContainer(sessionManager.getSession(session), + pe(sourceSample), + pe(destinationSample)); + + } + + void removeContainerFromSample(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + String session = + create(aSession() + .withSpaceRole(sourceSpaceRole, sourceSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + relationshipService.removeSampleFromContainer(sessionManager.getSession(session), + pe(this.sourceSample)); + } + + void addParentToDataSet(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + String session = + create(aSession() + .withSpaceRole(sourceSpaceRole, sourceSpace) + .withSpaceRole(destinationSpaceRole, destinationSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + relationshipService.addParentToDataSet(sessionManager.getSession(session), + pe(sourceDataSet), + pe(destinationDataSet)); + + } + + void removeParentFromDataSet(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + String session = + create(aSession() + .withSpaceRole(sourceSpaceRole, sourceSpace) + .withSpaceRole(destinationSpaceRole, destinationSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + relationshipService.removeParentFromDataSet(sessionManager.getSession(session), + pe(sourceDataSet), pe(destinationDataSet)); + } + + void addContainerToDataSet(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy destinationSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + String session = + create(aSession() + .withSpaceRole(sourceSpaceRole, sourceSpace) + .withSpaceRole(destinationSpaceRole, destinationSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + relationshipService.assignDataSetToContainer(sessionManager.getSession(session), + pe(sourceDataSet), + pe(destinationDataSet)); + + } + + void removeContainerFromDataSet(RoleWithHierarchy sourceSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + String session = + create(aSession() + .withSpaceRole(sourceSpaceRole, sourceSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + relationshipService.removeDataSetFromContainer(sessionManager.getSession(session), + pe(this.sourceDataSet)); } GuardedDomain instance = new InstanceDomain("instance"); @@ -625,7 +818,7 @@ public class RelationshipServiceAuthorizationTest extends BaseTest source, destination, instance); } - @DataProvider(name = "rolesAllowedRemoveAddParentFromSample") + @DataProvider(name = "rolesAllowedRemoveParentFromSample") RoleWithHierarchy[][] rolesAllowedToRemoveParentFromSample() { return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer, @@ -639,6 +832,90 @@ public class RelationshipServiceAuthorizationTest extends BaseTest source, destination, instance); } + @DataProvider(name = "rolesAllowedToAddContainerToSample") + RoleWithHierarchy[][] rolesAllowedToAddContainerToSample() + { + return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer, + source, destination, instance); + } + + @DataProvider(name = "rolesNotAllowedToAddContainerToSample") + RoleWithHierarchy[][] rolesNotAllowedToAddContainerToSample() + { + return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer), + source, destination, instance); + } + + @DataProvider(name = "rolesAllowedRemoveContainerFromSample") + RoleWithHierarchy[][] rolesAllowedToRemoveContainerFromSample() + { + return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServerSingle, + source, instance); + } + + @DataProvider(name = "rolesNotAllowedToRemoveContainerFromSample") + RoleWithHierarchy[][] rolesNotAllowedToRemoveContainerFromSample() + { + return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServerSingle), + source, instance); + } + + @DataProvider(name = "rolesAllowedToAddParentToDataSet") + RoleWithHierarchy[][] rolesAllowedToAddParentToDataSet() + { + return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer, + source, destination, instance); + } + + @DataProvider(name = "rolesNotAllowedToAddParentToDataSet") + RoleWithHierarchy[][] rolesNotAllowedToAddParentToDataSet() + { + return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer), + source, destination, instance); + } + + @DataProvider(name = "rolesAllowedRemoveParentFromDataSet") + RoleWithHierarchy[][] rolesAllowedToRemoveParentFromDataSet() + { + return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer, + source, destination, instance); + } + + @DataProvider(name = "rolesNotAllowedToRemoveParentFromDataSet") + RoleWithHierarchy[][] rolesNotAllowedToRemoveParentFromDataSet() + { + return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer), + source, destination, instance); + } + + @DataProvider(name = "rolesAllowedToAddContainerToDataSet") + RoleWithHierarchy[][] rolesAllowedToAddContainerToDataSet() + { + return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServer, + source, destination, instance); + } + + @DataProvider(name = "rolesNotAllowedToAddContainerToDataSet") + RoleWithHierarchy[][] rolesNotAllowedToAddContainerToDataSet() + { + return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServer), + source, destination, instance); + } + + @DataProvider(name = "rolesAllowedRemoveContainerFromDataSet") + RoleWithHierarchy[][] rolesAllowedToRemoveContainerFromDataSet() + { + return RolePermutator.getAcceptedPermutations(spaceAdminOrSpaceEtlServerSingle, + source, instance); + } + + @DataProvider(name = "rolesNotAllowedToRemoveContainerFromDataSet") + RoleWithHierarchy[][] rolesNotAllowedToRemoveContainerFromDataSet() + { + return RolePermutator.getAcceptedPermutations(not(spaceAdminOrSpaceEtlServerSingle), + source, instance); + } + ExperimentPE pe(Experiment experiment) { return daoFactory.getExperimentDAO().tryGetByPermID(experiment.getPermId()); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java index 2466c171dec56e1c109b12ace8a164255cab1bc1..873aee7e16df437e0219fa0c7cfb19c6729d0070 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetContainmentTest.java @@ -16,20 +16,30 @@ package ch.systemsx.cisd.openbis.systemtest; +import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.not; +import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.rule; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; import ch.systemsx.cisd.openbis.systemtest.base.BaseTest; +import ch.systemsx.cisd.openbis.systemtest.base.auth.AuthorizationRule; +import ch.systemsx.cisd.openbis.systemtest.base.auth.GuardedDomain; +import ch.systemsx.cisd.openbis.systemtest.base.auth.InstanceDomain; +import ch.systemsx.cisd.openbis.systemtest.base.auth.RolePermutator; +import ch.systemsx.cisd.openbis.systemtest.base.auth.SpaceDomain; /** * @author anttil @@ -128,6 +138,85 @@ public class UpdateDataSetContainmentTest extends BaseTest } + Space unrelatedAdmin; + + Space unrelatedObserver; + + Space unrelatedNone; + + @Test(dataProvider = "rolesAllowedToAddContainerToDataSet", groups = "authorization") + public void addingContainerToDataSetIsAllowedFor( + RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData container = create(aDataSet().inSample(sample)); + ExternalData component = create(aDataSet().inSample(sample)); + String user = + create(aSession() + .withSpaceRole(spaceRole, sample.getSpace()) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(container).withComponent(component).as(user)); + } + + @Test(dataProvider = "rolesNotAllowedToAddContainerToDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void addingContainerToDataSetNotIsAllowedFor( + RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData container = create(aDataSet().inSample(sample)); + ExternalData component = create(aDataSet().inSample(sample)); + String user = + create(aSession() + .withSpaceRole(spaceRole, sample.getSpace()) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(container).withComponent(component).as(user)); + } + + @Test(dataProvider = "rolesAllowedToAddContainerToDataSet", groups = "authorization") + public void removingContainerFromDataSetIsAllowedFor( + RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData component = create(aDataSet().inSample(sample)); + ExternalData container = + create(aDataSet().inSample(sample).asContainer().withComponent(component)); + + String user = + create(aSession() + .withSpaceRole(spaceRole, sample.getSpace()) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(container).withComponents().as(user)); + } + + @Test(dataProvider = "rolesNotAllowedToAddContainerToDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void removingContainerFromDataSetNotIsAllowedFor( + RoleWithHierarchy spaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData component = create(aDataSet().inSample(sample)); + ExternalData container = + create(aDataSet().inSample(sample).asContainer().withComponent(component)); + String user = + create(aSession() + .withSpaceRole(spaceRole, sample.getSpace()) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(container).withComponents().as(user)); + } + @BeforeClass void createFixture() throws Exception { @@ -135,5 +224,37 @@ public class UpdateDataSetContainmentTest extends BaseTest Project project = create(aProject().inSpace(space)); Experiment experiment = create(anExperiment().inProject(project)); sample = create(aSample().inExperiment(experiment)); + + unrelatedAdmin = create(aSpace()); + unrelatedObserver = create(aSpace()); + unrelatedNone = create(aSpace()); + } + + GuardedDomain spaceDomain; + + GuardedDomain instance; + + AuthorizationRule addParentToSampleRule; + + @BeforeClass + void createAuthorizationRules() + { + instance = new InstanceDomain("instance"); + spaceDomain = new SpaceDomain("space", instance); + + addParentToSampleRule = rule(spaceDomain, RoleWithHierarchy.SPACE_POWER_USER); + } + + @DataProvider + Object[][] rolesAllowedToAddContainerToDataSet() + { + return RolePermutator.getAcceptedPermutations(addParentToSampleRule, spaceDomain, instance); + } + + @DataProvider + Object[][] rolesNotAllowedToAddContainerToDataSet() + { + return RolePermutator.getAcceptedPermutations(not(addParentToSampleRule), spaceDomain, + instance); } } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java index 8bab6547df57099101e2d4b5f337598ddb0e4de1..93d6a3ecebe7e189bdc46d05614a2a8aaa5605df 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateDataSetParentsTest.java @@ -16,19 +16,31 @@ package ch.systemsx.cisd.openbis.systemtest; +import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.and; +import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.not; +import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.or; +import static ch.systemsx.cisd.openbis.systemtest.base.auth.RuleBuilder.rule; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import ch.systemsx.cisd.common.exceptions.AuthorizationFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; import ch.systemsx.cisd.openbis.systemtest.base.BaseTest; +import ch.systemsx.cisd.openbis.systemtest.base.auth.AuthorizationRule; +import ch.systemsx.cisd.openbis.systemtest.base.auth.GuardedDomain; +import ch.systemsx.cisd.openbis.systemtest.base.auth.InstanceDomain; +import ch.systemsx.cisd.openbis.systemtest.base.auth.RolePermutator; +import ch.systemsx.cisd.openbis.systemtest.base.auth.SpaceDomain; /** * @author anttil @@ -126,18 +138,110 @@ public class UpdateDataSetParentsTest extends BaseTest @Test public void parentCanBeInDifferentSpaceThanChild() throws Exception { - Space parentSpace = create(aSpace()); - Project parentProject = create(aProject().inSpace(parentSpace)); - Experiment parentExperiment = create(anExperiment().inProject(parentProject)); - Sample parentSample = create(aSample().inExperiment(parentExperiment)); ExternalData parent = create(aDataSet().inSample(parentSample)); - ExternalData child = create(aDataSet().inSample(sample)); + ExternalData child = create(aDataSet().inSample(childSample)); perform(anUpdateOf(child).withParent(parent)); assertThat(serverSays(child).getParents(), containsExactly(parent)); } + Sample childSample; + + Sample parentSample; + + Space childSpace; + + Space parentSpace; + + Space unrelatedAdmin; + + Space unrelatedObserver; + + Space unrelatedNone; + + @Test(dataProvider = "rolesAllowedToAddParentToDataSet", groups = "authorization") + public void addingParentToDataSetIsAllowedFor( + RoleWithHierarchy childSpaceRole, + RoleWithHierarchy parentSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData parentToBe = create(aDataSet().inSample(parentSample)); + ExternalData childToBe = create(aDataSet().inSample(childSample)); + String user = + create(aSession() + .withSpaceRole(childSpaceRole, childSpace) + .withSpaceRole(parentSpaceRole, parentSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(childToBe).withParent(parentToBe).as(user)); + } + + @Test(dataProvider = "rolesNotAllowedToAddParentToDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void addingParentToDataSetNotIsAllowedFor( + RoleWithHierarchy childSpaceRole, + RoleWithHierarchy parentSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData parentToBe = create(aDataSet().inSample(parentSample)); + ExternalData childToBe = create(aDataSet().inSample(childSample)); + String user = + create(aSession() + .withSpaceRole(childSpaceRole, childSpace) + .withSpaceRole(parentSpaceRole, parentSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(childToBe).withParent(parentToBe).as(user)); + } + + @Test(dataProvider = "rolesAllowedToRemoveParentFromDataSet", groups = "authorization") + public void removingParentFromDataSetIsAllowedFor( + RoleWithHierarchy childSpaceRole, + RoleWithHierarchy parentSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData parent1 = create(aDataSet().inSample(parentSample)); + ExternalData parent2 = create(aDataSet().inSample(parentSample)); + ExternalData child = create(aDataSet().inSample(childSample).withParents(parent1, parent2)); + + String user = + create(aSession() + .withSpaceRole(childSpaceRole, childSpace) + .withSpaceRole(parentSpaceRole, parentSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(child).withParent(parent1).as(user)); + } + + @Test(dataProvider = "rolesNotAllowedToRemoveParentFromDataSet", expectedExceptions = + { AuthorizationFailureException.class }, groups = "authorization") + public void removingParentFromDataSetNotIsAllowedFor( + RoleWithHierarchy childSpaceRole, + RoleWithHierarchy parentSpaceRole, + RoleWithHierarchy instanceRole) throws Exception + { + ExternalData parent1 = create(aDataSet().inSample(parentSample)); + ExternalData parent2 = create(aDataSet().inSample(parentSample)); + ExternalData child = create(aDataSet().inSample(childSample).withParents(parent1, parent2)); + + String user = + create(aSession() + .withSpaceRole(childSpaceRole, childSpace) + .withSpaceRole(parentSpaceRole, parentSpace) + .withInstanceRole(instanceRole) + .withSpaceRole(RoleWithHierarchy.SPACE_ADMIN, unrelatedAdmin) + .withSpaceRole(RoleWithHierarchy.SPACE_OBSERVER, unrelatedObserver)); + + perform(anUpdateOf(child).withParent(parent1).as(user)); + } + @BeforeClass void createFixture() throws Exception { @@ -146,5 +250,73 @@ public class UpdateDataSetParentsTest extends BaseTest Experiment experiment = create(anExperiment().inProject(project)); sample = create(aSample().inExperiment(experiment)); + unrelatedAdmin = create(aSpace()); + unrelatedObserver = create(aSpace()); + unrelatedNone = create(aSpace()); + + childSpace = create(aSpace()); + parentSpace = create(aSpace()); + Project childProject = create(aProject().inSpace(childSpace)); + Project parentProject = create(aProject().inSpace(parentSpace)); + Experiment childExperiment = create(anExperiment().inProject(childProject)); + Experiment parentExperiment = create(anExperiment().inProject(parentProject)); + childSample = create(aSample().inExperiment(childExperiment)); + parentSample = create(aSample().inExperiment(parentExperiment)); + + } + + GuardedDomain childSpaceDomain; + + GuardedDomain parentSpaceDomain; + + GuardedDomain instance; + + AuthorizationRule updateParentsOfDataSetRule; + + AuthorizationRule removeParentFromDataSetRule; + + @BeforeClass + void createAuthorizationRules() + { + instance = new InstanceDomain("instance"); + childSpaceDomain = new SpaceDomain("child", instance); + parentSpaceDomain = new SpaceDomain("parent", instance); + + updateParentsOfDataSetRule = + and( + rule(childSpaceDomain, RoleWithHierarchy.SPACE_POWER_USER), + or( + rule(parentSpaceDomain, RoleWithHierarchy.SPACE_POWER_USER), + rule(parentSpaceDomain, RoleWithHierarchy.SPACE_ETL_SERVER) + ) + ); + } + + @DataProvider + Object[][] rolesAllowedToAddParentToDataSet() + { + return RolePermutator.getAcceptedPermutations(updateParentsOfDataSetRule, childSpaceDomain, + parentSpaceDomain, instance); + } + + @DataProvider + Object[][] rolesNotAllowedToAddParentToDataSet() + { + return RolePermutator.getAcceptedPermutations(not(updateParentsOfDataSetRule), + childSpaceDomain, parentSpaceDomain, instance); + } + + @DataProvider + Object[][] rolesAllowedToRemoveParentFromDataSet() + { + return RolePermutator.getAcceptedPermutations(updateParentsOfDataSetRule, childSpaceDomain, + parentSpaceDomain, instance); + } + + @DataProvider + Object[][] rolesNotAllowedToRemoveParentFromDataSet() + { + return RolePermutator.getAcceptedPermutations(not(updateParentsOfDataSetRule), + childSpaceDomain, parentSpaceDomain, instance); } } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java index 88f5b81d058ff9ec3365a31dcea6768925376c3d..602bd0332ab5a92808c487646b1023c8bad63bd9 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/UpdateSampleParentsTest.java @@ -140,6 +140,16 @@ public class UpdateSampleParentsTest extends BaseTest perform(anUpdateOf(child).toHaveParent(parent)); } + @Test(expectedExceptions = + { UserFailureException.class }) + public void childCannotBeShared() throws Exception + { + Sample parent = create(aSample().inSpace(space)); + Sample child = create(aSample()); + + perform(anUpdateOf(child).toHaveParent(parent)); + } + Space unrelatedAdmin; Space unrelatedObserver; diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java index 28bff546d9b52dd471fc94967749efb5ef2c4650..ef6714871a26b531fece48d9b3da5bc9a0eac8c0 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/base/RelationshipServiceStub.java @@ -100,4 +100,24 @@ public class RelationshipServiceStub implements IRelationshipService public void removeSampleFromContainer(IAuthSession session, SamplePE sample) { } + + @Override + public void addParentToDataSet(IAuthSession session, DataPE data, DataPE parent) + { + } + + @Override + public void removeParentFromDataSet(IAuthSession session, DataPE data, DataPE parent) + { + } + + @Override + public void assignDataSetToContainer(IAuthSession session, DataPE data, DataPE container) + { + } + + @Override + public void removeDataSetFromContainer(IAuthSession session, DataPE sample) + { + } }