001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.acegisecurity.acl.basic;
017:
018: import junit.framework.TestCase;
019:
020: import org.acegisecurity.Authentication;
021: import org.acegisecurity.PopulatedDatabase;
022:
023: import org.acegisecurity.acl.AclEntry;
024: import org.acegisecurity.acl.basic.cache.BasicAclEntryHolder;
025: import org.acegisecurity.acl.basic.cache.NullAclEntryCache;
026: import org.acegisecurity.acl.basic.jdbc.JdbcDaoImpl;
027:
028: import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
029:
030: import java.util.HashMap;
031: import java.util.Map;
032:
033: /**
034: * Tests {@link BasicAclProvider}.
035: *
036: * @author Ben Alex
037: * @version $Id: BasicAclProviderTests.java 1496 2006-05-23 13:38:33Z benalex $
038: */
039: public class BasicAclProviderTests extends TestCase {
040: //~ Static fields/initializers =====================================================================================
041:
042: public static final String OBJECT_IDENTITY = "org.acegisecurity.acl.DomainObject";
043:
044: //~ Constructors ===================================================================================================
045:
046: public BasicAclProviderTests() {
047: super ();
048: }
049:
050: public BasicAclProviderTests(String arg0) {
051: super (arg0);
052: }
053:
054: //~ Methods ========================================================================================================
055:
056: public static void main(String[] args) {
057: junit.textui.TestRunner.run(BasicAclProviderTests.class);
058: }
059:
060: private JdbcDaoImpl makePopulatedJdbcDao() throws Exception {
061: JdbcDaoImpl dao = new JdbcDaoImpl();
062: dao.setDataSource(PopulatedDatabase.getDataSource());
063: dao.afterPropertiesSet();
064:
065: return dao;
066: }
067:
068: public final void setUp() throws Exception {
069: super .setUp();
070: }
071:
072: public void testCachingUsedProperly() throws Exception {
073: BasicAclProvider provider = new BasicAclProvider();
074: provider.setBasicAclDao(makePopulatedJdbcDao());
075:
076: MockCache cache = new MockCache();
077: provider.setBasicAclEntryCache(cache);
078:
079: assertEquals(0, cache.getGets());
080: assertEquals(0, cache.getGetsHits());
081: assertEquals(0, cache.getPuts());
082: assertEquals(0, cache.getBackingMap().size());
083:
084: Object object = new MockDomain(1); // has no parents
085: provider.getAcls(object);
086:
087: assertEquals(1, cache.getGets());
088: assertEquals(0, cache.getGetsHits());
089: assertEquals(1, cache.getPuts());
090: assertEquals(1, cache.getBackingMap().size());
091:
092: provider.getAcls(object);
093:
094: assertEquals(2, cache.getGets());
095: assertEquals(1, cache.getGetsHits());
096: assertEquals(1, cache.getPuts());
097: assertEquals(1, cache.getBackingMap().size());
098:
099: object = new MockDomain(1000); // does not exist
100:
101: provider.getAcls(object);
102:
103: assertEquals(3, cache.getGets());
104: assertEquals(1, cache.getGetsHits());
105: assertEquals(2, cache.getPuts());
106: assertEquals(2, cache.getBackingMap().size());
107:
108: provider.getAcls(object);
109:
110: assertEquals(4, cache.getGets());
111: assertEquals(2, cache.getGetsHits());
112: assertEquals(2, cache.getPuts());
113: assertEquals(2, cache.getBackingMap().size());
114:
115: provider.getAcls(object);
116:
117: assertEquals(5, cache.getGets());
118: assertEquals(3, cache.getGetsHits());
119: assertEquals(2, cache.getPuts());
120: assertEquals(2, cache.getBackingMap().size());
121: }
122:
123: public void testExceptionThrownIfUnsupportedObjectIsSubmitted()
124: throws Exception {
125: BasicAclProvider provider = new BasicAclProvider();
126: provider.setBasicAclDao(makePopulatedJdbcDao());
127:
128: // this one should NOT be supported, as it has no getId() method
129: assertFalse(provider.supports(new Integer(34)));
130:
131: // try anyway
132: try {
133: provider.getAcls(new Integer(34));
134: fail("Should have thrown IllegalArgumentException");
135: } catch (IllegalArgumentException expected) {
136: assertTrue(true);
137: }
138: }
139:
140: public void testGetAclsForInstanceNotFound() throws Exception {
141: BasicAclProvider provider = new BasicAclProvider();
142: provider.setBasicAclDao(makePopulatedJdbcDao());
143:
144: Object object = new MockDomain(546464646);
145: AclEntry[] acls = provider.getAcls(object);
146: assertNull(acls);
147: }
148:
149: public void testGetAclsForInstanceWithParentLevels()
150: throws Exception {
151: BasicAclProvider provider = new BasicAclProvider();
152: provider.setBasicAclDao(makePopulatedJdbcDao());
153:
154: Object object = new MockDomain(6);
155: AclEntry[] acls = provider.getAcls(object);
156: assertEquals(2, acls.length);
157:
158: assertEquals("scott", ((BasicAclEntry) acls[0]).getRecipient());
159: assertEquals(1, ((BasicAclEntry) acls[0]).getMask());
160: assertEquals("ROLE_SUPERVISOR", ((BasicAclEntry) acls[1])
161: .getRecipient());
162: }
163:
164: public void testGetAclsForInstanceWithParentLevelsButNoDirectAclsAgainstInstance()
165: throws Exception {
166: BasicAclProvider provider = new BasicAclProvider();
167: provider.setBasicAclDao(makePopulatedJdbcDao());
168:
169: Object object = new MockDomain(5);
170: AclEntry[] acls = provider.getAcls(object);
171:
172: assertEquals(3, acls.length);
173:
174: assertEquals("scott", ((BasicAclEntry) acls[0]).getRecipient());
175: assertEquals(14, ((BasicAclEntry) acls[0]).getMask());
176: assertEquals("ROLE_SUPERVISOR", ((BasicAclEntry) acls[1])
177: .getRecipient());
178: assertEquals(1, ((BasicAclEntry) acls[1]).getMask());
179: assertEquals(JdbcDaoImpl.RECIPIENT_USED_FOR_INHERITENCE_MARKER,
180: ((BasicAclEntry) acls[2]).getRecipient());
181: }
182:
183: public void testGetAclsWithAuthentication() throws Exception {
184: BasicAclProvider provider = new BasicAclProvider();
185: provider.setBasicAclDao(makePopulatedJdbcDao());
186:
187: Authentication scott = new UsernamePasswordAuthenticationToken(
188: "scott", "unused");
189:
190: Object object = new MockDomain(6);
191: AclEntry[] acls = provider.getAcls(object, scott);
192:
193: assertEquals(1, acls.length);
194: assertEquals("scott", ((BasicAclEntry) acls[0]).getRecipient());
195: }
196:
197: public void testGettersSetters() {
198: BasicAclProvider provider = new BasicAclProvider();
199: assertEquals(NullAclEntryCache.class, provider
200: .getBasicAclEntryCache().getClass());
201: assertEquals(NamedEntityObjectIdentity.class, provider
202: .getDefaultAclObjectIdentityClass());
203: assertEquals(GrantedAuthorityEffectiveAclsResolver.class,
204: provider.getEffectiveAclsResolver().getClass());
205:
206: provider.setBasicAclEntryCache(null);
207: assertNull(provider.getBasicAclEntryCache());
208:
209: provider.setDefaultAclObjectIdentityClass(null);
210: assertNull(provider.getDefaultAclObjectIdentityClass());
211:
212: provider.setEffectiveAclsResolver(null);
213: assertNull(provider.getEffectiveAclsResolver());
214:
215: provider.setBasicAclDao(new MockDao());
216: assertNotNull(provider.getBasicAclDao());
217:
218: assertNull(provider.getRestrictSupportToClass());
219: provider.setRestrictSupportToClass(SomeDomain.class);
220: assertEquals(SomeDomain.class, provider
221: .getRestrictSupportToClass());
222: }
223:
224: public void testStartupFailsIfNullAclDao() throws Exception {
225: BasicAclProvider provider = new BasicAclProvider();
226:
227: try {
228: provider.afterPropertiesSet();
229: fail("Should have thrown IllegalArgumentException");
230: } catch (IllegalArgumentException expected) {
231: assertTrue(true);
232: }
233: }
234:
235: public void testStartupFailsIfNullEffectiveAclsResolver()
236: throws Exception {
237: BasicAclProvider provider = new BasicAclProvider();
238: provider.setBasicAclDao(makePopulatedJdbcDao());
239:
240: provider.setEffectiveAclsResolver(null);
241:
242: try {
243: provider.afterPropertiesSet();
244: fail("Should have thrown IllegalArgumentException");
245: } catch (IllegalArgumentException expected) {
246: assertTrue(true);
247: }
248: }
249:
250: public void testStartupFailsIfNullEntryCache() throws Exception {
251: BasicAclProvider provider = new BasicAclProvider();
252: provider.setBasicAclDao(makePopulatedJdbcDao());
253:
254: provider.setBasicAclEntryCache(null);
255:
256: try {
257: provider.afterPropertiesSet();
258: fail("Should have thrown IllegalArgumentException");
259: } catch (IllegalArgumentException expected) {
260: assertTrue(true);
261: }
262: }
263:
264: public void testStartupFailsIfProblemWithAclObjectIdentityClass()
265: throws Exception {
266: BasicAclProvider provider = new BasicAclProvider();
267: provider.setBasicAclDao(makePopulatedJdbcDao());
268:
269: // check nulls rejected
270: provider.setDefaultAclObjectIdentityClass(null);
271:
272: try {
273: provider.afterPropertiesSet();
274: fail("Should have thrown IllegalArgumentException");
275: } catch (IllegalArgumentException expected) {
276: assertTrue(true);
277: }
278:
279: // check non-AclObjectIdentity classes are also rejected
280: provider.setDefaultAclObjectIdentityClass(String.class);
281:
282: try {
283: provider.afterPropertiesSet();
284: fail("Should have thrown IllegalArgumentException");
285: } catch (IllegalArgumentException expected) {
286: assertTrue(true);
287: }
288:
289: // check AclObjectIdentity class without constructor accepting a
290: // domain object is also rejected
291: provider
292: .setDefaultAclObjectIdentityClass(MockAclObjectIdentity.class);
293:
294: try {
295: provider.afterPropertiesSet();
296: fail("Should have thrown IllegalArgumentException");
297: } catch (IllegalArgumentException expected) {
298: assertEquals(
299: "defaultAclObjectIdentityClass must provide a constructor that accepts the domain object instance!",
300: expected.getMessage());
301: }
302: }
303:
304: public void testSupports() throws Exception {
305: BasicAclProvider provider = new BasicAclProvider();
306: provider.setBasicAclDao(makePopulatedJdbcDao());
307:
308: // this one should NOT be supported, as it has no getId() method
309: assertFalse(provider.supports(new Integer(34)));
310:
311: // this one SHOULD be supported, as it has a getId() method
312: assertTrue(provider.supports(new SomeDomain()));
313:
314: // this one SHOULD be supported, as it implements AclObjectIdentityAware
315: assertTrue(provider.supports(new MockDomain(4)));
316:
317: // now restrict the provider to only respond to SomeDomain.class requests
318: provider.setRestrictSupportToClass(SomeDomain.class);
319: assertEquals(SomeDomain.class, provider
320: .getRestrictSupportToClass());
321:
322: // this one SHOULD be supported, as it has a getId() method AND it meets the restrictSupportToClass criteria
323: assertTrue(provider.supports(new SomeDomain()));
324:
325: // this one should NOT be suported, as whilst it implement AclObjectIdentityAware (as proven earlier in the test), it does NOT meet the restrictSupportToClass criteria
326: assertFalse(provider.supports(new MockDomain(4)));
327: }
328:
329: public void testSupportsReturnsNullIfObjectNull() {
330: BasicAclProvider provider = new BasicAclProvider();
331: assertFalse(provider.supports(new Integer(34)));
332: }
333:
334: //~ Inner Classes ==================================================================================================
335:
336: private class MockCache implements BasicAclEntryCache {
337: private Map map = new HashMap();
338: private int gets = 0;
339: private int getsHits = 0;
340: private int puts = 0;
341:
342: public Map getBackingMap() {
343: return map;
344: }
345:
346: public BasicAclEntry[] getEntriesFromCache(
347: AclObjectIdentity aclObjectIdentity) {
348: gets++;
349:
350: Object result = map.get(aclObjectIdentity);
351:
352: if (result == null) {
353: return null;
354: }
355:
356: getsHits++;
357:
358: BasicAclEntryHolder holder = (BasicAclEntryHolder) result;
359:
360: return holder.getBasicAclEntries();
361: }
362:
363: public int getGets() {
364: return gets;
365: }
366:
367: public int getGetsHits() {
368: return getsHits;
369: }
370:
371: public int getPuts() {
372: return puts;
373: }
374:
375: public void putEntriesInCache(BasicAclEntry[] basicAclEntry) {
376: puts++;
377:
378: BasicAclEntryHolder holder = new BasicAclEntryHolder(
379: basicAclEntry);
380: map.put(basicAclEntry[0].getAclObjectIdentity(), holder);
381: }
382:
383: public void removeEntriesFromCache(
384: AclObjectIdentity aclObjectIdentity) {
385: }
386: }
387:
388: private class MockDao implements BasicAclDao {
389: public BasicAclEntry[] getAcls(
390: AclObjectIdentity aclObjectIdentity) {
391: return null;
392: }
393: }
394:
395: private class MockDomain implements AclObjectIdentityAware {
396: private int id;
397:
398: public MockDomain(int id) {
399: this .id = id;
400: }
401:
402: public AclObjectIdentity getAclObjectIdentity() {
403: return new NamedEntityObjectIdentity(OBJECT_IDENTITY,
404: new Integer(id).toString());
405: }
406: }
407: }
|