SEC-2114: Provide Spring Cache Abstraction based cache implementations
As of Spring 3.1 spring has its own cache abstraction. This commit adds cache imlpementations based on that abstraction.
This commit is contained in:
+172
@@ -0,0 +1,172 @@
|
||||
package org.springframework.security.acls.jdbc;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||
import org.springframework.security.acls.domain.*;
|
||||
import org.springframework.security.acls.model.MutableAcl;
|
||||
import org.springframework.security.acls.model.ObjectIdentity;
|
||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.util.FieldUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests {@link org.springframework.security.acls.domain.EhCacheBasedAclCache}
|
||||
*
|
||||
* @author Andrei Stefan
|
||||
*/
|
||||
public class SpringCacheBasedAclCacheTests {
|
||||
private static final String TARGET_CLASS = "org.springframework.security.acls.TargetObject";
|
||||
|
||||
private static CacheManager cacheManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void initCacheManaer() {
|
||||
cacheManager = new ConcurrentMapCacheManager();
|
||||
// Use disk caching immediately (to test for serialization issue reported in SEC-527)
|
||||
cacheManager.getCache("springcasebasedacltests");
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
private Cache getCache() {
|
||||
Cache cache = cacheManager.getCache("springcasebasedacltests");
|
||||
cache.clear();
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void constructorRejectsNullParameters() throws Exception {
|
||||
new SpringCacheBasedAclCache(null, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheOperationsAclWithoutParent() throws Exception {
|
||||
Cache cache = getCache();
|
||||
Map realCache = (Map) cache.getNativeCache();
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(100));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
AuditLogger auditLogger = new ConsoleAuditLogger();
|
||||
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache, permissionGrantingStrategy, aclAuthorizationStrategy);
|
||||
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, auditLogger);
|
||||
|
||||
assertEquals(0, realCache.size());
|
||||
myCache.putInCache(acl);
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
assertEquals(myCache.getFromCache(Long.valueOf(1)), acl);
|
||||
assertEquals(myCache.getFromCache(identity), acl);
|
||||
|
||||
// Put another object in cache
|
||||
ObjectIdentity identity2 = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(101));
|
||||
MutableAcl acl2 = new AclImpl(identity2, Long.valueOf(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
|
||||
|
||||
myCache.putInCache(acl2);
|
||||
|
||||
// Try to evict an entry that doesn't exist
|
||||
myCache.evictFromCache(Long.valueOf(3));
|
||||
myCache.evictFromCache(new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(102)));
|
||||
assertEquals(realCache.size(), 4);
|
||||
|
||||
myCache.evictFromCache(Long.valueOf(1));
|
||||
assertEquals(realCache.size(), 2);
|
||||
|
||||
// Check the second object inserted
|
||||
assertEquals(myCache.getFromCache(Long.valueOf(2)), acl2);
|
||||
assertEquals(myCache.getFromCache(identity2), acl2);
|
||||
|
||||
myCache.evictFromCache(identity2);
|
||||
assertEquals(realCache.size(), 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void cacheOperationsAclWithParent() throws Exception {
|
||||
Cache cache = getCache();
|
||||
Map realCache = (Map) cache.getNativeCache();
|
||||
|
||||
Authentication auth = new TestingAuthenticationToken("user", "password", "ROLE_GENERAL");
|
||||
auth.setAuthenticated(true);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
|
||||
ObjectIdentity identity = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(1));
|
||||
ObjectIdentity identityParent = new ObjectIdentityImpl(TARGET_CLASS, Long.valueOf(2));
|
||||
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(
|
||||
new SimpleGrantedAuthority("ROLE_OWNERSHIP"), new SimpleGrantedAuthority("ROLE_AUDITING"),
|
||||
new SimpleGrantedAuthority("ROLE_GENERAL"));
|
||||
AuditLogger auditLogger = new ConsoleAuditLogger();
|
||||
|
||||
PermissionGrantingStrategy permissionGrantingStrategy = new DefaultPermissionGrantingStrategy(auditLogger);
|
||||
SpringCacheBasedAclCache myCache = new SpringCacheBasedAclCache(cache, permissionGrantingStrategy, aclAuthorizationStrategy);
|
||||
|
||||
MutableAcl acl = new AclImpl(identity, Long.valueOf(1), aclAuthorizationStrategy, auditLogger);
|
||||
MutableAcl parentAcl = new AclImpl(identityParent, Long.valueOf(2), aclAuthorizationStrategy, auditLogger);
|
||||
|
||||
acl.setParent(parentAcl);
|
||||
|
||||
assertEquals(0, realCache.size());
|
||||
myCache.putInCache(acl);
|
||||
assertEquals(realCache.size(), 4);
|
||||
|
||||
// Check we can get from cache the same objects we put in
|
||||
AclImpl aclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(1));
|
||||
assertEquals(acl, aclFromCache);
|
||||
// SEC-951 check transient fields are set on parent
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "aclAuthorizationStrategy"));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache.getParentAcl(), "permissionGrantingStrategy"));
|
||||
assertEquals(acl, myCache.getFromCache(identity));
|
||||
assertNotNull(FieldUtils.getFieldValue(aclFromCache, "aclAuthorizationStrategy"));
|
||||
AclImpl parentAclFromCache = (AclImpl) myCache.getFromCache(Long.valueOf(2));
|
||||
assertEquals(parentAcl, parentAclFromCache);
|
||||
assertNotNull(FieldUtils.getFieldValue(parentAclFromCache, "aclAuthorizationStrategy"));
|
||||
assertEquals(parentAcl, myCache.getFromCache(identityParent));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockCache implements Cache {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "mockcache";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getNativeCache() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueWrapper get(Object key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(Object key, Object value) {}
|
||||
|
||||
@Override
|
||||
public void evict(Object key) {}
|
||||
|
||||
@Override
|
||||
public void clear() {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user