diff --git a/acl/src/main/java/org/springframework/security/acls/domain/SidRetrievalStrategyImpl.java b/acl/src/main/java/org/springframework/security/acls/domain/SidRetrievalStrategyImpl.java
index 706626ed4f..10ffcb767e 100644
--- a/acl/src/main/java/org/springframework/security/acls/domain/SidRetrievalStrategyImpl.java
+++ b/acl/src/main/java/org/springframework/security/acls/domain/SidRetrievalStrategyImpl.java
@@ -18,14 +18,18 @@ package org.springframework.security.acls.domain;
import java.util.ArrayList;
import java.util.List;
+import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
+import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.acls.model.Sid;
import org.springframework.security.acls.model.SidRetrievalStrategy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
+import org.springframework.util.Assert;
/**
* Basic implementation of {@link SidRetrievalStrategy} that creates a {@link Sid} for the principal, as well as
- * every granted authority the principal holds.
+ * every granted authority the principal holds. Can optionally have a RoleHierarchy injected in order to
+ * determine the extended list of authorities that the principal is assigned.
*
* The returned array will always contain the {@link PrincipalSid} before any {@link GrantedAuthoritySid} elements.
*
@@ -33,10 +37,21 @@ import org.springframework.security.core.GrantedAuthority;
* @version $Id$
*/
public class SidRetrievalStrategyImpl implements SidRetrievalStrategy {
+
+ private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
+
+ public SidRetrievalStrategyImpl() {
+ }
+
+ public SidRetrievalStrategyImpl(RoleHierarchy roleHierarchy) {
+ Assert.notNull(roleHierarchy, "RoleHierarchy must not be null");
+ this.roleHierarchy = roleHierarchy;
+ }
+
//~ Methods ========================================================================================================
public List getSids(Authentication authentication) {
- List authorities = authentication.getAuthorities();
+ List authorities = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
List sids = new ArrayList(authorities.size() + 1);
sids.add(new PrincipalSid(authentication));
diff --git a/acl/src/test/java/org/springframework/security/acls/sid/SidRetrievalStrategyTests.java b/acl/src/test/java/org/springframework/security/acls/sid/SidRetrievalStrategyTests.java
index 5b341ce27b..882cc1a1d4 100644
--- a/acl/src/test/java/org/springframework/security/acls/sid/SidRetrievalStrategyTests.java
+++ b/acl/src/test/java/org/springframework/security/acls/sid/SidRetrievalStrategyTests.java
@@ -1,10 +1,13 @@
package org.springframework.security.acls.sid;
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
import java.util.List;
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
+import org.junit.Test;
+import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.acls.domain.GrantedAuthoritySid;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.domain.SidRetrievalStrategyImpl;
@@ -12,18 +15,23 @@ import org.springframework.security.acls.model.Sid;
import org.springframework.security.acls.model.SidRetrievalStrategy;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.AuthorityUtils;
/**
* Tests for {@link SidRetrievalStrategyImpl}
*
* @author Andrei Stefan
+ * @author Luke Taylor
*/
-public class SidRetrievalStrategyTests extends TestCase {
+@SuppressWarnings("unchecked")
+public class SidRetrievalStrategyTests {
+ Authentication authentication = new TestingAuthenticationToken("scott", "password", "A", "B", "C");
//~ Methods ========================================================================================================
- public void testSidsRetrieval() throws Exception {
- Authentication authentication = new TestingAuthenticationToken("scott", "password", "ROLE_1", "ROLE_2", "ROLE_3");
+ @Test
+ public void correctSidsAreRetrieved() throws Exception {
SidRetrievalStrategy retrStrategy = new SidRetrievalStrategyImpl();
List sids = retrStrategy.getSids(authentication);
@@ -36,9 +44,23 @@ public class SidRetrievalStrategyTests extends TestCase {
assertTrue(sids.get(i) instanceof GrantedAuthoritySid);
}
- Assert.assertEquals("scott", ((PrincipalSid) sids.get(0)).getPrincipal());
- Assert.assertEquals("ROLE_1", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
- Assert.assertEquals("ROLE_2", ((GrantedAuthoritySid) sids.get(2)).getGrantedAuthority());
- Assert.assertEquals("ROLE_3", ((GrantedAuthoritySid) sids.get(3)).getGrantedAuthority());
+ assertEquals("scott", ((PrincipalSid) sids.get(0)).getPrincipal());
+ assertEquals("A", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
+ assertEquals("B", ((GrantedAuthoritySid) sids.get(2)).getGrantedAuthority());
+ assertEquals("C", ((GrantedAuthoritySid) sids.get(3)).getGrantedAuthority());
+ }
+
+ @Test
+ public void roleHierarchyIsUsedWhenSet() throws Exception {
+ RoleHierarchy rh = mock(RoleHierarchy.class);
+ List rhAuthorities = AuthorityUtils.createAuthorityList("D");
+ when(rh.getReachableGrantedAuthorities(anyList())).thenReturn(rhAuthorities);
+ SidRetrievalStrategy strat = new SidRetrievalStrategyImpl(rh);
+
+ List sids = strat.getSids(authentication);
+ assertEquals(2, sids.size());
+ assertNotNull(sids.get(0));
+ assertTrue(sids.get(0) instanceof PrincipalSid);
+ assertEquals("D", ((GrantedAuthoritySid) sids.get(1)).getGrantedAuthority());
}
}
diff --git a/core/src/main/java/org/springframework/security/access/hierarchicalroles/NullRoleHierarchy.java b/core/src/main/java/org/springframework/security/access/hierarchicalroles/NullRoleHierarchy.java
new file mode 100644
index 0000000000..e5b871d099
--- /dev/null
+++ b/core/src/main/java/org/springframework/security/access/hierarchicalroles/NullRoleHierarchy.java
@@ -0,0 +1,19 @@
+package org.springframework.security.access.hierarchicalroles;
+
+import java.util.List;
+
+import org.springframework.security.core.GrantedAuthority;
+
+/**
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ * @since 3.0
+ */
+public final class NullRoleHierarchy implements RoleHierarchy {
+
+ public List getReachableGrantedAuthorities(List authorities) {
+ return authorities;
+ }
+
+}