    1   /* Copyright 2004 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.afterinvocation;
    17
    18  import junit.framework.TestCase;
    19
    20  import org.acegisecurity.AccessDeniedException;
    21  import org.acegisecurity.ConfigAttributeDefinition;
    22  import org.acegisecurity.MockAclManager;
    23  import org.acegisecurity.SecurityConfig;
    24  import org.acegisecurity.acl.AclEntry;
    25  import org.acegisecurity.acl.AclManager;
    26  import org.acegisecurity.acl.basic.MockAclObjectIdentity;
    27  import org.acegisecurity.acl.basic.SimpleAclEntry;
    28  import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
    29  import org.acegisecurity.util.SimpleMethodInvocation;
    30
    31
    32  /***
    33   * Tests {@link BasicAclEntryAfterInvocationProvider}.
    34   *
    35   * @author Ben Alex
    36   * @version $Id: BasicAclEntryAfterInvocationProviderTests.java,v 1.5 2005/11/30 01:23:35 benalex Exp $
    37   */
    38  public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
    39      //~ Constructors ===========================================================
    40
    41      public BasicAclEntryAfterInvocationProviderTests() {
    42          super();
    43      }
    44
    45      public BasicAclEntryAfterInvocationProviderTests(String arg0) {
    46          super(arg0);
    47      }
    48
    49      //~ Methods ================================================================
    50
    51      public final void setUp() throws Exception {
    52          super.setUp();
    53      }
    54
    55      public static void main(String[] args) {
    56          junit.textui.TestRunner.run(BasicAclEntryAfterInvocationProviderTests.class);
    57      }
    58
    59      public void testCorrectOperationWhenPrincipalHasIncorrectPermissionToDomainObject()
    60          throws Exception {
    61          // Create an AclManager, granting scott only ADMINISTRATION rights
    62          AclManager aclManager = new MockAclManager("belmont", "scott",
    63                  new AclEntry[] {new SimpleAclEntry("scott",
    64                          new MockAclObjectIdentity(), null,
    65                          SimpleAclEntry.ADMINISTRATION)});
    66
    67          BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    68          provider.setAclManager(aclManager);
    69          provider.afterPropertiesSet();
    70
    71          // Create the Authentication and Config Attribs we'll be presenting
    72          UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott",
    73                  "NOT_USED");
    74          ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
    75          attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ"));
    76
    77          try {
    78              provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont");
    79              fail("Should have thrown AccessDeniedException");
    80          } catch (AccessDeniedException expected) {
    81              assertTrue(true);
    82          }
    83      }
    84
    85      public void testCorrectOperationWhenPrincipalHasNoPermissionToDomainObject()
    86          throws Exception {
    87          // Create an AclManager
    88          AclManager aclManager = new MockAclManager("belmont", "marissa",
    89                  new AclEntry[] {new MockAclEntry(), new SimpleAclEntry(
    90                          "marissa", new MockAclObjectIdentity(), null,
    91                          SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry(
    92                          "marissa", new MockAclObjectIdentity(), null,
    93                          SimpleAclEntry.READ), new SimpleAclEntry("marissa",
    94                          new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
    95
    96          BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    97          provider.setAclManager(aclManager);
    98          provider.afterPropertiesSet();
    99
    100         // Create the Authentication and Config Attribs we'll be presenting
    101         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("scott",
    102                 "NOT_USED");
    103         ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
    104         attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ"));
    105
    106         try {
    107             provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont");
    108             fail("Should have thrown AccessDeniedException");
    109         } catch (AccessDeniedException expected) {
    110             assertTrue(true);
    111         }
    112     }
    113
    114     public void testCorrectOperationWhenPrincipalIsAuthorised()
    115         throws Exception {
    116         // Create an AclManager
    117         AclManager aclManager = new MockAclManager("belmont", "marissa",
    118                 new AclEntry[] {new MockAclEntry(), new SimpleAclEntry(
    119                         "marissa", new MockAclObjectIdentity(), null,
    120                         SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry(
    121                         "marissa", new MockAclObjectIdentity(), null,
    122                         SimpleAclEntry.READ), new SimpleAclEntry("marissa",
    123                         new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
    124
    125         BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    126         provider.setAclManager(aclManager);
    127         assertEquals(aclManager, provider.getAclManager());
    128         provider.afterPropertiesSet();
    129
    130         // Create the Authentication and Config Attribs we'll be presenting
    131         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa",
    132                 "NOT_USED");
    133         ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
    134         attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ"));
    135
    136         // Filter
    137         assertEquals("belmont",
    138             provider.decide(auth, new SimpleMethodInvocation(), attr, "belmont"));
    139     }
    140
    141     public void testGrantsAccessIfReturnedObjectIsNull()
    142         throws Exception {
    143         // Create an AclManager
    144         AclManager aclManager = new MockAclManager("belmont", "marissa",
    145                 new AclEntry[] {new SimpleAclEntry("marissa",
    146                         new MockAclObjectIdentity(), null,
    147                         SimpleAclEntry.ADMINISTRATION), new SimpleAclEntry(
    148                         "marissa", new MockAclObjectIdentity(), null,
    149                         SimpleAclEntry.READ), new SimpleAclEntry("marissa",
    150                         new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()});
    151
    152         BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    153         provider.setAclManager(aclManager);
    154         provider.afterPropertiesSet();
    155
    156         // Create the Authentication and Config Attribs we'll be presenting
    157         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa",
    158                 "NOT_USED");
    159         ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
    160         attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ"));
    161
    162         // Filter
    163         assertNull(provider.decide(auth, new SimpleMethodInvocation(), attr, null));
    164     }
    165
    166     public void testRespectsModificationsToProcessConfigAttribute()
    167         throws Exception {
    168         // Create an AclManager
    169         AclManager aclManager = new MockAclManager("sydney", "marissa",
    170                 new AclEntry[] {new SimpleAclEntry("marissa",
    171                         new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()});
    172
    173         BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    174         provider.setAclManager(aclManager);
    175         assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute());
    176         provider.setProcessConfigAttribute("AFTER_ACL_ADMIN");
    177         assertEquals("AFTER_ACL_ADMIN", provider.getProcessConfigAttribute());
    178         provider.afterPropertiesSet();
    179
    180         // Create the Authentication and Config Attribs we'll be presenting
    181         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa",
    182                 "NOT_USED");
    183         ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
    184         attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ"));
    185
    186         // As no matching config attrib, ensure provider returns original obj
    187         assertEquals("sydney",
    188             provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney"));
    189
    190         // Filter, this time with the conf attrib provider setup to answer
    191         attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_ADMIN"));
    192         assertEquals("sydney",
    193             provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney"));
    194     }
    195
    196     public void testRespectsModificationsToRequirePermissions()
    197         throws Exception {
    198         // Create an AclManager
    199         AclManager aclManager = new MockAclManager("sydney", "marissa",
    200                 new AclEntry[] {new SimpleAclEntry("marissa",
    201                         new MockAclObjectIdentity(), null,
    202                         SimpleAclEntry.ADMINISTRATION), new MockAclEntry()});
    203
    204         BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    205         provider.setAclManager(aclManager);
    206         assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]);
    207         provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION});
    208         assertEquals(SimpleAclEntry.ADMINISTRATION,
    209             provider.getRequirePermission()[0]);
    210         provider.afterPropertiesSet();
    211
    212         // Create the Authentication and Config Attribs we'll be presenting
    213         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken("marissa",
    214                 "NOT_USED");
    215         ConfigAttributeDefinition attr = new ConfigAttributeDefinition();
    216         attr.addConfigAttribute(new SecurityConfig("AFTER_ACL_READ"));
    217
    218         // Filter
    219         assertEquals("sydney",
    220             provider.decide(auth, new SimpleMethodInvocation(), attr, "sydney"));
    221     }
    222
    223     public void testStartupDetectsMissingAclManager() throws Exception {
    224         BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    225
    226         try {
    227             provider.afterPropertiesSet();
    228             fail("Should have thrown IllegalArgumentException");
    229         } catch (IllegalArgumentException expected) {
    230             assertEquals("An aclManager is mandatory", expected.getMessage());
    231         }
    232     }
    233
    234     public void testStartupDetectsMissingProcessConfigAttribute()
    235         throws Exception {
    236         BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    237         AclManager aclManager = new MockAclManager("sydney", "marissa",
    238                 new AclEntry[] {new SimpleAclEntry("marissa",
    239                         new MockAclObjectIdentity(), null,
    240                         SimpleAclEntry.ADMINISTRATION), new MockAclEntry()});
    241         provider.setAclManager(aclManager);
    242
    243         provider.setProcessConfigAttribute(null);
    244
    245         try {
    246             provider.afterPropertiesSet();
    247             fail("Should have thrown IllegalArgumentException");
    248         } catch (IllegalArgumentException expected) {
    249             assertEquals("A processConfigAttribute is mandatory",
    250                 expected.getMessage());
    251         }
    252     }
    253
    254     public void testStartupDetectsMissingRequirePermission()
    255         throws Exception {
    256         BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
    257         AclManager aclManager = new MockAclManager("sydney", "marissa",
    258                 new AclEntry[] {new SimpleAclEntry("marissa",
    259                         new MockAclObjectIdentity(), null,
    260                         SimpleAclEntry.ADMINISTRATION), new MockAclEntry()});
    261         provider.setAclManager(aclManager);
    262
    263         provider.setRequirePermission(null);
    264
    265         try {
    266             provider.afterPropertiesSet();
    267             fail("Should have thrown IllegalArgumentException");
    268         } catch (IllegalArgumentException expected) {
    269             assertEquals("One or more requirePermission entries is mandatory",
    270                 expected.getMessage());
    271         }
    272     }
    273
    274     public void testSupportsAnything() {
    275         assertTrue(new BasicAclEntryAfterInvocationProvider().supports(
    276                 String.class));
    277     }
    278
    279     //~ Inner Classes ==========================================================
    280
    281     private class MockAclEntry implements AclEntry {
    282         // just so AclTag iterates some different types of AclEntrys
    283     }
    284 }