浏览代码

SEC-2150: Add tests to verify JSR-250 Spec behavior

Rob Winch 11 年之前
父节点
当前提交
d429c96253

+ 108 - 1
core/src/test/java/org/springframework/security/access/annotation/Jsr250MethodDefinitionSourceTests.java

@@ -1,5 +1,6 @@
 package org.springframework.security.access.annotation;
 
+import static org.fest.assertions.Assertions.assertThat;
 import static org.junit.Assert.assertEquals;
 
 import java.util.Collection;
@@ -11,6 +12,7 @@ import junit.framework.Assert;
 
 import org.junit.Test;
 import org.springframework.security.access.ConfigAttribute;
+import org.springframework.security.access.intercept.method.MockMethodInvocation;
 
 /**
  * @author Luke Taylor
@@ -58,7 +60,87 @@ public class Jsr250MethodDefinitionSourceTests {
         assertEquals("ADMIN", accessAttributes.toArray()[0].toString());
     }
 
-//~ Inner Classes ======================================================================================================
+    // JSR-250 Spec Tests
+
+    /**
+     *  Class-level annotations only affect the class they annotate and their members, that
+     *  is, its methods and fields. They never affect a member declared by a superclass,
+     * even if it is not hidden or overridden by the class in question.
+     * @throws Exception
+     */
+    @Test
+    public void classLevelAnnotationsOnlyAffectTheClassTheyAnnotateAndTheirMembers() throws Exception {
+        Child target = new Child();
+        MockMethodInvocation mi = new MockMethodInvocation(target, target.getClass(), "notOverriden");
+
+        Collection<ConfigAttribute> accessAttributes = mds.getAttributes(mi);
+        assertThat(accessAttributes).isNull();
+    }
+
+    @Test
+    public void classLevelAnnotationsOnlyAffectTheClassTheyAnnotateAndTheirMembersOverriden() throws Exception {
+        Child target = new Child();
+        MockMethodInvocation mi = new MockMethodInvocation(target, target.getClass(), "overriden");
+
+        Collection<ConfigAttribute> accessAttributes = mds.getAttributes(mi);
+        assertEquals(1, accessAttributes.size());
+        assertEquals("DERIVED", accessAttributes.toArray()[0].toString());
+    }
+
+    @Test
+    public void classLevelAnnotationsImpactMemberLevel() throws Exception {
+        Child target = new Child();
+        MockMethodInvocation mi = new MockMethodInvocation(target, target.getClass(), "defaults");
+
+        Collection<ConfigAttribute> accessAttributes = mds.getAttributes(mi);
+        assertEquals(1, accessAttributes.size());
+        assertEquals("DERIVED", accessAttributes.toArray()[0].toString());
+    }
+
+    @Test
+    public void classLevelAnnotationsIgnoredByExplicitMemberAnnotation() throws Exception {
+        Child target = new Child();
+        MockMethodInvocation mi = new MockMethodInvocation(target, target.getClass(), "explicitMethod");
+
+        Collection<ConfigAttribute> accessAttributes = mds.getAttributes(mi);
+        assertEquals(1, accessAttributes.size());
+        assertEquals("EXPLICIT", accessAttributes.toArray()[0].toString());
+    }
+
+    /**
+     * The interfaces implemented by a class never contribute annotations to the class
+     * itself or any of its members.
+     * @throws Exception
+     */
+    @Test
+    public void interfacesNeverContributeAnnotationsMethodLevel() throws Exception {
+        Parent target = new Parent();
+        MockMethodInvocation mi = new MockMethodInvocation(target, target.getClass(), "interfaceMethod");
+
+        Collection<ConfigAttribute> accessAttributes = mds.getAttributes(mi);
+        assertThat(accessAttributes).isEmpty();
+    }
+
+    @Test
+    public void interfacesNeverContributeAnnotationsClassLevel() throws Exception {
+        Parent target = new Parent();
+        MockMethodInvocation mi = new MockMethodInvocation(target, target.getClass(), "notOverriden");
+
+        Collection<ConfigAttribute> accessAttributes = mds.getAttributes(mi);
+        assertThat(accessAttributes).isEmpty();
+    }
+
+    @Test
+    public void annotationsOnOverriddenMemberIgnored() throws Exception {
+        Child target = new Child();
+        MockMethodInvocation mi = new MockMethodInvocation(target, target.getClass(), "overridenIgnored");
+
+        Collection<ConfigAttribute> accessAttributes = mds.getAttributes(mi);
+        assertEquals(1, accessAttributes.size());
+        assertEquals("DERIVED", accessAttributes.toArray()[0].toString());
+    }
+
+    //~ Inner Classes ======================================================================================================
 
     public static class A {
 
@@ -78,4 +160,29 @@ public class Jsr250MethodDefinitionSourceTests {
         @RolesAllowed("ADMIN")
         public void adminMethod() {}
     }
+
+    // JSR-250 Spec
+
+    @RolesAllowed("IPARENT")
+    interface IParent {
+        @RolesAllowed("INTERFACEMETHOD")
+        void interfaceMethod();
+    }
+
+    static class Parent implements IParent {
+        public void interfaceMethod() {}
+        public void notOverriden() {}
+        public void overriden() {}
+        @RolesAllowed("OVERRIDENIGNORED")
+        public void overridenIgnored() {}
+    }
+
+    @RolesAllowed("DERIVED")
+    class Child extends Parent {
+        public void overriden() {}
+        public void overridenIgnored() {}
+        public void defaults() {}
+        @RolesAllowed("EXPLICIT")
+        public void explicitMethod() {}
+    }
 }