    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 }