diff --git a/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtils.java b/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtils.java
index ff5ce22e5c..0f716c07a8 100644
--- a/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtils.java
+++ b/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,84 +15,55 @@
*/
package org.springframework.security.access.hierarchicalroles;
+import org.springframework.util.Assert;
+
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
/**
- * Utility method for working with {@link RoleHierarchy}.
+ * Utility methods for {@link RoleHierarchy}.
*
* @author Thomas Darimont
- * @since
+ * @since 4.2.0
*/
-public class RoleHierarchyUtils {
+public final class RoleHierarchyUtils {
+
+ private RoleHierarchyUtils() {
+ }
/**
- * Builds a {@link RoleHierarchy} representation from the given {@link Map} of role name to implied roles.
- * The map key is the role name and the map value is a {@link List} of implied role names.
+ * Converts the supplied {@link Map} of role name to implied role name(s) to a string
+ * representation understood by {@link RoleHierarchyImpl#setHierarchy(String)}.
+ * The map key is the role name and the map value is a {@link List} of implied role name(s).
*
- *
- * Here is an example configuration of a role hierarchy configured via yaml.
- * wich follows the pattern:
- * {@code ROLE_NAME: List of implied role names}
- *
- *
- *
+ * @param roleHierarchyMap the mapping(s) of role name to implied role name(s)
+ * @return a string representation of a role hierarchy
+ * @throws IllegalArgumentException if roleHierarchyMap is null or empty or if a role name is null or
+ * empty or if an implied role name(s) is null or empty
*
- * security:
- * roles:
- * hierarchy:
- * ROLE_ALL: ROLE_A, ROLE_C
- * ROLE_A: ROLE_B
- * ROLE_B: ROLE_AUTHENTICATED
- * ROLE_C: ROLE_AUTHENTICATED
- * ROLE_AUTHENTICATED: ROLE_UNAUTHENTICATED
- *
- *
- * This yaml configuration could then be mapped by the following {@literal ConfigurationProperties}
- *
- *
- * {@literal @}ConfigurationProperties("security.roles")
- * class SecurityPropertiesExtension {
- * Map> hierarchy = new LinkedHashMap<>();
- *
- * //getter | setter
- * }
- *
- *
- * To define the role hierarchy just declare a {@link org.springframework.context.annotation.Bean} of
- * type {@link RoleHierarchy} as follows:
- *
- *
- * {@literal @}Bean
- * RoleHierarchy roleHierarchy(SecurityPropertiesExtension spe) {
- * return RoleHierarchyUtils.roleHierarchyFromMap(spe.getHierarchy());
- * }
- *
- *
- *
- * @param roleHierarchyMapping the role name to implied role names mapping
- * @return
*/
- public static RoleHierarchy roleHierarchyFromMap(Map> roleHierarchyMapping) {
+ public static String roleHierarchyFromMap(Map> roleHierarchyMap) {
+ Assert.notEmpty(roleHierarchyMap, "roleHierarchyMap cannot be empty");
- StringWriter roleHierachyDescriptionBuffer = new StringWriter();
- PrintWriter roleHierarchyDescriptionWriter = new PrintWriter(roleHierachyDescriptionBuffer);
+ StringWriter roleHierarchyBuffer = new StringWriter();
+ PrintWriter roleHierarchyWriter = new PrintWriter(roleHierarchyBuffer);
- for (Map.Entry> entry : roleHierarchyMapping.entrySet()) {
+ for (Map.Entry> roleHierarchyEntry : roleHierarchyMap.entrySet()) {
+ String role = roleHierarchyEntry.getKey();
+ List impliedRoles = roleHierarchyEntry.getValue();
- String currentRole = entry.getKey();
- List impliedRoles = entry.getValue();
+ Assert.hasLength(role, "role name must be supplied");
+ Assert.notEmpty(impliedRoles, "implied role name(s) cannot be empty");
for (String impliedRole : impliedRoles) {
- String roleMapping = currentRole + " > " + impliedRole;
- roleHierarchyDescriptionWriter.println(roleMapping);
+ String roleMapping = role + " > " + impliedRole;
+ roleHierarchyWriter.println(roleMapping);
}
}
- RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
- roleHierarchy.setHierarchy(roleHierachyDescriptionBuffer.toString());
- return roleHierarchy;
+ return roleHierarchyBuffer.toString();
}
+
}
diff --git a/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtilsTests.java b/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtilsTests.java
index b90e58f03b..0f369a0db4 100644
--- a/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtilsTests.java
+++ b/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyUtilsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,251 +16,72 @@
package org.springframework.security.access.hierarchicalroles;
import org.junit.Test;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
-import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-import static org.springframework.security.access.hierarchicalroles.RoleHierarchyUtils.roleHierarchyFromMap;
/**
* Tests for {@link RoleHierarchyUtils}.
*
- * Copied from {@link RoleHierarchyImplTests} with adaptations for {@link RoleHierarchyUtils}.
- *
- * @author Thomas Darimont
+ * @author Joe Grandja
*/
public class RoleHierarchyUtilsTests {
@Test
- public void testRoleHierarchyWithNullOrEmptyAuthorities() {
+ public void roleHierarchyFromMapWhenMapValidThenConvertsCorrectly() throws Exception {
+ String expectedRoleHierarchy = "ROLE_A > ROLE_B\nROLE_A > ROLE_C\nROLE_B > ROLE_D\nROLE_C > ROLE_D\n";
- List authorities0 = null;
- List authorities1 = new ArrayList();
+ Map> roleHierarchyMap = new TreeMap>();
+ roleHierarchyMap.put("ROLE_A", asList("ROLE_B", "ROLE_C"));
+ roleHierarchyMap.put("ROLE_B", asList("ROLE_D"));
+ roleHierarchyMap.put("ROLE_C", asList("ROLE_D"));
- RoleHierarchy roleHierarchy = roleHierarchyFromMap(singletonMap("ROLE_A", singletonList("ROLE_B")));
+ String roleHierarchy = RoleHierarchyUtils.roleHierarchyFromMap(roleHierarchyMap);
- assertThat(roleHierarchy.getReachableGrantedAuthorities(
- authorities0)).isNotNull();
- assertThat(
- roleHierarchy.getReachableGrantedAuthorities(authorities0)).isEmpty();
- ;
- assertThat(roleHierarchy.getReachableGrantedAuthorities(
- authorities1)).isNotNull();
- assertThat(
- roleHierarchy.getReachableGrantedAuthorities(authorities1)).isEmpty();
- ;
+ assertThat(roleHierarchy).isEqualTo(expectedRoleHierarchy);
}
- @Test
- public void testSimpleRoleHierarchy() {
-
- List authorities0 = AuthorityUtils.createAuthorityList(
- "ROLE_0");
- List authorities1 = AuthorityUtils.createAuthorityList(
- "ROLE_A");
- List authorities2 = AuthorityUtils.createAuthorityList("ROLE_A",
- "ROLE_B");
-
- RoleHierarchy roleHierarchy = roleHierarchyFromMap(singletonMap("ROLE_A", singletonList("ROLE_B")));
-
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy.getReachableGrantedAuthorities(authorities0),
- authorities0)).isTrue();
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy.getReachableGrantedAuthorities(authorities1),
- authorities2)).isTrue();
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy.getReachableGrantedAuthorities(authorities2),
- authorities2)).isTrue();
+ @Test(expected = IllegalArgumentException.class)
+ public void roleHierarchyFromMapWhenMapNullThenThrowsIllegalArgumentException() throws Exception {
+ RoleHierarchyUtils.roleHierarchyFromMap(null);
}
- @Test
- public void testTransitiveRoleHierarchies() {
- List authorities1 = AuthorityUtils.createAuthorityList(
- "ROLE_A");
- List authorities2 = AuthorityUtils.createAuthorityList("ROLE_A",
- "ROLE_B", "ROLE_C");
- List authorities3 = AuthorityUtils.createAuthorityList("ROLE_A",
- "ROLE_B", "ROLE_C", "ROLE_D");
-
- RoleHierarchy roleHierarchy2Levels = roleHierarchyFromMap(new HashMap>(){
- {
- put("ROLE_A", asList("ROLE_B"));
- put("ROLE_B", asList("ROLE_C"));
- }
- });
-
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy2Levels.getReachableGrantedAuthorities(authorities1),
- authorities2)).isTrue();
-
- RoleHierarchy roleHierarchy3Levels = roleHierarchyFromMap(new HashMap>(){
- {
- put("ROLE_A", asList("ROLE_B"));
- put("ROLE_B", asList("ROLE_C"));
- put("ROLE_C", asList("ROLE_D"));
- }
- });
-
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy3Levels.getReachableGrantedAuthorities(authorities1),
- authorities3)).isTrue();
+ @Test(expected = IllegalArgumentException.class)
+ public void roleHierarchyFromMapWhenMapEmptyThenThrowsIllegalArgumentException() throws Exception {
+ RoleHierarchyUtils.roleHierarchyFromMap(Collections.>emptyMap());
}
- @Test
- public void testComplexRoleHierarchy() {
- List authoritiesInput1 = AuthorityUtils.createAuthorityList(
- "ROLE_A");
- List authoritiesOutput1 = AuthorityUtils.createAuthorityList(
- "ROLE_A", "ROLE_B", "ROLE_C", "ROLE_D");
- List authoritiesInput2 = AuthorityUtils.createAuthorityList(
- "ROLE_B");
- List authoritiesOutput2 = AuthorityUtils.createAuthorityList(
- "ROLE_B", "ROLE_D");
- List authoritiesInput3 = AuthorityUtils.createAuthorityList(
- "ROLE_C");
- List authoritiesOutput3 = AuthorityUtils.createAuthorityList(
- "ROLE_C", "ROLE_D");
- List authoritiesInput4 = AuthorityUtils.createAuthorityList(
- "ROLE_D");
- List authoritiesOutput4 = AuthorityUtils.createAuthorityList(
- "ROLE_D");
+ @Test(expected = IllegalArgumentException.class)
+ public void roleHierarchyFromMapWhenRoleNullThenThrowsIllegalArgumentException() throws Exception {
+ Map> roleHierarchyMap = new HashMap>();
+ roleHierarchyMap.put(null, asList("ROLE_B", "ROLE_C"));
-
- RoleHierarchy roleHierarchy3LevelsMultipleRoles = roleHierarchyFromMap(new HashMap>(){
- {
- put("ROLE_A", asList("ROLE_B","ROLE_C"));
- put("ROLE_B", asList("ROLE_D"));
- put("ROLE_C", asList("ROLE_D"));
- }
- });
-
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy3LevelsMultipleRoles.getReachableGrantedAuthorities(authoritiesInput1),
- authoritiesOutput1)).isTrue();
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy3LevelsMultipleRoles.getReachableGrantedAuthorities(authoritiesInput2),
- authoritiesOutput2)).isTrue();
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy3LevelsMultipleRoles.getReachableGrantedAuthorities(authoritiesInput3),
- authoritiesOutput3)).isTrue();
- assertThat(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(
- roleHierarchy3LevelsMultipleRoles.getReachableGrantedAuthorities(authoritiesInput4),
- authoritiesOutput4)).isTrue();
+ RoleHierarchyUtils.roleHierarchyFromMap(roleHierarchyMap);
}
- @Test
- public void testCyclesInRoleHierarchy() {
+ @Test(expected = IllegalArgumentException.class)
+ public void roleHierarchyFromMapWhenRoleEmptyThenThrowsIllegalArgumentException() throws Exception {
+ Map> roleHierarchyMap = new HashMap>();
+ roleHierarchyMap.put("", asList("ROLE_B", "ROLE_C"));
- try {
- roleHierarchyFromMap(singletonMap("ROLE_A", singletonList("ROLE_A")));
- fail("Cycle in role hierarchy was not detected!");
- }
- catch (CycleInRoleHierarchyException e) {
- }
-
- try {
-
- roleHierarchyFromMap(new HashMap>(){
- {
- put("ROLE_A", asList("ROLE_B"));
- put("ROLE_B", asList("ROLE_A"));
- }
- });
-
- fail("Cycle in role hierarchy was not detected!");
- }
- catch (CycleInRoleHierarchyException e) {
- }
-
- try {
-
- roleHierarchyFromMap(new HashMap>(){
- {
- put("ROLE_A", asList("ROLE_B"));
- put("ROLE_B", asList("ROLE_C"));
- put("ROLE_C", asList("ROLE_A"));
- }
- });
-
- fail("Cycle in role hierarchy was not detected!");
- }
- catch (CycleInRoleHierarchyException e) {
- }
-
- try {
-
- roleHierarchyFromMap(new HashMap>(){
- {
- put("ROLE_A", asList("ROLE_B"));
- put("ROLE_B", asList("ROLE_C"));
- put("ROLE_C", asList("ROLE_E"));
- put("ROLE_E", asList("ROLE_D"));
- put("ROLE_D", asList("ROLE_B"));
- }
- });
-
-
- fail("Cycle in role hierarchy was not detected!");
- }
- catch (CycleInRoleHierarchyException e) {
- }
+ RoleHierarchyUtils.roleHierarchyFromMap(roleHierarchyMap);
}
- @Test
- public void testNoCyclesInRoleHierarchy() {
- RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
+ @Test(expected = IllegalArgumentException.class)
+ public void roleHierarchyFromMapWhenImpliedRolesNullThenThrowsIllegalArgumentException() throws Exception {
+ Map> roleHierarchyMap = new HashMap>();
+ roleHierarchyMap.put("ROLE_A", null);
- try {
- roleHierarchyImpl.setHierarchy(
- "ROLE_A > ROLE_B\nROLE_A > ROLE_C\nROLE_C > ROLE_D\nROLE_B > ROLE_D");
-
- roleHierarchyFromMap(new HashMap>(){
- {
- put("ROLE_A", asList("ROLE_B"));
- put("ROLE_A", asList("ROLE_C"));
- put("ROLE_C", asList("ROLE_D"));
- put("ROLE_B", asList("ROLE_D"));
- }
- });
-
- }
- catch (CycleInRoleHierarchyException e) {
- fail("A cycle in role hierarchy was incorrectly detected!");
- }
+ RoleHierarchyUtils.roleHierarchyFromMap(roleHierarchyMap);
}
- @Test
- public void testSimpleRoleHierarchyWithCustomGrantedAuthorityImplementation() {
+ @Test(expected = IllegalArgumentException.class)
+ public void roleHierarchyFromMapWhenImpliedRolesEmptyThenThrowsIllegalArgumentException() throws Exception {
+ Map> roleHierarchyMap = new HashMap>();
+ roleHierarchyMap.put("ROLE_A", Collections.emptyList());
- List authorities0 = HierarchicalRolesTestHelper.createAuthorityList(
- "ROLE_0");
- List authorities1 = HierarchicalRolesTestHelper.createAuthorityList(
- "ROLE_A");
- List authorities2 = HierarchicalRolesTestHelper.createAuthorityList(
- "ROLE_A", "ROLE_B");
-
- RoleHierarchy roleHierarchy = roleHierarchyFromMap(singletonMap("ROLE_A", singletonList("ROLE_B")));
-
- assertThat(
- HierarchicalRolesTestHelper.containTheSameGrantedAuthoritiesCompareByAuthorityString(
- roleHierarchy.getReachableGrantedAuthorities(authorities0),
- authorities0)).isTrue();
- assertThat(
- HierarchicalRolesTestHelper.containTheSameGrantedAuthoritiesCompareByAuthorityString(
- roleHierarchy.getReachableGrantedAuthorities(authorities1),
- authorities2)).isTrue();
- assertThat(
- HierarchicalRolesTestHelper.containTheSameGrantedAuthoritiesCompareByAuthorityString(
- roleHierarchy.getReachableGrantedAuthorities(authorities2),
- authorities2)).isTrue();
+ RoleHierarchyUtils.roleHierarchyFromMap(roleHierarchyMap);
}
}