1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.shiro.guice.aop;
20
21 import com.google.inject.Binding;
22 import com.google.inject.Key;
23 import com.google.inject.name.Named;
24 import com.google.inject.name.Names;
25 import com.google.inject.spi.Element;
26 import com.google.inject.spi.Elements;
27 import com.google.inject.spi.InterceptorBinding;
28 import org.aopalliance.intercept.MethodInterceptor;
29 import org.apache.shiro.aop.*;
30 import org.apache.shiro.authz.annotation.*;
31 import org.apache.shiro.authz.aop.*;
32 import org.junit.Before;
33 import org.junit.Test;
34
35 import java.lang.annotation.*;
36 import java.lang.reflect.Method;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40
41 import static org.junit.Assert.*;
42
43 public class ShiroAopModuleTest {
44 @Test
45 public void testGetAnnotationResolver() {
46
47 final AnnotationResolver annotationResolver = new DefaultAnnotationResolver();
48
49 ShiroAopModule underTest = new ShiroAopModule() {
50
51 @Override
52 protected AnnotationResolver createAnnotationResolver() {
53 return annotationResolver;
54 }
55
56 @Override
57 protected void configureDefaultInterceptors(AnnotationResolver resolver) {
58 assertSame(annotationResolver, resolver);
59 bind(Object.class).annotatedWith(Names.named("configureDefaultInterceptors"));
60 }
61
62 @Override
63 protected void configureInterceptors(AnnotationResolver resolver) {
64 assertSame(annotationResolver, resolver);
65 bind(Object.class).annotatedWith(Names.named("configureInterceptors"));
66 }
67 };
68
69 boolean calledDefault = false;
70 boolean calledCustom = false;
71
72 for (Element e : Elements.getElements(underTest)) {
73 if (e instanceof Binding) {
74 Key key = ((Binding) e).getKey();
75 if (Named.class.isAssignableFrom(key.getAnnotation().annotationType())
76 && "configureInterceptors".equals(((Named) key.getAnnotation()).value())
77 && key.getTypeLiteral().getRawType().equals(Object.class)) {
78 calledCustom = true;
79 }
80 if (Named.class.isAssignableFrom(key.getAnnotation().annotationType())
81 && "configureDefaultInterceptors".equals(((Named) key.getAnnotation()).value())
82 && key.getTypeLiteral().getRawType().equals(Object.class)) {
83 calledDefault = true;
84 }
85 }
86 }
87 }
88
89 @Test
90 public void testBindShiroInterceptor() {
91
92
93 ShiroAopModule underTest = new ShiroAopModule() {
94 @Override
95 protected void configureInterceptors(AnnotationResolver resolver) {
96 bindShiroInterceptor(new MyAnnotationMethodInterceptor());
97 }
98 };
99
100 List<Element> elements = Elements.getElements(underTest);
101
102 for (Element element : elements) {
103 if (element instanceof InterceptorBinding) {
104 InterceptorBinding binding = (InterceptorBinding) element;
105 assertTrue(binding.getClassMatcher().matches(getClass()));
106 Method method = null;
107 Class<? extends Annotation> theAnnotation = null;
108
109 for (Class<? extends Annotation> annotation : protectedMethods.keySet()) {
110 if (binding.getMethodMatcher().matches(protectedMethods.get(annotation))) {
111 method = protectedMethods.get(annotation);
112 theAnnotation = annotation;
113 protectedMethods.remove(annotation);
114 break;
115 }
116 }
117
118 if (method == null) {
119 fail("Did not expect interceptor binding " + binding.getInterceptors());
120 }
121
122 List<MethodInterceptor> interceptors = binding.getInterceptors();
123 assertEquals(1, interceptors.size());
124 assertTrue(interceptors.get(0) instanceof AopAllianceMethodInterceptorAdapter);
125 assertTrue(interceptorTypes.get(theAnnotation).isInstance(((AopAllianceMethodInterceptorAdapter) interceptors.get(0)).shiroInterceptor));
126
127 }
128 }
129
130 assertTrue("Not all interceptors were bound.", protectedMethods.isEmpty());
131 }
132
133 @Target({ElementType.TYPE, ElementType.METHOD})
134 @Retention(RetentionPolicy.RUNTIME)
135 private static @interface MyTestAnnotation {
136 }
137
138 private static class MyAnnotationHandler extends AnnotationHandler {
139
140
141
142
143
144
145
146 public MyAnnotationHandler(Class<? extends Annotation> annotationClass) {
147 super(annotationClass);
148 }
149 }
150
151 private static class MyAnnotationMethodInterceptor extends AnnotationMethodInterceptor {
152 public MyAnnotationMethodInterceptor() {
153 super(new MyAnnotationHandler(MyTestAnnotation.class));
154 }
155
156 public Object invoke(MethodInvocation methodInvocation) throws Throwable {
157 return null;
158 }
159 }
160
161
162 @RequiresRoles("role")
163 public void roleProtected() {
164
165 }
166
167 @RequiresPermissions("permission")
168 public void permissionProtected() {
169
170 }
171
172 @RequiresAuthentication
173 public void authProtected() {
174
175 }
176
177 @RequiresUser
178 public void userProtected() {
179
180 }
181
182 @RequiresGuest
183 public void guestProtected() {
184
185 }
186
187 @ShiroAopModuleTest.MyTestAnnotation
188 public void myTestProtected() {
189
190 }
191
192 private Map<Class<? extends Annotation>, Method> protectedMethods;
193 private Map<Class<? extends Annotation>, Class<? extends AnnotationMethodInterceptor>> interceptorTypes;
194
195 @Before
196 public void setup() throws NoSuchMethodException {
197 protectedMethods = new HashMap<Class<? extends Annotation>, Method>();
198 protectedMethods.put(RequiresRoles.class, getClass().getMethod("roleProtected"));
199 protectedMethods.put(RequiresPermissions.class, getClass().getMethod("permissionProtected"));
200 protectedMethods.put(RequiresAuthentication.class, getClass().getMethod("authProtected"));
201 protectedMethods.put(RequiresUser.class, getClass().getMethod("userProtected"));
202 protectedMethods.put(RequiresGuest.class, getClass().getMethod("guestProtected"));
203 protectedMethods.put(MyTestAnnotation.class, getClass().getMethod("myTestProtected"));
204
205 interceptorTypes = new HashMap<Class<? extends Annotation>, Class<? extends AnnotationMethodInterceptor>>();
206 interceptorTypes.put(RequiresRoles.class, RoleAnnotationMethodInterceptor.class);
207 interceptorTypes.put(RequiresPermissions.class, PermissionAnnotationMethodInterceptor.class);
208 interceptorTypes.put(RequiresAuthentication.class, AuthenticatedAnnotationMethodInterceptor.class);
209 interceptorTypes.put(RequiresUser.class, UserAnnotationMethodInterceptor.class);
210 interceptorTypes.put(RequiresGuest.class, GuestAnnotationMethodInterceptor.class);
211 interceptorTypes.put(MyTestAnnotation.class, MyAnnotationMethodInterceptor.class);
212 }
213 }