diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/roleassignment/CreateRoleAssignmentExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/roleassignment/CreateRoleAssignmentExecutor.java index d6e29950ccfdb7afca50f3c81c88428924fd2cc6..b77f0d89b70548793503a5479aea0ede8bdb4e94 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/roleassignment/CreateRoleAssignmentExecutor.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/asapi/v3/executor/roleassignment/CreateRoleAssignmentExecutor.java @@ -28,6 +28,7 @@ import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Component; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.IObjectId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.id.ObjectIdentifier; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.create.RoleAssignmentCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.id.RoleAssignmentTechId; import ch.ethz.sis.openbis.generic.server.asapi.v3.context.IProgress; @@ -41,6 +42,8 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.server.business.bo.DataAccessExceptionTranslator; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode; +import ch.systemsx.cisd.openbis.generic.shared.dto.AuthorizationGroupPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE; import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE; import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE; import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE; @@ -76,7 +79,46 @@ public class CreateRoleAssignmentExecutor @Override protected IObjectId getId(RoleAssignmentPE entity) { - return new RoleAssignmentTechId(entity.getId()); + // Note, we can not return an instance of RoleAssignmentId because entity.getId() == null + return new ObjectIdentifier(renderAssignment(entity)) + { + private static final long serialVersionUID = 1L; + }; + } + + private String renderAssignment(RoleAssignmentPE entity) + { + StringBuilder builder = new StringBuilder(); + SpacePE space = entity.getSpace(); + ProjectPE project = entity.getProject(); + if (space != null) + { + builder.append("SPACE_"); + } else + { + builder.append(project != null ? "PROJECT_" : "INSTANCE_"); + } + builder.append(entity.getRole()); + if (space != null) + { + builder.append(" [Space: ").append(space.getCode()).append("]"); + } else if (project != null) + { + builder.append(" [Project: ").append(project.getIdentifier()).append("]"); + } + PersonPE user = entity.getPerson(); + if (user != null) + { + builder.append(" for user ").append(user.getUserId()); + } else + { + AuthorizationGroupPE group = entity.getAuthorizationGroup(); + if (group != null) + { + builder.append(" for authorization group ").append(group.getCode()); + } + } + return builder.toString(); } @Override diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java index 7c82fb8f3f3ec850560de30dd8eb60e1d4f6659c..a63c5a1475aba475f1a79a035ee46c022ca96501 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/AbstractTest.java @@ -1177,6 +1177,16 @@ public class AbstractTest extends SystemTestCase assertCollectionContainsOnly(actualIds, expectedIds.toArray(new Long[] {})); } + protected Object[][] createTestUsersProvider(String... users) + { + Object[][] objects = new Object[users.length][]; + for (int i = 0; i < users.length; i++) + { + objects[i] = new Object[] {users[i]}; + } + return objects; + } + protected static String patternContains(String... parts) { StringBuilder pattern = new StringBuilder(); diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateRoleAssignmentTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateRoleAssignmentTest.java index 24e73701d452b4668f0deb956e620cd7be974299..d27c69afd0ed715071de83f8c6eb3859708faceb 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateRoleAssignmentTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/CreateRoleAssignmentTest.java @@ -21,9 +21,11 @@ import static org.testng.Assert.assertEquals; import java.util.Arrays; import java.util.List; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.id.PersonPermId; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.project.id.ProjectIdentifier; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleLevel; @@ -31,6 +33,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.create.RoleAssign import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.fetchoptions.RoleAssignmentFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.id.RoleAssignmentTechId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId; +import ch.systemsx.cisd.common.action.IDelegatedAction; /** * @@ -87,4 +90,115 @@ public class CreateRoleAssignmentTest extends AbstractTest assertEquals(roleAssignment.getSpace().getCode(), "CISD"); assertEquals(roleAssignment.getProject(), null); } + + @Test(dataProvider = "usersNotAllowedToCreateInstanceRoleAssignment") + public void testCreateInstanceRoleAssignmentWithUserCausingAuthorizationFailure(final String user) + { + assertAnyAuthorizationException(new IDelegatedAction() + { + @Override + public void execute() + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentCreation creation = new RoleAssignmentCreation(); + creation.setRole(Role.ADMIN); + creation.setUserId(new PersonPermId(TEST_OBSERVER_CISD)); + v3api.createRoleAssignments(sessionToken, Arrays.asList(creation)); + } + }); + } + + @DataProvider + Object[][] usersNotAllowedToCreateInstanceRoleAssignment() + { + return createTestUsersProvider(TEST_GROUP_ADMIN, TEST_INSTANCE_ETLSERVER, TEST_GROUP_OBSERVER, + TEST_GROUP_POWERUSER, TEST_INSTANCE_OBSERVER, TEST_OBSERVER_CISD, TEST_POWER_USER_CISD, + TEST_SPACE_USER); + } + + @Test(dataProvider = "usersNotAllowedToCreateRoleAssignmentForSpaceCISD") + public void testCreateSpaceRoleAssignmentWithUserCausingAuthorizationFailure(final String user) + { + assertAnyAuthorizationException(new IDelegatedAction() + { + @Override + public void execute() + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentCreation creation = new RoleAssignmentCreation(); + creation.setRole(Role.USER); + creation.setSpaceId(new SpacePermId("CISD")); + creation.setUserId(new PersonPermId(TEST_INSTANCE_ETLSERVER)); + v3api.createRoleAssignments(sessionToken, Arrays.asList(creation)); + } + }); + } + + @DataProvider + Object[][] usersNotAllowedToCreateRoleAssignmentForSpaceCISD() + { + return createTestUsersProvider(TEST_GROUP_ADMIN, TEST_INSTANCE_ETLSERVER, TEST_GROUP_OBSERVER, + TEST_GROUP_POWERUSER, TEST_INSTANCE_OBSERVER, TEST_OBSERVER_CISD, TEST_POWER_USER_CISD, + TEST_SPACE_USER); + } + + @Test(dataProvider = "usersAllowedToCreateRoleAssignmentForSpaceCISD") + public void testCreateSpaceRoleAssignmentWithUser(final String user) + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentCreation creation = new RoleAssignmentCreation(); + creation.setRole(Role.USER); + creation.setSpaceId(new SpacePermId("CISD")); + creation.setUserId(new PersonPermId(TEST_INSTANCE_ETLSERVER)); + v3api.createRoleAssignments(sessionToken, Arrays.asList(creation)); + } + + @DataProvider + Object[][] usersAllowedToCreateRoleAssignmentForSpaceCISD() + { + return createTestUsersProvider(TEST_USER, TEST_ROLE_V3); + } + + @Test(dataProvider = "usersNotAllowedToCreateRoleAssignmentForProjectTEST_PROJECT") + public void testCreateProjectRoleAssignmentWithUserCausingAuthorizationFailure(final String user) + { + assertAnyAuthorizationException(new IDelegatedAction() + { + @Override + public void execute() + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentCreation creation = new RoleAssignmentCreation(); + creation.setRole(Role.USER); + creation.setProjectId(new ProjectIdentifier("/TEST-SPACE/TEST-PROJECT")); + creation.setUserId(new PersonPermId(TEST_INSTANCE_ETLSERVER)); + v3api.createRoleAssignments(sessionToken, Arrays.asList(creation)); + } + }); + } + + @DataProvider + Object[][] usersNotAllowedToCreateRoleAssignmentForProjectTEST_PROJECT() + { + return createTestUsersProvider(TEST_GROUP_ADMIN, TEST_INSTANCE_ETLSERVER, TEST_GROUP_OBSERVER, + TEST_GROUP_POWERUSER, TEST_INSTANCE_OBSERVER, TEST_OBSERVER_CISD, TEST_POWER_USER_CISD); + } + + @Test(dataProvider = "usersAllowedToCreateRoleAssignmentForProjectTEST_PROJECT") + public void testCreateProjectRoleAssignmentWithUser(final String user) + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentCreation creation = new RoleAssignmentCreation(); + creation.setRole(Role.USER); + creation.setProjectId(new ProjectIdentifier("/TEST-SPACE/TEST-PROJECT")); + creation.setUserId(new PersonPermId(TEST_INSTANCE_ETLSERVER)); + v3api.createRoleAssignments(sessionToken, Arrays.asList(creation)); + } + + @DataProvider + Object[][] usersAllowedToCreateRoleAssignmentForProjectTEST_PROJECT() + { + return createTestUsersProvider(TEST_USER, TEST_SPACE_USER); + } + } diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DeleteRoleAssignmentTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DeleteRoleAssignmentTest.java index e776450f2f46c57c4e2ff5fae23adc9bb9254e57..3e6d6730eccdd403972ba30973b53ff4081513ed 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DeleteRoleAssignmentTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/DeleteRoleAssignmentTest.java @@ -17,15 +17,15 @@ package ch.ethz.sis.openbis.systemtest.asapi.v3; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; import java.util.Arrays; import java.util.List; import java.util.Map; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.AuthorizationGroup; -import ch.ethz.sis.openbis.generic.asapi.v3.dto.authorizationgroup.id.IAuthorizationGroupId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.person.id.PersonPermId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.Role; import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.RoleAssignment; @@ -36,6 +36,8 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.id.IRoleAssignmen import ch.ethz.sis.openbis.generic.asapi.v3.dto.roleassignment.id.RoleAssignmentTechId; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create.SpaceCreation; import ch.ethz.sis.openbis.generic.asapi.v3.dto.space.id.SpacePermId; +import ch.systemsx.cisd.common.action.IDelegatedAction; +import ch.systemsx.cisd.common.exceptions.UserFailureException; /** * @@ -61,10 +63,10 @@ public class DeleteRoleAssignmentTest extends AbstractTest fetchOptions.withSpace(); RoleAssignment assignment = v3api.getRoleAssignments(sessionToken, assignments, fetchOptions).get(assignments.get(0)); assertEquals(assignment.getSpace().getCode(), spaceCreation.getCode()); - - // When RoleAssignmentDeletionOptions deletionOptions = new RoleAssignmentDeletionOptions(); deletionOptions.setReason("test"); + + // When v3api.deleteRoleAssignments(sessionToken, assignments, deletionOptions); // Then @@ -72,4 +74,133 @@ public class DeleteRoleAssignmentTest extends AbstractTest assertEquals(map.toString(), "{}"); v3api.logout(sessionToken); } + + @Test + public void testDeleteSpaceAdminRoleAssignmentBySameUser() + { + // Given + String sessionToken = v3api.login(TEST_ROLE_V3, PASSWORD); + RoleAssignmentDeletionOptions deletionOptions = new RoleAssignmentDeletionOptions(); + deletionOptions.setReason("testing"); + + try + { + // Then + // delete role assignment: user: test_v3, space: CISD, role: ADMIN + v3api.deleteRoleAssignments(sessionToken, Arrays.asList(new RoleAssignmentTechId(11L)), deletionOptions); + fail("UserFailureException expected"); + } catch (UserFailureException e) + { + // When + assertEquals(e.getMessage(), "For safety reason you cannot give away your own space admin power. " + + "Ask instance admin to do that for you. (Context: [])"); + } + } + + @Test(dataProvider = "usersNotAllowedToDeleteInstanceRoleAssignment") + public void testDeleteInstanceRoleAssignmentWithUserCausingAuthorizationFailure(final String user) + { + assertAnyAuthorizationException(new IDelegatedAction() + { + @Override + public void execute() + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentDeletionOptions deletionOptions = new RoleAssignmentDeletionOptions(); + deletionOptions.setReason("testing"); + // delete role assignment: user: test, role: ADMIN + v3api.deleteRoleAssignments(sessionToken, Arrays.asList(new RoleAssignmentTechId(1L)), deletionOptions); + } + }); + } + + @DataProvider + Object[][] usersNotAllowedToDeleteInstanceRoleAssignment() + { + return createTestUsersProvider(TEST_GROUP_ADMIN, TEST_INSTANCE_ETLSERVER, TEST_GROUP_OBSERVER, + TEST_GROUP_POWERUSER, TEST_INSTANCE_OBSERVER, TEST_OBSERVER_CISD, TEST_POWER_USER_CISD, + TEST_SPACE_USER); + } + + @Test(dataProvider = "usersNotAllowedToDeleteRoleAssignmentForSpaceCISD") + public void testDeleteSpaceRoleAssignmentWithUserCausingAuthorizationFailure(final String user) + { + assertAnyAuthorizationException(new IDelegatedAction() + { + @Override + public void execute() + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentDeletionOptions deletionOptions = new RoleAssignmentDeletionOptions(); + deletionOptions.setReason("testing"); + // delete role assignment: user: test_role, space: CISD, role: POWER_USER + v3api.deleteRoleAssignments(sessionToken, Arrays.asList(new RoleAssignmentTechId(8L)), deletionOptions); + } + }); + } + + @DataProvider + Object[][] usersNotAllowedToDeleteRoleAssignmentForSpaceCISD() + { + return createTestUsersProvider(TEST_GROUP_ADMIN, TEST_INSTANCE_ETLSERVER, TEST_GROUP_OBSERVER, + TEST_GROUP_POWERUSER, TEST_INSTANCE_OBSERVER, TEST_OBSERVER_CISD, TEST_POWER_USER_CISD, + TEST_SPACE_USER); + } + + @Test(dataProvider = "usersAllowedToDeleteRoleAssignmentForSpaceCISD") + public void testDeleteSpaceRoleAssignmentWithUser(final String user) + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentDeletionOptions deletionOptions = new RoleAssignmentDeletionOptions(); + deletionOptions.setReason("testing"); + // delete role assignment: user: test_role, space: CISD, role: POWER_USER + v3api.deleteRoleAssignments(sessionToken, Arrays.asList(new RoleAssignmentTechId(8L)), deletionOptions); + } + + @DataProvider + Object[][] usersAllowedToDeleteRoleAssignmentForSpaceCISD() + { + return createTestUsersProvider(TEST_USER, TEST_ROLE_V3); + } + + @Test(dataProvider = "usersNotAllowedToDeleteRoleAssignmentForProjectTEST_PROJECT") + public void testDeleteProjectRoleAssignmentWithUserCausingAuthorizationFailure(final String user) + { + assertAnyAuthorizationException(new IDelegatedAction() + { + @Override + public void execute() + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentDeletionOptions deletionOptions = new RoleAssignmentDeletionOptions(); + deletionOptions.setReason("testing"); + // delete role assignment: user: test_project_pa_on, project: /TEST-SPACE/TEST-PROJECT, role: ADMIN + v3api.deleteRoleAssignments(sessionToken, Arrays.asList(new RoleAssignmentTechId(20L)), deletionOptions); + } + }); + } + + @DataProvider + Object[][] usersNotAllowedToDeleteRoleAssignmentForProjectTEST_PROJECT() + { + return createTestUsersProvider(TEST_GROUP_ADMIN, TEST_INSTANCE_ETLSERVER, TEST_GROUP_OBSERVER, + TEST_GROUP_POWERUSER, TEST_INSTANCE_OBSERVER, TEST_OBSERVER_CISD, TEST_POWER_USER_CISD); + } + + @Test(dataProvider = "usersAllowedToDeleteRoleAssignmentForProjectTEST_PROJECT") + public void testDeleteProjectRoleAssignmentWithUser(final String user) + { + String sessionToken = v3api.login(user, PASSWORD); + RoleAssignmentDeletionOptions deletionOptions = new RoleAssignmentDeletionOptions(); + deletionOptions.setReason("testing"); + // delete role assignment: user: test_project_pa_on, project: /TEST-SPACE/TEST-PROJECT, role: ADMIN + v3api.deleteRoleAssignments(sessionToken, Arrays.asList(new RoleAssignmentTechId(20L)), deletionOptions); + } + + @DataProvider + Object[][] usersAllowedToDeleteRoleAssignmentForProjectTEST_PROJECT() + { + return createTestUsersProvider(TEST_USER, TEST_SPACE_USER); + } + } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java index a2ead9a8af5eae9f012cbbf9c1df363baa462822..5f608a22c4423eca49d3826f514cb56025ac6b7a 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java @@ -95,6 +95,8 @@ public abstract class SystemTestCase extends AbstractTransactionalTestNGSpringCo protected static final String TEST_POWER_USER_CISD = "test_role"; + protected static final String TEST_INSTANCE_ETLSERVER = "etlserver"; + protected static final String TEST_GROUP_OBSERVER = "observer"; protected static final String TEST_INSTANCE_OBSERVER = "instance_observer";