    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;
    17
    18  import junit.framework.TestCase;
    19
    20  import org.acegisecurity.ConfigAttribute;
    21  import org.acegisecurity.ConfigAttributeDefinition;
    22  import org.acegisecurity.GrantedAuthority;
    23  import org.acegisecurity.GrantedAuthorityImpl;
    24  import org.acegisecurity.ITargetObject;
    25  import org.acegisecurity.OtherTargetObject;
    26  import org.acegisecurity.SecurityConfig;
    27  import org.acegisecurity.TargetObject;
    28  import org.acegisecurity.acl.basic.SomeDomain;
    29  import org.acegisecurity.context.SecurityContextHolder;
    30  import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
    31  import org.acegisecurity.util.SimpleMethodInvocation;
    32
    33  import org.springframework.context.ApplicationContext;
    34  import org.springframework.context.support.ClassPathXmlApplicationContext;
    35
    36  import java.lang.reflect.Method;
    37
    38  import java.util.HashSet;
    39  import java.util.Iterator;
    40  import java.util.Set;
    41
    42
    43  /***
    44   * Tests {@link MethodDefinitionAttributes}.
    45   *
    46   * @author Cameron Braid
    47   * @author Ben Alex
    48   * @version $Id: MethodDefinitionAttributesTests.java,v 1.9 2005/11/25 04:17:24 benalex Exp $
    49   */
    50  public class MethodDefinitionAttributesTests extends TestCase {
    51      //~ Instance fields ========================================================
    52
    53      ClassPathXmlApplicationContext applicationContext;
    54
    55      //~ Constructors ===========================================================
    56
    57      public MethodDefinitionAttributesTests(String a) {
    58          super(a);
    59      }
    60
    61      //~ Methods ================================================================
    62
    63      public final void setUp() throws Exception {
    64          super.setUp();
    65      }
    66
    67      public static void main(String[] args) {
    68          junit.textui.TestRunner.run(MethodDefinitionAttributesTests.class);
    69      }
    70
    71      public void testAttributesForInterfaceTargetObject()
    72          throws Exception {
    73          ConfigAttributeDefinition def1 = getConfigAttributeDefinition(ITargetObject.class,
    74                  "countLength", new Class[] {String.class});
    75          Set set1 = toSet(def1);
    76          assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE")));
    77          assertTrue(set1.contains(
    78                  new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH")));
    79
    80          ConfigAttributeDefinition def2 = getConfigAttributeDefinition(ITargetObject.class,
    81                  "makeLowerCase", new Class[] {String.class});
    82          Set set2 = toSet(def2);
    83          assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE")));
    84          assertTrue(set2.contains(
    85                  new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")));
    86
    87          ConfigAttributeDefinition def3 = getConfigAttributeDefinition(ITargetObject.class,
    88                  "makeUpperCase", new Class[] {String.class});
    89          Set set3 = toSet(def3);
    90          assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE")));
    91          assertTrue(set3.contains(
    92                  new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE")));
    93      }
    94
    95      public void testAttributesForOtherTargetObject() throws Exception {
    96          ConfigAttributeDefinition def1 = getConfigAttributeDefinition(OtherTargetObject.class,
    97                  "countLength", new Class[] {String.class});
    98          Set set1 = toSet(def1);
    99          assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE")));
    100         assertTrue(set1.contains(
    101                 new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH")));
    102
    103         // Confirm MOCK_CLASS_METHOD_COUNT_LENGTH not added, as it's a String (not a ConfigAttribute)
    104         // Confirm also MOCK_CLASS not added, as we return null for class
    105         assertEquals(2, set1.size());
    106
    107         ConfigAttributeDefinition def2 = getConfigAttributeDefinition(OtherTargetObject.class,
    108                 "makeLowerCase", new Class[] {String.class});
    109         Set set2 = toSet(def2);
    110         assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE")));
    111         assertTrue(set2.contains(
    112                 new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")));
    113         assertTrue(set2.contains(
    114                 new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE")));
    115
    116         // Confirm MOCK_CLASS not added, as we return null for class
    117         assertEquals(3, set2.size());
    118
    119         ConfigAttributeDefinition def3 = getConfigAttributeDefinition(OtherTargetObject.class,
    120                 "makeUpperCase", new Class[] {String.class});
    121         Set set3 = toSet(def3);
    122         assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE")));
    123         assertTrue(set3.contains(
    124                 new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE")));
    125         assertTrue(set3.contains(new SecurityConfig("RUN_AS"))); // defined against interface
    126
    127         assertEquals(3, set3.size());
    128     }
    129
    130     public void testAttributesForTargetObject() throws Exception {
    131         ConfigAttributeDefinition def1 = getConfigAttributeDefinition(TargetObject.class,
    132                 "countLength", new Class[] {String.class});
    133         Set set1 = toSet(def1);
    134         assertTrue(set1.contains(new SecurityConfig("MOCK_INTERFACE")));
    135         assertTrue(set1.contains(
    136                 new SecurityConfig("MOCK_INTERFACE_METHOD_COUNT_LENGTH")));
    137
    138         assertTrue(set1.contains(new SecurityConfig("MOCK_CLASS")));
    139
    140         // Confirm the MOCK_CLASS_METHOD_COUNT_LENGTH was not added, as it's not a ConfigAttribute
    141         assertEquals(3, set1.size());
    142
    143         ConfigAttributeDefinition def2 = getConfigAttributeDefinition(TargetObject.class,
    144                 "makeLowerCase", new Class[] {String.class});
    145         Set set2 = toSet(def2);
    146         assertTrue(set2.contains(new SecurityConfig("MOCK_INTERFACE")));
    147         assertTrue(set2.contains(
    148                 new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")));
    149         assertTrue(set2.contains(new SecurityConfig("MOCK_CLASS")));
    150         assertTrue(set2.contains(
    151                 new SecurityConfig("MOCK_CLASS_METHOD_MAKE_LOWER_CASE")));
    152         assertEquals(4, set2.size());
    153
    154         ConfigAttributeDefinition def3 = getConfigAttributeDefinition(TargetObject.class,
    155                 "makeUpperCase", new Class[] {String.class});
    156         Set set3 = toSet(def3);
    157         assertTrue(set3.contains(new SecurityConfig("MOCK_INTERFACE")));
    158         assertTrue(set3.contains(
    159                 new SecurityConfig("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE")));
    160         assertTrue(set3.contains(new SecurityConfig("MOCK_CLASS")));
    161         assertTrue(set3.contains(
    162                 new SecurityConfig("MOCK_CLASS_METHOD_MAKE_UPPER_CASE")));
    163         assertTrue(set3.contains(new SecurityConfig("RUN_AS")));
    164         assertEquals(5, set3.size());
    165     }
    166
    167     public void testMethodCallWithRunAsReplacement() throws Exception {
    168         UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
    169                 "Password",
    170                 new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_UPPER_CASE")});
    171         SecurityContextHolder.getContext().setAuthentication(token);
    172
    173         ITargetObject target = makeInterceptedTarget();
    174         String result = target.makeUpperCase("hello");
    175         assertEquals("HELLO org.acegisecurity.MockRunAsAuthenticationToken true",
    176             result);
    177
    178         SecurityContextHolder.getContext().setAuthentication(null);
    179     }
    180
    181     public void testMethodCallWithoutRunAsReplacement()
    182         throws Exception {
    183         UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test",
    184                 "Password",
    185                 new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_INTERFACE_METHOD_MAKE_LOWER_CASE")});
    186         SecurityContextHolder.getContext().setAuthentication(token);
    187
    188         ITargetObject target = makeInterceptedTarget();
    189         String result = target.makeLowerCase("HELLO");
    190
    191         assertEquals("hello org.acegisecurity.providers.UsernamePasswordAuthenticationToken true",
    192             result);
    193
    194         SecurityContextHolder.getContext().setAuthentication(null);
    195     }
    196
    197     public void testNullReturnedIfZeroAttributesDefinedForMethodInvocation()
    198         throws Exception {
    199         // SomeDomain is not defined in the MockAttributes()
    200         // (which getConfigAttributeDefinition refers to)
    201         ConfigAttributeDefinition def = getConfigAttributeDefinition(SomeDomain.class,
    202                 "getId", null);
    203         assertNull(def);
    204     }
    205
    206     private ConfigAttributeDefinition getConfigAttributeDefinition(
    207         Class clazz, String methodName, Class[] args) throws Exception {
    208         final Method method = clazz.getMethod(methodName, args);
    209         MethodDefinitionAttributes source = new MethodDefinitionAttributes();
    210         source.setAttributes(new MockAttributes());
    211
    212         ConfigAttributeDefinition config = source.getAttributes(new SimpleMethodInvocation() {
    213                     public Method getMethod() {
    214                         return method;
    215                     }
    216                 });
    217
    218         return config;
    219     }
    220
    221     private ITargetObject makeInterceptedTarget() {
    222         ApplicationContext context = new ClassPathXmlApplicationContext(
    223                 "org/acegisecurity/intercept/method/applicationContext.xml");
    224
    225         return (ITargetObject) context.getBean("target");
    226     }
    227
    228     /***
    229      * convert a <code>ConfigAttributeDefinition</code> into a set of
    230      * <code>ConfigAttribute</code>(s)
    231      *
    232      * @param def the <code>ConfigAttributeDefinition</code> to cover
    233      *
    234      * @return a Set of <code>ConfigAttributes</code>
    235      */
    236     private Set toSet(ConfigAttributeDefinition def) {
    237         Set set = new HashSet();
    238         Iterator i = def.getConfigAttributes();
    239
    240         while (i.hasNext()) {
    241             ConfigAttribute a = (ConfigAttribute) i.next();
    242             set.add(a);
    243         }
    244
    245         return set;
    246     }
    247 }