1   /* Copyright 2004, 2005 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.intercept.method.aspectj;
17  
18  import java.lang.reflect.Method;
19  
20  import junit.framework.TestCase;
21  
22  import org.acegisecurity.AccessDeniedException;
23  import org.acegisecurity.GrantedAuthority;
24  import org.acegisecurity.GrantedAuthorityImpl;
25  import org.acegisecurity.MockAccessDecisionManager;
26  import org.acegisecurity.MockApplicationContext;
27  import org.acegisecurity.MockAuthenticationManager;
28  import org.acegisecurity.MockJoinPoint;
29  import org.acegisecurity.MockRunAsManager;
30  import org.acegisecurity.TargetObject;
31  import org.acegisecurity.context.SecurityContextHolder;
32  import org.acegisecurity.intercept.method.MethodDefinitionMap;
33  import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
34  import org.acegisecurity.providers.TestingAuthenticationToken;
35  
36  
37  /***
38   * Tests {@link AspectJSecurityInterceptor}.
39   *
40   * @author Ben Alex
41   * @version $Id: AspectJSecurityInterceptorTests.java,v 1.8 2005/11/30 01:23:35 benalex Exp $
42   */
43  public class AspectJSecurityInterceptorTests extends TestCase {
44      //~ Constructors ===========================================================
45  
46      public AspectJSecurityInterceptorTests() {
47          super();
48      }
49  
50      public AspectJSecurityInterceptorTests(String arg0) {
51          super(arg0);
52      }
53  
54      //~ Methods ================================================================
55  
56      public final void setUp() throws Exception {
57          super.setUp();
58      }
59  
60      public static void main(String[] args) {
61          junit.textui.TestRunner.run(AspectJSecurityInterceptorTests.class);
62      }
63  
64      public void testCallbackIsInvokedWhenPermissionGranted()
65          throws Exception {
66          AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
67          si.setApplicationEventPublisher(MockApplicationContext.getContext());
68          si.setAccessDecisionManager(new MockAccessDecisionManager());
69          si.setAuthenticationManager(new MockAuthenticationManager());
70          si.setRunAsManager(new MockRunAsManager());
71  
72          MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
73          editor.setAsText(
74              "org.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO");
75  
76          MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
77          si.setObjectDefinitionSource(map);
78          assertEquals(map, si.getObjectDefinitionSource());
79  
80          si.afterPropertiesSet();
81  
82          Class clazz = TargetObject.class;
83          Method method = clazz.getMethod("countLength",
84                  new Class[] {String.class});
85          MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method);
86  
87          MockAspectJCallback aspectJCallback = new MockAspectJCallback();
88  
89          SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken(
90                  "marissa", "koala",
91                  new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_ONE")}));
92  
93          Object result = si.invoke(joinPoint, aspectJCallback);
94  
95          assertEquals("object proceeded", result);
96  
97          SecurityContextHolder.getContext().setAuthentication(null);
98      }
99  
100     public void testCallbackIsNotInvokedWhenPermissionDenied()
101         throws Exception {
102         AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
103         si.setApplicationEventPublisher(MockApplicationContext.getContext());
104         si.setAccessDecisionManager(new MockAccessDecisionManager());
105         si.setAuthenticationManager(new MockAuthenticationManager());
106         si.setRunAsManager(new MockRunAsManager());
107 
108         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
109         editor.setAsText(
110             "org.acegisecurity.TargetObject.countLength=MOCK_ONE,MOCK_TWO");
111 
112         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
113         si.setObjectDefinitionSource(map);
114 
115         si.afterPropertiesSet();
116 
117         Class clazz = TargetObject.class;
118         Method method = clazz.getMethod("countLength",
119                 new Class[] {String.class});
120         MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method);
121 
122         MockAspectJCallback aspectJCallback = new MockAspectJCallback();
123         aspectJCallback.setThrowExceptionIfInvoked(true);
124 
125         SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken(
126                 "marissa", "koala", new GrantedAuthority[] {}));
127 
128         try {
129             si.invoke(joinPoint, aspectJCallback);
130             fail("Should have thrown AccessDeniedException");
131         } catch (AccessDeniedException expected) {
132             assertTrue(true);
133         }
134 
135         SecurityContextHolder.getContext().setAuthentication(null);
136     }
137 
138     //~ Inner Classes ==========================================================
139 
140     private class MockAspectJCallback implements AspectJCallback {
141         private boolean throwExceptionIfInvoked = false;
142 
143         private MockAspectJCallback() {}
144 
145         public void setThrowExceptionIfInvoked(boolean throwExceptionIfInvoked) {
146             this.throwExceptionIfInvoked = throwExceptionIfInvoked;
147         }
148 
149         public Object proceedWithObject() {
150             if (throwExceptionIfInvoked) {
151                 throw new IllegalStateException("AspectJCallback proceeded");
152             }
153 
154             return "object proceeded";
155         }
156     }
157 }