|
@@ -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() {}
|
|
|
+ }
|
|
|
}
|