SEC-2151: Support binding method arguments with Annotations

This allow utilizing method arguments for method access control on
interfaces prior to JDK 8.
This commit is contained in:
Rob Winch
2013-09-27 11:18:37 -05:00
parent fb0a8d19e8
commit a09756745f
9 changed files with 547 additions and 36 deletions

View File

@@ -0,0 +1,106 @@
package org.springframework.security.core.parameters;
import static org.fest.assertions.Assertions.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.springframework.security.access.method.P;
import org.springframework.util.ReflectionUtils;
public class AnnotationParameterNameDiscovererTests {
private AnnotationParameterNameDiscoverer discoverer;
@Before
public void setup() {
discoverer = new AnnotationParameterNameDiscoverer(P.class.getName());
}
@Test
public void getParameterNamesInterfaceSingleParam() {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByTo", String.class))).isEqualTo(new String [] { "to"});
}
@Test
public void getParameterNamesInterfaceSingleParamAnnotatedWithMultiParams() {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByToAndFrom", String.class, String.class))).isNull();
}
@Test
public void getParameterNamesInterfaceNoAnnotation() {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByIdNoAnnotation", String.class))).isNull();
}
@Test
public void getParameterNamesClassSingleParam() {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByTo", String.class))).isEqualTo(new String [] { "to"});
}
@Test
public void getParameterNamesClassSingleParamAnnotatedWithMultiParams() {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByToAndFrom", String.class, String.class))).isNull();
}
@Test
public void getParameterNamesClassNoAnnotation() {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByIdNoAnnotation", String.class))).isNull();
}
@Test
public void getParameterNamesConstructor() throws Exception {
assertThat(discoverer.getParameterNames(Impl.class.getConstructor(String.class))).isEqualTo(new String[] { "id"});
}
@Test
public void getParameterNamesConstructorNoAnnotation() throws Exception {
assertThat(discoverer.getParameterNames(Impl.class.getConstructor(Long.class))).isNull();
}
@Test
public void getParameterNamesClassAnnotationOnInterface() throws Exception {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(DaoImpl.class, "findMessageByTo", String.class))).isEqualTo(new String[] {"to"});
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByTo", String.class))).isEqualTo(new String[] {"to"});
}
@Test
public void getParameterNamesClassAnnotationOnImpl() throws Exception {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByToAndFrom", String.class, String.class))).isNull();
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(DaoImpl.class, "findMessageByToAndFrom", String.class, String.class))).isEqualTo(new String[] {"to", "from"});
}
@Test
public void getParameterNamesClassAnnotationOnBaseClass() throws Exception {
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(Dao.class, "findMessageByIdNoAnnotation", String.class))).isNull();
assertThat(discoverer.getParameterNames(ReflectionUtils.findMethod(DaoImpl.class, "findMessageByIdNoAnnotation", String.class))).isEqualTo(new String[] {"id"});
}
interface Dao {
String findMessageByTo(@P("to") String to);
String findMessageByToAndFrom(@P("to") String to, String from);
String findMessageByIdNoAnnotation(String id);
}
static class BaseDaoImpl {
public String findMessageByIdNoAnnotation(@P("id") String id) { return null; }
}
static class DaoImpl extends BaseDaoImpl implements Dao {
public String findMessageByTo(String to) { return null; }
public String findMessageByToAndFrom(@P("to") String to, @P("from") String from) { return null; }
}
static class Impl {
public Impl(Long dataSourceId) {}
public Impl(@P("id") String dataSourceId) {}
String findMessageByTo(@P("to") String to) { return null; }
String findMessageByToAndFrom(@P("to") String to, String from) { return null; }
String findMessageByIdNoAnnotation(String id) { return null; }
}
}

View File

@@ -19,12 +19,14 @@ import static org.fest.assertions.Assertions.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.security.access.method.P;
import org.springframework.test.util.ReflectionTestUtils;
/**
@@ -45,8 +47,16 @@ public class DefaultSecurityParameterNameDiscovererTests {
public void constructorDefault() {
List<ParameterNameDiscoverer> discoverers = (List<ParameterNameDiscoverer>) ReflectionTestUtils
.getField(discoverer, "parameterNameDiscoverers");
assertThat(discoverers.size()).isEqualTo(1);
assertThat(discoverers.get(0)).isInstanceOf(
assertThat(discoverers.size()).isEqualTo(2);
ParameterNameDiscoverer annotationDisc = discoverers.get(0);
assertThat(annotationDisc).isInstanceOf(
AnnotationParameterNameDiscoverer.class);
Set<String> annotationsToUse = (Set<String>)ReflectionTestUtils.getField(annotationDisc, "annotationClassesToUse");
assertThat(annotationsToUse).containsOnly(P.class.getName());
assertThat(discoverers.get(1)).isInstanceOf(
DefaultParameterNameDiscoverer.class);
}
@@ -57,10 +67,17 @@ public class DefaultSecurityParameterNameDiscovererTests {
List<ParameterNameDiscoverer> discoverers = (List<ParameterNameDiscoverer>) ReflectionTestUtils
.getField(discoverer, "parameterNameDiscoverers");
assertThat(discoverers.size()).isEqualTo(2);
assertThat(discoverers.size()).isEqualTo(3);
assertThat(discoverers.get(0)).isInstanceOf(
LocalVariableTableParameterNameDiscoverer.class);
assertThat(discoverers.get(1)).isInstanceOf(
ParameterNameDiscoverer annotationDisc = discoverers.get(1);
assertThat(annotationDisc).isInstanceOf(
AnnotationParameterNameDiscoverer.class);
Set<String> annotationsToUse = (Set<String>)ReflectionTestUtils.getField(annotationDisc, "annotationClassesToUse");
assertThat(annotationsToUse).containsOnly(P.class.getName());
assertThat(discoverers.get(2)).isInstanceOf(
DefaultParameterNameDiscoverer.class);
}
}