diff --git a/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.java b/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.java
index 191a2b9a58..b1ce26e159 100755
--- a/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.java
+++ b/core/src/main/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImpl.java
@@ -1,198 +1,233 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.access.hierarchicalroles;
-
-
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.GrantedAuthorityImpl;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import java.util.*;
-
-/**
- *
- * This class defines a role hierarchy for use with the UserDetailsServiceWrapper.
- *
- *
- * Here is an example configuration of a role hierarchy (hint: read the ">" sign as "includes"):
-
- <property name="hierarchy">
- <value>
- ROLE_A > ROLE_B
- ROLE_B > ROLE_AUTHENTICATED
- ROLE_AUTHENTICATED > ROLE_UNAUTHENTICATED
- </value>
- </property>
-
-
- *
- * Explanation of the above:
- * In effect every user with ROLE_A also has ROLE_B, ROLE_AUTHENTICATED and ROLE_UNAUTHENTICATED;
- * every user with ROLE_B also has ROLE_AUTHENTICATED and ROLE_UNAUTHENTICATED;
- * every user with ROLE_AUTHENTICATED also has ROLE_UNAUTHENTICATED.
- *
- *
- * Hierarchical Roles will dramatically shorten your access rules (and also make the access rules much more elegant).
- *
- *
- * Consider this access rule for Spring Security's RoleVoter (background: every user that is authenticated should be
- * able to log out):
- * /logout.html=ROLE_A,ROLE_B,ROLE_AUTHENTICATED
- * With hierarchical roles this can now be shortened to:
- * /logout.html=ROLE_AUTHENTICATED
- * In addition to shorter rules this will also make your access rules more readable and your intentions clearer.
- *
- *
- * @author Michael Mayr
- *
- */
-public class RoleHierarchyImpl implements RoleHierarchy {
-
- private static final Log logger = LogFactory.getLog(RoleHierarchyImpl.class);
-
- private String roleHierarchyStringRepresentation = null;
-
- /**
- * rolesReachableInOneStepMap is a Map that under the key of a specific role name contains a set of all roles
- * reachable from this role in 1 step
- */
- private Map> rolesReachableInOneStepMap = null;
-
- /**
- * rolesReachableInOneOrMoreStepsMap is a Map that under the key of a specific role name contains a set of all
- * roles reachable from this role in 1 or more steps
- */
- private Map> rolesReachableInOneOrMoreStepsMap = null;
-
- /**
- * Set the role hierarchy and pre-calculate for every role the set of all reachable roles, i.e. all roles lower in
- * the hierarchy of every given role. Pre-calculation is done for performance reasons (reachable roles can then be
- * calculated in O(1) time).
- * During pre-calculation, cycles in role hierarchy are detected and will cause a
- * CycleInRoleHierarchyException to be thrown.
- *
- * @param roleHierarchyStringRepresentation - String definition of the role hierarchy.
- */
- public void setHierarchy(String roleHierarchyStringRepresentation) {
- this.roleHierarchyStringRepresentation = roleHierarchyStringRepresentation;
-
- logger.debug("setHierarchy() - The following role hierarchy was set: " + roleHierarchyStringRepresentation);
-
- buildRolesReachableInOneStepMap();
- buildRolesReachableInOneOrMoreStepsMap();
- }
-
- public List getReachableGrantedAuthorities(List authorities) {
- if (authorities == null || authorities.isEmpty()) {
- return null;
- }
-
- Set reachableRoles = new HashSet();
-
- for (GrantedAuthority authority : authorities) {
- reachableRoles.add(authority);
- Set additionalReachableRoles = rolesReachableInOneOrMoreStepsMap.get(authority);
- if (additionalReachableRoles != null) {
- reachableRoles.addAll(additionalReachableRoles);
- }
- }
-
- if (logger.isDebugEnabled()) {
- logger.debug("getReachableGrantedAuthorities() - From the roles " + authorities
- + " one can reach " + reachableRoles + " in zero or more steps.");
- }
-
- List reachableRoleList = new ArrayList(reachableRoles.size());
- reachableRoleList.addAll(reachableRoles);
-
- return reachableRoleList;
- }
-
- /**
- * Parse input and build the map for the roles reachable in one step: the higher role will become a key that
- * references a set of the reachable lower roles.
- */
- private void buildRolesReachableInOneStepMap() {
- Pattern pattern = Pattern.compile("(\\s*([^\\s>]+)\\s*\\>\\s*([^\\s>]+))");
-
- Matcher roleHierarchyMatcher = pattern.matcher(roleHierarchyStringRepresentation);
- rolesReachableInOneStepMap = new HashMap>();
-
- while (roleHierarchyMatcher.find()) {
- GrantedAuthority higherRole = new GrantedAuthorityImpl(roleHierarchyMatcher.group(2));
- GrantedAuthority lowerRole = new GrantedAuthorityImpl(roleHierarchyMatcher.group(3));
- Set rolesReachableInOneStepSet = null;
-
- if (!rolesReachableInOneStepMap.containsKey(higherRole)) {
- rolesReachableInOneStepSet = new HashSet();
- rolesReachableInOneStepMap.put(higherRole, rolesReachableInOneStepSet);
- } else {
- rolesReachableInOneStepSet = rolesReachableInOneStepMap.get(higherRole);
- }
- rolesReachableInOneStepSet.add(lowerRole);
-
- logger.debug("buildRolesReachableInOneStepMap() - From role "
- + higherRole + " one can reach role " + lowerRole + " in one step.");
- }
- }
-
- /**
- * For every higher role from rolesReachableInOneStepMap store all roles that are reachable from it in the map of
- * roles reachable in one or more steps. (Or throw a CycleInRoleHierarchyException if a cycle in the role
- * hierarchy definition is detected)
- */
- private void buildRolesReachableInOneOrMoreStepsMap() {
- rolesReachableInOneOrMoreStepsMap = new HashMap>();
- // iterate over all higher roles from rolesReachableInOneStepMap
-
- for(GrantedAuthority role : rolesReachableInOneStepMap.keySet()) {
- Set rolesToVisitSet = new HashSet();
-
- if (rolesReachableInOneStepMap.containsKey(role)) {
- rolesToVisitSet.addAll(rolesReachableInOneStepMap.get(role));
- }
-
- Set visitedRolesSet = new HashSet();
-
- while (!rolesToVisitSet.isEmpty()) {
- // take a role from the rolesToVisit set
- GrantedAuthority aRole = (GrantedAuthority) rolesToVisitSet.iterator().next();
- rolesToVisitSet.remove(aRole);
- visitedRolesSet.add(aRole);
- if (rolesReachableInOneStepMap.containsKey(aRole)) {
- Set newReachableRoles = rolesReachableInOneStepMap.get(aRole);
-
- // definition of a cycle: you can reach the role you are starting from
- if (rolesToVisitSet.contains(role) || visitedRolesSet.contains(role)) {
- throw new CycleInRoleHierarchyException();
- } else {
- // no cycle
- rolesToVisitSet.addAll(newReachableRoles);
- }
- }
- }
- rolesReachableInOneOrMoreStepsMap.put(role, visitedRolesSet);
-
- logger.debug("buildRolesReachableInOneOrMoreStepsMap() - From role "
- + role + " one can reach " + visitedRolesSet + " in one or more steps.");
- }
-
- }
-
-}
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.access.hierarchicalroles;
+
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.GrantedAuthorityImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import java.util.*;
+
+/**
+ *
+ * This class defines a role hierarchy for use with the UserDetailsServiceWrapper.
+ *
+ *
+ * Here is an example configuration of a role hierarchy (hint: read the ">" sign as "includes"):
+
+ <property name="hierarchy">
+ <value>
+ ROLE_A > ROLE_B
+ ROLE_B > ROLE_AUTHENTICATED
+ ROLE_AUTHENTICATED > ROLE_UNAUTHENTICATED
+ </value>
+ </property>
+
+
+ *
+ * Explanation of the above:
+ * In effect every user with ROLE_A also has ROLE_B, ROLE_AUTHENTICATED and ROLE_UNAUTHENTICATED;
+ * every user with ROLE_B also has ROLE_AUTHENTICATED and ROLE_UNAUTHENTICATED;
+ * every user with ROLE_AUTHENTICATED also has ROLE_UNAUTHENTICATED.
+ *
+ *
+ * Hierarchical Roles will dramatically shorten your access rules (and also make the access rules much more elegant).
+ *
+ *
+ * Consider this access rule for Spring Security's RoleVoter (background: every user that is authenticated should be
+ * able to log out):
+ * /logout.html=ROLE_A,ROLE_B,ROLE_AUTHENTICATED
+ * With hierarchical roles this can now be shortened to:
+ * /logout.html=ROLE_AUTHENTICATED
+ * In addition to shorter rules this will also make your access rules more readable and your intentions clearer.
+ *
+ *
+ * @author Michael Mayr
+ *
+ */
+public class RoleHierarchyImpl implements RoleHierarchy {
+
+ private static final Log logger = LogFactory.getLog(RoleHierarchyImpl.class);
+
+ private String roleHierarchyStringRepresentation = null;
+
+ /**
+ * rolesReachableInOneStepMap is a Map that under the key of a specific role name contains a set of all roles
+ * reachable from this role in 1 step
+ */
+ private Map> rolesReachableInOneStepMap = null;
+
+ /**
+ * rolesReachableInOneOrMoreStepsMap is a Map that under the key of a specific role name contains a set of all
+ * roles reachable from this role in 1 or more steps
+ */
+ private Map> rolesReachableInOneOrMoreStepsMap = null;
+
+ /**
+ * Set the role hierarchy and pre-calculate for every role the set of all reachable roles, i.e. all roles lower in
+ * the hierarchy of every given role. Pre-calculation is done for performance reasons (reachable roles can then be
+ * calculated in O(1) time).
+ * During pre-calculation, cycles in role hierarchy are detected and will cause a
+ * CycleInRoleHierarchyException to be thrown.
+ *
+ * @param roleHierarchyStringRepresentation - String definition of the role hierarchy.
+ */
+ public void setHierarchy(String roleHierarchyStringRepresentation) {
+ this.roleHierarchyStringRepresentation = roleHierarchyStringRepresentation;
+
+ logger.debug("setHierarchy() - The following role hierarchy was set: " + roleHierarchyStringRepresentation);
+
+ buildRolesReachableInOneStepMap();
+ buildRolesReachableInOneOrMoreStepsMap();
+ }
+
+ public List getReachableGrantedAuthorities(List authorities) {
+ if (authorities == null || authorities.isEmpty()) {
+ return null;
+ }
+
+ Set reachableRoles = new HashSet();
+
+ for (GrantedAuthority authority : authorities) {
+ addReachableRoles(reachableRoles, authority);
+ Set additionalReachableRoles = getRolesReachableInOneOrMoreSteps(authority);
+ if (additionalReachableRoles != null) {
+ reachableRoles.addAll(additionalReachableRoles);
+ }
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("getReachableGrantedAuthorities() - From the roles " + authorities
+ + " one can reach " + reachableRoles + " in zero or more steps.");
+ }
+
+ List reachableRoleList = new ArrayList(reachableRoles.size());
+ reachableRoleList.addAll(reachableRoles);
+
+ return reachableRoleList;
+ }
+
+ // SEC-863
+ private void addReachableRoles(Set reachableRoles,
+ GrantedAuthority authority) {
+
+ Iterator iterator = reachableRoles.iterator();
+ while (iterator.hasNext()) {
+ GrantedAuthority testAuthority = iterator.next();
+ String testKey = testAuthority.getAuthority();
+ if ((testKey != null) && (testKey.equals(authority.getAuthority()))) {
+ return;
+ }
+ }
+ reachableRoles.add(authority);
+ }
+
+ // SEC-863
+ private Set getRolesReachableInOneOrMoreSteps(
+ GrantedAuthority authority) {
+
+ if (authority.getAuthority() == null) {
+ return null;
+ }
+
+ Iterator iterator = rolesReachableInOneOrMoreStepsMap.keySet().iterator();
+ while (iterator.hasNext()) {
+ GrantedAuthority testAuthority = iterator.next();
+ String testKey = testAuthority.getAuthority();
+ if ((testKey != null) && (testKey.equals(authority.getAuthority()))) {
+ return rolesReachableInOneOrMoreStepsMap.get(testAuthority);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Parse input and build the map for the roles reachable in one step: the higher role will become a key that
+ * references a set of the reachable lower roles.
+ */
+ private void buildRolesReachableInOneStepMap() {
+ Pattern pattern = Pattern.compile("(\\s*([^\\s>]+)\\s*\\>\\s*([^\\s>]+))");
+
+ Matcher roleHierarchyMatcher = pattern.matcher(roleHierarchyStringRepresentation);
+ rolesReachableInOneStepMap = new HashMap>();
+
+ while (roleHierarchyMatcher.find()) {
+ GrantedAuthority higherRole = new GrantedAuthorityImpl(roleHierarchyMatcher.group(2));
+ GrantedAuthority lowerRole = new GrantedAuthorityImpl(roleHierarchyMatcher.group(3));
+ Set rolesReachableInOneStepSet = null;
+
+ if (!rolesReachableInOneStepMap.containsKey(higherRole)) {
+ rolesReachableInOneStepSet = new HashSet();
+ rolesReachableInOneStepMap.put(higherRole, rolesReachableInOneStepSet);
+ } else {
+ rolesReachableInOneStepSet = rolesReachableInOneStepMap.get(higherRole);
+ }
+ addReachableRoles(rolesReachableInOneStepSet, lowerRole);
+
+ logger.debug("buildRolesReachableInOneStepMap() - From role "
+ + higherRole + " one can reach role " + lowerRole + " in one step.");
+ }
+ }
+
+ /**
+ * For every higher role from rolesReachableInOneStepMap store all roles that are reachable from it in the map of
+ * roles reachable in one or more steps. (Or throw a CycleInRoleHierarchyException if a cycle in the role
+ * hierarchy definition is detected)
+ */
+ private void buildRolesReachableInOneOrMoreStepsMap() {
+ rolesReachableInOneOrMoreStepsMap = new HashMap>();
+ // iterate over all higher roles from rolesReachableInOneStepMap
+
+ for(GrantedAuthority role : rolesReachableInOneStepMap.keySet()) {
+ Set rolesToVisitSet = new HashSet();
+
+ if (rolesReachableInOneStepMap.containsKey(role)) {
+ rolesToVisitSet.addAll(rolesReachableInOneStepMap.get(role));
+ }
+
+ Set visitedRolesSet = new HashSet();
+
+ while (!rolesToVisitSet.isEmpty()) {
+ // take a role from the rolesToVisit set
+ GrantedAuthority aRole = (GrantedAuthority) rolesToVisitSet.iterator().next();
+ rolesToVisitSet.remove(aRole);
+ addReachableRoles(visitedRolesSet, aRole);
+ if (rolesReachableInOneStepMap.containsKey(aRole)) {
+ Set newReachableRoles = rolesReachableInOneStepMap.get(aRole);
+
+ // definition of a cycle: you can reach the role you are starting from
+ if (rolesToVisitSet.contains(role) || visitedRolesSet.contains(role)) {
+ throw new CycleInRoleHierarchyException();
+ } else {
+ // no cycle
+ rolesToVisitSet.addAll(newReachableRoles);
+ }
+ }
+ }
+ rolesReachableInOneOrMoreStepsMap.put(role, visitedRolesSet);
+
+ logger.debug("buildRolesReachableInOneOrMoreStepsMap() - From role "
+ + role + " one can reach " + visitedRolesSet + " in one or more steps.");
+ }
+
+ }
+
+}
diff --git a/core/src/test/java/org/springframework/security/access/hierarchicalroles/HierarchicalRolesTestHelper.java b/core/src/test/java/org/springframework/security/access/hierarchicalroles/HierarchicalRolesTestHelper.java
index 21fcb9f72c..0d363f4270 100755
--- a/core/src/test/java/org/springframework/security/access/hierarchicalroles/HierarchicalRolesTestHelper.java
+++ b/core/src/test/java/org/springframework/security/access/hierarchicalroles/HierarchicalRolesTestHelper.java
@@ -1,40 +1,92 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.access.hierarchicalroles;
-
-import java.util.List;
-
-import org.springframework.security.core.GrantedAuthority;
-import org.apache.commons.collections.CollectionUtils;
-
-/**
- * Test helper class for the hierarchical roles tests.
- *
- * @author Michael Mayr
- */
-public abstract class HierarchicalRolesTestHelper {
-
- public static boolean containTheSameGrantedAuthorities(List authorities1, List authorities2) {
- if (authorities1 == null && authorities2 == null) {
- return true;
- }
-
- if (authorities1 == null || authorities2 == null) {
- return false;
- }
- return CollectionUtils.isEqualCollection(authorities1, authorities2);
- }
-
-}
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.access.hierarchicalroles;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.apache.commons.collections.CollectionUtils;
+
+/**
+ * Test helper class for the hierarchical roles tests.
+ *
+ * @author Michael Mayr
+ */
+public abstract class HierarchicalRolesTestHelper {
+
+ public static boolean containTheSameGrantedAuthorities(List authorities1, List authorities2) {
+ if (authorities1 == null && authorities2 == null) {
+ return true;
+ }
+
+ if (authorities1 == null || authorities2 == null) {
+ return false;
+ }
+ return CollectionUtils.isEqualCollection(authorities1, authorities2);
+ }
+
+ public static boolean containTheSameGrantedAuthoritiesCompareByAuthorityString(List authorities1, List authorities2) {
+ if (authorities1 == null && authorities2 == null) {
+ return true;
+ }
+
+ if (authorities1 == null || authorities2 == null) {
+ return false;
+ }
+ return CollectionUtils.isEqualCollection(toListOfAuthorityStrings(authorities1), toListOfAuthorityStrings(authorities2));
+ }
+
+ public static List toListOfAuthorityStrings(List authorities) {
+ if (authorities == null) {
+ return null;
+ }
+
+ List result = new ArrayList(authorities.size());
+ for (GrantedAuthority authority : authorities) {
+ result.add(authority.getAuthority());
+ }
+ return result;
+ }
+
+ public static List createAuthorityList(final String... roles) {
+ List authorities = new ArrayList(roles.length);
+
+ for (final String role : roles) {
+ // Use non GrantedAuthorityImpl (SEC-863)
+ authorities.add(new GrantedAuthority() {
+ public String getAuthority() {
+ return role;
+ }
+
+ public int compareTo(GrantedAuthority ga) {
+ if (ga != null) {
+ String rhsRole = ga.getAuthority();
+
+ if (rhsRole == null) {
+ return -1;
+ }
+
+ return role.compareTo(rhsRole);
+ }
+ return -1;
+ }
+ });
+ }
+
+ return authorities;
+ }
+
+}
diff --git a/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImplTests.java b/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImplTests.java
index 266e7a5987..060e02baeb 100755
--- a/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImplTests.java
+++ b/core/src/test/java/org/springframework/security/access/hierarchicalroles/RoleHierarchyImplTests.java
@@ -1,114 +1,128 @@
-/*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package org.springframework.security.access.hierarchicalroles;
-
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.springframework.security.access.hierarchicalroles.CycleInRoleHierarchyException;
-import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-
-/**
- * Tests for {@link RoleHierarchyImpl}.
- *
- * @author Michael Mayr
- */
-public class RoleHierarchyImplTests extends TestCase {
-
- public void testSimpleRoleHierarchy() {
-
- List authorities0 = AuthorityUtils.createAuthorityList("ROLE_0");
- List authorities1 = AuthorityUtils.createAuthorityList("ROLE_A");
- List authorities2 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_B");
-
- RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B");
-
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities0), authorities0));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities1), authorities2));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities2), authorities2));
- }
-
- 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");
-
- RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
-
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C");
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities1), authorities2));
-
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C\nROLE_C > ROLE_D");
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities1), authorities3));
- }
-
- 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");
-
- RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_A > ROLE_C\nROLE_C > ROLE_D\nROLE_B > ROLE_D");
-
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput1), authoritiesOutput1));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput2), authoritiesOutput2));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput3), authoritiesOutput3));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput4), authoritiesOutput4));
- }
-
- public void testCyclesInRoleHierarchy() {
- RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
-
- try {
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_A");
- fail("Cycle in role hierarchy was not detected!");
- } catch (CycleInRoleHierarchyException e) {}
-
- try {
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_A");
- fail("Cycle in role hierarchy was not detected!");
- } catch (CycleInRoleHierarchyException e) {}
-
- try {
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C\nROLE_C > ROLE_A");
- fail("Cycle in role hierarchy was not detected!");
- } catch (CycleInRoleHierarchyException e) {}
-
- try {
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C\nROLE_C > ROLE_E\nROLE_E > ROLE_D\nROLE_D > ROLE_B");
- fail("Cycle in role hierarchy was not detected!");
- } catch (CycleInRoleHierarchyException e) {}
- }
-
- public void testNoCyclesInRoleHierarchy() {
- RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
-
- try {
- roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_A > ROLE_C\nROLE_C > ROLE_D\nROLE_B > ROLE_D");
- } catch (CycleInRoleHierarchyException e) {
- fail("A cycle in role hierarchy was incorrectly detected!");
- }
- }
-
-}
+/*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.springframework.security.access.hierarchicalroles;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.springframework.security.access.hierarchicalroles.CycleInRoleHierarchyException;
+import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+
+/**
+ * Tests for {@link RoleHierarchyImpl}.
+ *
+ * @author Michael Mayr
+ */
+public class RoleHierarchyImplTests extends TestCase {
+
+ public void testSimpleRoleHierarchy() {
+
+ List authorities0 = AuthorityUtils.createAuthorityList("ROLE_0");
+ List authorities1 = AuthorityUtils.createAuthorityList("ROLE_A");
+ List authorities2 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_B");
+
+ RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B");
+
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities0), authorities0));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities1), authorities2));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities2), authorities2));
+ }
+
+ 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");
+
+ RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
+
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C");
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities1), authorities2));
+
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C\nROLE_C > ROLE_D");
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authorities1), authorities3));
+ }
+
+ 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");
+
+ RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_A > ROLE_C\nROLE_C > ROLE_D\nROLE_B > ROLE_D");
+
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput1), authoritiesOutput1));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput2), authoritiesOutput2));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput3), authoritiesOutput3));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(roleHierarchyImpl.getReachableGrantedAuthorities(authoritiesInput4), authoritiesOutput4));
+ }
+
+ public void testCyclesInRoleHierarchy() {
+ RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
+
+ try {
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_A");
+ fail("Cycle in role hierarchy was not detected!");
+ } catch (CycleInRoleHierarchyException e) {}
+
+ try {
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_A");
+ fail("Cycle in role hierarchy was not detected!");
+ } catch (CycleInRoleHierarchyException e) {}
+
+ try {
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C\nROLE_C > ROLE_A");
+ fail("Cycle in role hierarchy was not detected!");
+ } catch (CycleInRoleHierarchyException e) {}
+
+ try {
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_B > ROLE_C\nROLE_C > ROLE_E\nROLE_E > ROLE_D\nROLE_D > ROLE_B");
+ fail("Cycle in role hierarchy was not detected!");
+ } catch (CycleInRoleHierarchyException e) {}
+ }
+
+ public void testNoCyclesInRoleHierarchy() {
+ RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
+
+ try {
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B\nROLE_A > ROLE_C\nROLE_C > ROLE_D\nROLE_B > ROLE_D");
+ } catch (CycleInRoleHierarchyException e) {
+ fail("A cycle in role hierarchy was incorrectly detected!");
+ }
+ }
+
+ // SEC-863
+ public void testSimpleRoleHierarchyWithCustomGrantedAuthorityImplementation() {
+
+ List authorities0 = HierarchicalRolesTestHelper.createAuthorityList("ROLE_0");
+ List authorities1 = HierarchicalRolesTestHelper.createAuthorityList("ROLE_A");
+ List authorities2 = HierarchicalRolesTestHelper.createAuthorityList("ROLE_A","ROLE_B");
+
+ RoleHierarchyImpl roleHierarchyImpl = new RoleHierarchyImpl();
+ roleHierarchyImpl.setHierarchy("ROLE_A > ROLE_B");
+
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthoritiesCompareByAuthorityString(roleHierarchyImpl.getReachableGrantedAuthorities(authorities0), authorities0));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthoritiesCompareByAuthorityString(roleHierarchyImpl.getReachableGrantedAuthorities(authorities1), authorities2));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthoritiesCompareByAuthorityString(roleHierarchyImpl.getReachableGrantedAuthorities(authorities2), authorities2));
+ }
+}
diff --git a/core/src/test/java/org/springframework/security/access/hierarchicalroles/TestHelperTests.java b/core/src/test/java/org/springframework/security/access/hierarchicalroles/TestHelperTests.java
index 4e3087ccc7..fbe292b7e6 100755
--- a/core/src/test/java/org/springframework/security/access/hierarchicalroles/TestHelperTests.java
+++ b/core/src/test/java/org/springframework/security/access/hierarchicalroles/TestHelperTests.java
@@ -1,55 +1,143 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.access.hierarchicalroles;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.AuthorityUtils;
-
-/**
- * Tests for {@link HierarchicalRolesTestHelper}.
- *
- * @author Michael Mayr
- */
-public class TestHelperTests {
-
- @Test
- public void testContainTheSameGrantedAuthorities() {
- List authorities1 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_B");
- List authorities2 = AuthorityUtils.createAuthorityList("ROLE_B","ROLE_A");
- List authorities3 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_C");
- List authorities4 = AuthorityUtils.createAuthorityList("ROLE_A");
- List authorities5 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_A");
-
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(null, null));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities1));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities2));
- assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities2, authorities1));
-
- assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(null, authorities1));
- assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, null));
- assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities3));
- assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities3, authorities1));
- assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities4));
- assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities4, authorities1));
- assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities4, authorities5));
- }
-
-}
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.access.hierarchicalroles;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.junit.Test;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
+
+/**
+ * Tests for {@link HierarchicalRolesTestHelper}.
+ *
+ * @author Michael Mayr
+ */
+public class TestHelperTests {
+
+ @Test
+ public void testContainTheSameGrantedAuthorities() {
+ List authorities1 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_B");
+ List authorities2 = AuthorityUtils.createAuthorityList("ROLE_B","ROLE_A");
+ List authorities3 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_C");
+ List authorities4 = AuthorityUtils.createAuthorityList("ROLE_A");
+ List authorities5 = AuthorityUtils.createAuthorityList("ROLE_A","ROLE_A");
+
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(null, null));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities1));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities2));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities2, authorities1));
+
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(null, authorities1));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, null));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities3));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities3, authorities1));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities4));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities4, authorities1));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities4, authorities5));
+ }
+
+ // SEC-863
+ @Test
+ public void testToListOfAuthorityStrings() {
+ List authorities1 = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_B");
+ List authorities2 = AuthorityUtils.createAuthorityList("ROLE_B", "ROLE_A");
+ List authorities3 = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_C");
+ List authorities4 = AuthorityUtils.createAuthorityList("ROLE_A");
+ List authorities5 = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_A");
+
+ List authoritiesStrings1 = new ArrayList();
+ authoritiesStrings1.add("ROLE_A");
+ authoritiesStrings1.add("ROLE_B");
+
+ List authoritiesStrings2 = new ArrayList();
+ authoritiesStrings2.add("ROLE_B");
+ authoritiesStrings2.add("ROLE_A");
+
+ List authoritiesStrings3 = new ArrayList();
+ authoritiesStrings3.add("ROLE_A");
+ authoritiesStrings3.add("ROLE_C");
+
+ List authoritiesStrings4 = new ArrayList();
+ authoritiesStrings4.add("ROLE_A");
+
+ List authoritiesStrings5 = new ArrayList();
+ authoritiesStrings5.add("ROLE_A");
+ authoritiesStrings5.add("ROLE_A");
+
+ assertTrue(CollectionUtils.isEqualCollection(
+ HierarchicalRolesTestHelper.toListOfAuthorityStrings(authorities1), authoritiesStrings1));
+
+ assertTrue(CollectionUtils.isEqualCollection(
+ HierarchicalRolesTestHelper.toListOfAuthorityStrings(authorities2), authoritiesStrings2));
+
+ assertTrue(CollectionUtils.isEqualCollection(
+ HierarchicalRolesTestHelper.toListOfAuthorityStrings(authorities3), authoritiesStrings3));
+
+ assertTrue(CollectionUtils.isEqualCollection(
+ HierarchicalRolesTestHelper.toListOfAuthorityStrings(authorities4), authoritiesStrings4));
+
+ assertTrue(CollectionUtils.isEqualCollection(
+ HierarchicalRolesTestHelper.toListOfAuthorityStrings(authorities5), authoritiesStrings5));
+ }
+
+ // SEC-863
+ @Test
+ public void testContainTheSameGrantedAuthoritiesCompareByAuthorityString() {
+ List authorities1 = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_B");
+ List authorities2 = AuthorityUtils.createAuthorityList("ROLE_B", "ROLE_A");
+ List authorities3 = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_C");
+ List authorities4 = AuthorityUtils.createAuthorityList("ROLE_A");
+ List authorities5 = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_A");
+
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(null, null));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities1));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities2));
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities2, authorities1));
+
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(null, authorities1));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, null));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities3));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities3, authorities1));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities1, authorities4));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities4, authorities1));
+ assertFalse(HierarchicalRolesTestHelper.containTheSameGrantedAuthorities(authorities4, authorities5));
+ }
+
+ // SEC-863
+ @Test
+ public void testContainTheSameGrantedAuthoritiesCompareByAuthorityStringWithAuthorityLists() {
+ List authorities1 = HierarchicalRolesTestHelper.createAuthorityList("ROLE_A", "ROLE_B");
+ List authorities2 = AuthorityUtils.createAuthorityList("ROLE_A", "ROLE_B");
+ assertTrue(HierarchicalRolesTestHelper.containTheSameGrantedAuthoritiesCompareByAuthorityString(authorities1, authorities2));
+ }
+
+ // SEC-863
+ @Test
+ public void testCreateAuthorityList() {
+ List authorities1 = HierarchicalRolesTestHelper.createAuthorityList("ROLE_A");
+ assertEquals(authorities1.size(), 1);
+ assertEquals("ROLE_A", authorities1.get(0).getAuthority());
+
+ List authorities2 = HierarchicalRolesTestHelper.createAuthorityList("ROLE_A", "ROLE_C");
+ assertEquals(authorities2.size(), 2);
+ assertEquals("ROLE_A", authorities2.get(0).getAuthority());
+ assertEquals("ROLE_C", authorities2.get(1).getAuthority());
+ }
+}