diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMap.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMap.java index 072ab612e4ffc946b6d60a7f8cd5663ac8ae3810..6642806d5e96f099da13b2cdaa5feadeecb58aec 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMap.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMap.java @@ -87,53 +87,106 @@ class CapabilityMap { continue; } - final String[] splitted = StringUtils.split(trimmed, " \t:"); - if (splitted.length != 2) + String[] terms = StringUtils.split(trimmed, ';'); + String firstTerm = terms[0].trim(); + + final String[] firstTermSplitted = StringUtils.split(firstTerm, " \t:", 2); + if (firstTermSplitted.length != 2) { - operationLog.warn(String.format("Ignoring mal-formed line '%s' in %s.", trimmed, - filePath)); + logWarning(line, filePath, null); continue; } - final String capabilityName = splitted[0]; - final String roleNames = splitted[1]; - final String[] roleNameArray = StringUtils.split(roleNames, ","); - for (String roleName : roleNameArray) + final String capabilityName = firstTermSplitted[0].toUpperCase(); + if (firstTermSplitted[1].contains("=")) { - try + addRolesForParameter(capabilityName, firstTermSplitted[1], trimmed, filePath); + } else + { + final String roleNames = firstTermSplitted[1]; + addRoles(capabilityName, roleNames, trimmed, filePath); + } + for (int i = 1; i < terms.length; i++) + { + addRolesForParameter(capabilityName, terms[i].trim(), trimmed, filePath); + } + } + } + + private void addRolesForParameter(String capabilityName, String parameterTerm, String line, String filePath) + { + int indexOfEqual = parameterTerm.indexOf('='); + if (indexOfEqual < 0) + { + logWarning(line, filePath, "missing '='"); + return; + } + String parameterName = parameterTerm.substring(0, indexOfEqual).trim().toUpperCase(); + if (StringUtils.isBlank(parameterName)) + { + logWarning(line, filePath, "parameter name not specified"); + return; + } + String roleNames = parameterTerm.substring(indexOfEqual + 1).trim(); + addRoles(capabilityName + ":" + parameterName, roleNames, line, filePath); + } + + private void addRoles(String capabilityName, String roleNames, String line, String filePath) + { + final String[] roleNameArray = StringUtils.split(roleNames, ","); + for (String roleName : roleNameArray) + { + roleName = roleName.trim().toUpperCase(); + try + { + final RoleWithHierarchy role = RoleWithHierarchy.valueOf(roleName); + Collection<RoleWithHierarchy> roles = capMap.get(capabilityName); + if (roles == null) { - final RoleWithHierarchy role = RoleWithHierarchy.valueOf(roleName); - Collection<RoleWithHierarchy> roles = capMap.get(capabilityName); - if (roles == null) - { - roles = new HashSet<RoleWithHierarchy>(); - capMap.put(capabilityName, roles); - } - roles.add(role); + roles = new HashSet<RoleWithHierarchy>(); + capMap.put(capabilityName, roles); + } + roles.add(role); - if (operationLog.isDebugEnabled()) - { - operationLog.debug(String - .format("Add to map: '%s' -> %s", capabilityName, role)); - } - } catch (IllegalArgumentException ex) + if (operationLog.isDebugEnabled()) { - operationLog.warn(String.format( - "Ignoring mal-formed line '%s' in %s [role '%s' doesn't exist].", - trimmed, - filePath, roleName)); + operationLog.debug(String + .format("Add to map: '%s' -> %s", capabilityName, role)); } + } catch (IllegalArgumentException ex) + { + logWarning(line, filePath, "role '" + roleName + "' doesn't exist"); } } } + + private void logWarning(String line, String filePath, String messageOrNull) + { + String msg = String.format( + "Ignoring mal-formed line '%s' in %s", + line, filePath); + if (messageOrNull == null) + { + msg += "."; + } else + { + msg += " [" + messageOrNull + "]."; + } + operationLog.warn(msg); + + } - Collection<RoleWithHierarchy> tryGetRoles(Method m) + Collection<RoleWithHierarchy> tryGetRoles(Method m, String argumentNameOrNull) { final Capability cap = m.getAnnotation(Capability.class); if (cap == null) { return null; } - final String capabilityName = cap.value().toUpperCase(); + String capabilityName = cap.value().toUpperCase(); + if (StringUtils.isNotBlank(argumentNameOrNull)) + { + capabilityName += ":" + argumentNameOrNull.toUpperCase(); + } final Collection<RoleWithHierarchy> rolesOrNull = capMap.get(capabilityName); if (operationLog.isDebugEnabled()) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java index 25cd3c59288069b2e778a6beb926a0ee0261ce4e..7f8f49af3cae6196af73a9165cfffba275fa07b3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java @@ -19,7 +19,9 @@ package ch.systemsx.cisd.openbis.generic.server.authorization; import java.io.File; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; @@ -73,6 +75,8 @@ public final class DefaultAccessController implements IAccessController private final Map<Method, Set<RoleWithHierarchy>> methodRolesCache = new HashMap<Method, Set<RoleWithHierarchy>>(); + private final Map<Method, Map<String, Set<RoleWithHierarchy>>> argumentRolesCache = new HashMap<>(); + private final CapabilityMap capabilities = new CapabilityMap(new File("etc/capabilities")); private PredicateExecutor predicateExecutor; @@ -111,38 +115,6 @@ public final class DefaultAccessController implements IAccessController } } - private Set<RoleWithHierarchy> getMethodRoles(final Method method) - { - synchronized (methodRolesCache) - { - Set<RoleWithHierarchy> roles = methodRolesCache.get(method); - if (roles == null) - { - roles = new LinkedHashSet<RoleWithHierarchy>(); - final Collection<RoleWithHierarchy> rootRoles = capabilities.tryGetRoles(method); - if (rootRoles != null) - { - for (RoleWithHierarchy role : rootRoles) - { - roles.addAll(role.getRoles()); - } - } else - { - final RolesAllowed rolesAllowed = method.getAnnotation(RolesAllowed.class); - if (rolesAllowed != null) - { - for (RoleWithHierarchy role : rolesAllowed.value()) - { - roles.addAll(role.getRoles()); - } - } - } - methodRolesCache.put(method, roles); - } - return roles; - } - } - @Override public final Status isAuthorized(final IAuthSession session, final Method method, final Argument<?>[] arguments) throws UserFailureException @@ -172,7 +144,7 @@ public final class DefaultAccessController implements IAccessController { for (final Argument<?> argument : arguments) { - Set<RoleWithHierarchy> argumentRoles = getArgumentRoles(methodRoles, argument); + Set<RoleWithHierarchy> argumentRoles = getArgumentRoles(method, argument, methodRoles); List<RoleWithIdentifier> relevantRoles = getRelevantRoles(userRoles, argumentRoles); status = checkNotEmpty(relevantRoles, argumentRoles, session); if (status.isOK()) @@ -195,21 +167,90 @@ public final class DefaultAccessController implements IAccessController } } - private Set<RoleWithHierarchy> getArgumentRoles(final Set<RoleWithHierarchy> methodRoles, final Argument<?> argument) + private Set<RoleWithHierarchy> getMethodRoles(final Method method) + { + synchronized (methodRolesCache) + { + Set<RoleWithHierarchy> roles = methodRolesCache.get(method); + if (roles == null) + { + roles = new LinkedHashSet<RoleWithHierarchy>(); + for (RoleWithHierarchy role : getRootRoles(method)) + { + roles.addAll(role.getRoles()); + } + methodRolesCache.put(method, roles); + } + return roles; + } + } + + private Collection<RoleWithHierarchy> getRootRoles(final Method method) + { + Collection<RoleWithHierarchy> rootRoles = capabilities.tryGetRoles(method, null); + if (rootRoles == null) + { + final RolesAllowed rolesAllowed = method.getAnnotation(RolesAllowed.class); + if (rolesAllowed != null) + { + rootRoles = Arrays.asList(rolesAllowed.value()); + } else + { + rootRoles = Collections.emptyList(); + } + } + return rootRoles; + } + + private Set<RoleWithHierarchy> getArgumentRoles(Method method, Argument<?> argument, + Set<RoleWithHierarchy> defaultRoles) + { + synchronized (argumentRolesCache) + { + AuthorizationGuard predicateCandidate = argument.getPredicateCandidate(); + if (predicateCandidate == null) + { + return defaultRoles; + } + String name = predicateCandidate.name(); + Map<String, Set<RoleWithHierarchy>> map = argumentRolesCache.get(method); + if (map == null) + { + map = new HashMap<>(); + argumentRolesCache.put(method, map); + } + Set<RoleWithHierarchy> roles = map.get(name); + if (roles == null) + { + roles = new LinkedHashSet<>(); + for (RoleWithHierarchy role : getRootRoles(method, predicateCandidate, defaultRoles)) + { + roles.addAll(role.getRoles()); + } + map.put(name, Collections.unmodifiableSet(roles)); + } + return roles; + } + } + + private Collection<RoleWithHierarchy> getRootRoles(Method method, AuthorizationGuard predicateCandidate, + Set<RoleWithHierarchy> defaultRoles) { - Set<RoleWithHierarchy> argumentRoles = methodRoles; - AuthorizationGuard predicateCandidate = argument.getPredicateCandidate(); - if (predicateCandidate != null && predicateCandidate.rolesAllowed().length > 0) + Collection<RoleWithHierarchy> roles = capabilities.tryGetRoles(method, predicateCandidate.name()); + if (roles == null) { RoleWithHierarchy[] rolesAllowed = predicateCandidate.rolesAllowed(); - argumentRoles = new LinkedHashSet<RoleWithHierarchy>(); - for (RoleWithHierarchy role : rolesAllowed) + if (rolesAllowed.length == 0) { - argumentRoles.addAll(role.getRoles()); + roles = defaultRoles; + } else + { + roles = Arrays.asList(rolesAllowed); } } - return argumentRoles; + return roles; } + private Status checkNotEmpty(List<RoleWithIdentifier> relevantRoles, Set<RoleWithHierarchy> argumentRoles, IAuthSession session) diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMapTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMapTest.java index deda70438d058e1e137a192d6751918c48c394c3..74b08314ac19839a16495bfc7b119e5d92d2a2b5 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMapTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/CapabilityMapTest.java @@ -21,13 +21,19 @@ import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; import java.util.Arrays; +import java.util.Collection; +import java.util.TreeSet; +import org.apache.log4j.Level; import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import ch.systemsx.cisd.common.logging.BufferedAppender; import ch.systemsx.cisd.common.logging.LogInitializer; import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.Capability; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; +import ch.systemsx.cisd.openbis.util.LogRecordingUtils; /** * Tests for {@link CapabilityMap}. @@ -36,6 +42,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy; */ public class CapabilityMapTest { + private BufferedAppender logRecorder; + @BeforeClass public void init() { @@ -61,23 +69,31 @@ public class CapabilityMapTest { } + @BeforeMethod + public void startUp() + { + logRecorder = LogRecordingUtils.createRecorder("%-5p %c - %m%n", Level.DEBUG); + } + @Test public void testHappyCase() throws SecurityException, NoSuchMethodException { CapabilityMap capMap = new CapabilityMap(Arrays.asList("A: SPACE_POWER_USER\t", "# Some comment", "", " B INSTANCE_ETL_SERVER"), "<memory>"); + + assertEquals("", logRecorder.getLogContent()); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null).toArray()[0]); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2"), null).toArray()[0]); assertEquals( RoleWithHierarchy.INSTANCE_ETL_SERVER, capMap.tryGetRoles(CapabilityMapTest.class - .getDeclaredMethod("dummyB", String.class)).toArray()[0]); - assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"))); + .getDeclaredMethod("dummyB", String.class), null).toArray()[0]); + assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"), null)); } @Test @@ -86,17 +102,19 @@ public class CapabilityMapTest CapabilityMap capMap = new CapabilityMap(Arrays.asList("A:SPACE_POWER_USER\t", "# Some comment", "", " B INSTANCE_ETL_SERVER"), "<memory>"); + + assertEquals("", logRecorder.getLogContent()); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null).toArray()[0]); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2"), null).toArray()[0]); assertEquals( RoleWithHierarchy.INSTANCE_ETL_SERVER, capMap.tryGetRoles(CapabilityMapTest.class - .getDeclaredMethod("dummyB", String.class)).toArray()[0]); - assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"))); + .getDeclaredMethod("dummyB", String.class), null).toArray()[0]); + assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"), null)); } @Test @@ -105,17 +123,19 @@ public class CapabilityMapTest CapabilityMap capMap = new CapabilityMap(Arrays.asList("A :SPACE_POWER_USER\t", "# Some comment", "", " B INSTANCE_ETL_SERVER"), "<memory>"); + + assertEquals("", logRecorder.getLogContent()); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null).toArray()[0]); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2"), null).toArray()[0]); assertEquals( RoleWithHierarchy.INSTANCE_ETL_SERVER, capMap.tryGetRoles(CapabilityMapTest.class - .getDeclaredMethod("dummyB", String.class)).toArray()[0]); - assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"))); + .getDeclaredMethod("dummyB", String.class), null).toArray()[0]); + assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"), null)); } @Test @@ -123,31 +143,35 @@ public class CapabilityMapTest { CapabilityMap capMap = new CapabilityMap(Arrays.asList("A : SPACE_POWER_USER\t", "# Some comment", "", - " B INSTANCE_ETL_SERVER"), "<memory>"); + " b instance_etl_server"), "<memory>"); + + assertEquals("", logRecorder.getLogContent()); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null).toArray()[0]); assertEquals( RoleWithHierarchy.SPACE_POWER_USER, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2")).toArray()[0]); + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA2"), null).toArray()[0]); assertEquals( RoleWithHierarchy.INSTANCE_ETL_SERVER, capMap.tryGetRoles(CapabilityMapTest.class - .getDeclaredMethod("dummyB", String.class)).toArray()[0]); - assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"))); + .getDeclaredMethod("dummyB", String.class), null).toArray()[0]); + assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"), null)); } @Test public void testHappyCaseAlternative4() throws SecurityException, NoSuchMethodException { CapabilityMap capMap = - new CapabilityMap(Arrays.asList("A : SPACE_POWER_USER\t", + new CapabilityMap(Arrays.asList("A SPACE_POWER_USER\t", " A INSTANCE_ETL_SERVER"), "<memory>"); - assertEquals(2, capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")) + + assertEquals("", logRecorder.getLogContent()); + assertEquals(2, capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null) .size()); - assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")) + assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null) .contains(RoleWithHierarchy.SPACE_POWER_USER)); - assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")) + assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null) .contains(RoleWithHierarchy.INSTANCE_ETL_SERVER)); } @@ -157,14 +181,39 @@ public class CapabilityMapTest CapabilityMap capMap = new CapabilityMap(Arrays.asList("A : SPACE_POWER_USER,INSTANCE_ETL_SERVER\t"), "<memory>"); - assertEquals(2, capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")) + + assertEquals("", logRecorder.getLogContent()); + assertEquals(2, capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null) .size()); - assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")) + assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null) .contains(RoleWithHierarchy.SPACE_POWER_USER)); - assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")) + assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null) .contains(RoleWithHierarchy.INSTANCE_ETL_SERVER)); } + @Test + public void testParameterRoles() throws Exception + { + CapabilityMap capMap = + new CapabilityMap(Arrays.asList("A\tSPACE_POWER_USER,INSTANCE_ETL_SERVER; " + + "sample = SPACE_USER, SPACE_ETL_SERVER"), "<memory>"); + + assertEquals("", logRecorder.getLogContent()); + assertRoles("[INSTANCE_ETL_SERVER, SPACE_POWER_USER]", capMap, "dummyA1", null); + assertRoles("[SPACE_USER, SPACE_ETL_SERVER]", capMap, "dummyA1", "SAMPLE"); + } + + @Test + public void testOnlyParameterRoles() throws Exception + { + CapabilityMap capMap = + new CapabilityMap(Arrays.asList("a : sample = SPACE_USER, SPACE_ETL_SERVER"), "<memory>"); + + assertEquals("", logRecorder.getLogContent()); + assertNoRoles(capMap, "dummyA1", null); + assertRoles("[SPACE_USER, SPACE_ETL_SERVER]", capMap, "dummyA1", "SAMPLE"); + } + @Test public void testInvalidMapLines() throws SecurityException, NoSuchMethodException { @@ -172,10 +221,17 @@ public class CapabilityMapTest new CapabilityMap(Arrays.asList( "CapabilityMapTest.dummyA: SPACE_POWER_USER #wrong", "CapabilityMapTest.dummyB NO_ROLE"), "<memory>"); - assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"))); + + assertEquals("WARN OPERATION.CapabilityMap - Ignoring mal-formed line " + + "'CapabilityMapTest.dummyA: SPACE_POWER_USER #wrong' in <memory> " + + "[role 'SPACE_POWER_USER #WRONG' doesn't exist].\n" + + "WARN OPERATION.CapabilityMap - Ignoring mal-formed line " + + "'CapabilityMapTest.dummyB NO_ROLE' in <memory> [role 'NO_ROLE' doesn't exist].", + logRecorder.getLogContent()); + assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null)); assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyB", - String.class))); - assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"))); + String.class), null)); + assertNull(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyC"), null)); } @Test @@ -183,12 +239,32 @@ public class CapabilityMapTest { CapabilityMap capMap = new CapabilityMap(Arrays.asList("A: INSTANCE_DISABLED\t"), "<memory>"); + + assertEquals("", logRecorder.getLogContent()); assertEquals( RoleWithHierarchy.INSTANCE_DISABLED, - capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")).toArray()[0]); - assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1")) + capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null).toArray()[0]); + assertTrue(capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod("dummyA1"), null) .toArray(new RoleWithHierarchy[0])[0] .getRoles().isEmpty()); } + private void assertRoles(String expectedRoles, CapabilityMap capMap, String methodName, + String argumentNameOrNull) throws Exception + { + TreeSet<RoleWithHierarchy> set = new TreeSet<RoleWithHierarchy>(); + Collection<RoleWithHierarchy> roles = capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod(methodName), argumentNameOrNull); + if (roles != null) + { + set.addAll(roles); + } + assertEquals(expectedRoles, set.toString()); + } + + private void assertNoRoles(CapabilityMap capMap, String methodName, String argumentNameOrNull) throws Exception + { + Collection<RoleWithHierarchy> roles = capMap.tryGetRoles(CapabilityMapTest.class.getDeclaredMethod(methodName), argumentNameOrNull); + assertEquals(null, roles); + } + } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java index 2a30d8fd46f24f57045d90eb8cad24f220e3c8d6..eab731110aac579f1f430be5dede438a494ab3cc 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java @@ -90,7 +90,7 @@ public final class DefaultAccessControllerTest try { FileUtils.writeLines(capFile, - Arrays.asList("# Test overriding annotation", "MY_CAP: SPACE_OBSERVER")); + Arrays.asList("# Test overriding annotation", "MY_CAP: SPACE_OBSERVER; ARG1 = SPACE_USER")); } catch (IOException ex) { ex.printStackTrace(); @@ -318,6 +318,23 @@ public final class DefaultAccessControllerTest assertEquals(null, project.getDescription()); context.assertIsSatisfied(); } + + @Test + public void testIsAuthorizedWithGardedArgumentWithRolesOverridden() throws Exception + { + final IAuthSession session = AuthorizationTestUtil.createSession(); + session.tryGetPerson().setRoleAssignments(createRoleAssignments()); + final Method method = MyInterface.class.getMethod("myMethodWithGardedArgumentWithRolesOverridden", + String.class, String.class); + assertNotNull(method); + Argument<?>[] arguments = createArguments(method); + + final Status authorized = accessController.isAuthorized(session, method, arguments); + + assertEquals("OK", authorized.toString()); + assertEquals("person: john_doe, roles: [SPACE_USER], value: arg0", project.getDescription()); + context.assertIsSatisfied(); + } private Argument<?>[] createArguments(final Method method) { @@ -369,6 +386,13 @@ public final class DefaultAccessControllerTest @AuthorizationGuard(guardClass = MockPredicate.class, rolesAllowed = { RoleWithHierarchy.SPACE_ETL_SERVER }) String argument1); + + @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) + @Capability("MY_CAP") + public void myMethodWithGardedArgumentWithRolesOverridden(String sessionToken, + @AuthorizationGuard(name = "ARG1", guardClass = MockPredicate.class, + rolesAllowed = { RoleWithHierarchy.SPACE_ETL_SERVER }) + String argument1); } /**