Browse Source

SEC-1049: RoleHierarchy in SidRetrievalStrategy. Added optional RoleHierarchy injection to SidRetrievalStrategyImpl

Luke Taylor 16 years ago
parent
commit
9639340fef

+ 17 - 2
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 <tt>RoleHierarchy</tt> injected in order to
+ * determine the extended list of authorities that the principal is assigned.
  * <p>
  * 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<Sid> getSids(Authentication authentication) {
-        List<GrantedAuthority> authorities = authentication.getAuthorities();
+        List<GrantedAuthority> authorities = roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
         List<Sid> sids = new ArrayList<Sid>(authorities.size() + 1);
 
         sids.add(new PrincipalSid(authentication));

+ 32 - 10
acl/src/test/java/org/springframework/security/acls/sid/SidRetrievalStrategyTests.java

@@ -1,10 +1,13 @@
 package org.springframework.security.acls.sid;
 
-import java.util.List;
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
 
-import junit.framework.Assert;
-import junit.framework.TestCase;
+import java.util.List;
 
+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<Sid> 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<GrantedAuthority> rhAuthorities = AuthorityUtils.createAuthorityList("D");
+        when(rh.getReachableGrantedAuthorities(anyList())).thenReturn(rhAuthorities);
+        SidRetrievalStrategy strat = new SidRetrievalStrategyImpl(rh);
+
+        List<Sid> 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());
     }
 }

+ 19 - 0
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<GrantedAuthority> getReachableGrantedAuthorities(List<GrantedAuthority> authorities) {
+        return authorities;
+    }
+
+}