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 }