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.context.rmi;
17  
18  import junit.framework.TestCase;
19  
20  import org.acegisecurity.Authentication;
21  import org.acegisecurity.TargetObject;
22  import org.acegisecurity.context.SecurityContextHolder;
23  import org.acegisecurity.context.SecurityContextImpl;
24  import org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocation;
25  import org.acegisecurity.context.rmi.ContextPropagatingRemoteInvocationFactory;
26  import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
27  import org.acegisecurity.util.SimpleMethodInvocation;
28  
29  import org.aopalliance.intercept.MethodInvocation;
30  
31  import java.lang.reflect.Method;
32  
33  
34  /***
35   * Tests {@link ContextPropagatingRemoteInvocation} and {@link
36   * ContextPropagatingRemoteInvocationFactory}.
37   *
38   * @author Ben Alex
39   * @version $Id: ContextPropagatingRemoteInvocationTests.java,v 1.7 2005/11/25 04:17:25 benalex Exp $
40   */
41  public class ContextPropagatingRemoteInvocationTests extends TestCase {
42      //~ Constructors ===========================================================
43  
44      public ContextPropagatingRemoteInvocationTests() {
45          super();
46      }
47  
48      public ContextPropagatingRemoteInvocationTests(String arg0) {
49          super(arg0);
50      }
51  
52      //~ Methods ================================================================
53  
54      public static void main(String[] args) {
55          junit.textui.TestRunner.run(ContextPropagatingRemoteInvocationTests.class);
56      }
57  
58      public void testNormalOperation() throws Exception {
59          // Setup client-side context
60          Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("marissa",
61                  "koala");
62          SecurityContextHolder.getContext().setAuthentication(clientSideAuthentication);
63  
64          ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation();
65  
66          // Set to null, as ContextPropagatingRemoteInvocation already obtained
67          // a copy and nulling is necessary to ensure the Context delivered by
68          // ContextPropagatingRemoteInvocation is used on server-side
69          SecurityContextHolder.setContext(new SecurityContextImpl());
70  
71          // The result from invoking the TargetObject should contain the
72          // Authentication class delivered via the SecurityContextHolder
73          assertEquals("some_string org.acegisecurity.providers.UsernamePasswordAuthenticationToken false",
74              remoteInvocation.invoke(new TargetObject()));
75      }
76  
77      public void testNullContextHolderDoesNotCauseInvocationProblems()
78          throws Exception {
79          SecurityContextHolder.getContext().setAuthentication(null); // just to be explicit
80  
81          ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation();
82          SecurityContextHolder.getContext().setAuthentication(null); // unnecessary, but for explicitness
83  
84          assertEquals("some_string Authentication empty",
85              remoteInvocation.invoke(new TargetObject()));
86      }
87  
88      public void testContextIsResetEvenIfExceptionOccurs() throws Exception {
89          // Setup client-side context
90          Authentication clientSideAuthentication = new UsernamePasswordAuthenticationToken("marissa",
91                  "koala");
92          SecurityContextHolder.getContext().setAuthentication(clientSideAuthentication);
93  
94          ContextPropagatingRemoteInvocation remoteInvocation = getRemoteInvocation();
95  
96          try {
97              // Set up the wrong arguments.
98              remoteInvocation.setArguments(new Object[] {});
99              remoteInvocation.invoke(TargetObject.class.newInstance());
100             fail("Expected IllegalArgumentException");
101         } catch(IllegalArgumentException e) {
102             // expected
103         }
104 
105         assertNull("Authentication must be null ", SecurityContextHolder.getContext().getAuthentication());
106 
107     }
108 
109 
110     private ContextPropagatingRemoteInvocation getRemoteInvocation()
111         throws Exception {
112         Class clazz = TargetObject.class;
113         Method method = clazz.getMethod("makeLowerCase",
114                 new Class[] {String.class});
115         MethodInvocation mi = new SimpleMethodInvocation(method,
116                 new Object[] {"SOME_STRING"});
117 
118         ContextPropagatingRemoteInvocationFactory factory = new ContextPropagatingRemoteInvocationFactory();
119 
120         return (ContextPropagatingRemoteInvocation) factory
121         .createRemoteInvocation(mi);
122     }
123 }