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; + } + +}