From 42721d407b3a75b73c368d1b65f645a3efcac9f8 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Tue, 24 Aug 2010 18:22:54 +0100 Subject: [PATCH] Added tests for acls/afterinvocation package --- ...InvocationCollectionFilteringProvider.java | 4 +- .../AclEntryAfterInvocationProvider.java | 10 +- ...ationCollectionFilteringProviderTests.java | 64 +++++++++++ .../AclEntryAfterInvocationProviderTests.java | 101 ++++++++++++++++++ 4 files changed, 169 insertions(+), 10 deletions(-) create mode 100644 acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java create mode 100644 acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java b/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java index 19cf8d0f9b..2ddcf12230 100644 --- a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java +++ b/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java @@ -75,9 +75,7 @@ public class AclEntryAfterInvocationCollectionFilteringProvider extends Abstract Object returnedObject) throws AccessDeniedException { if (returnedObject == null) { - if (logger.isDebugEnabled()) { - logger.debug("Return object is null, skipping"); - } + logger.debug("Return object is null, skipping"); return null; } diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java b/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java index 4d120dc4a6..113f53b153 100644 --- a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java +++ b/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java @@ -65,7 +65,7 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme //~ Constructors =================================================================================================== public AclEntryAfterInvocationProvider(AclService aclService, List requirePermission) { - super(aclService, "AFTER_ACL_READ", requirePermission); + this(aclService, "AFTER_ACL_READ", requirePermission); } public AclEntryAfterInvocationProvider(AclService aclService, String processConfigAttribute, @@ -81,17 +81,13 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme if (returnedObject == null) { // AclManager interface contract prohibits nulls // As they have permission to null/nothing, grant access - if (logger.isDebugEnabled()) { - logger.debug("Return object is null, skipping"); - } + logger.debug("Return object is null, skipping"); return null; } if (!getProcessDomainObjectClass().isAssignableFrom(returnedObject.getClass())) { - if (logger.isDebugEnabled()) { - logger.debug("Return object is not applicable for this provider, skipping"); - } + logger.debug("Return object is not applicable for this provider, skipping"); return returnedObject; } diff --git a/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java b/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java new file mode 100644 index 0000000000..4a53134feb --- /dev/null +++ b/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java @@ -0,0 +1,64 @@ +package org.springframework.security.acls.afterinvocation; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.SecurityConfig; +import org.springframework.security.acls.model.*; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.SpringSecurityMessageSource; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author Luke Taylor + */ +@SuppressWarnings({"unchecked"}) +public class AclEntryAfterInvocationCollectionFilteringProviderTests { + @Test + public void objectsAreRemovedIfPermissionDenied() throws Exception { + AclService service = mock(AclService.class); + Acl acl = mock(Acl.class); + when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(false); + when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(acl); + AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(service, Arrays.asList(mock(Permission.class))); + provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class)); + provider.setProcessDomainObjectClass(Object.class); + provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class)); + + Object returned = provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), new ArrayList(Arrays.asList(new Object(), new Object()))); + assertTrue(returned instanceof List); + assertTrue(((List)returned).isEmpty()); + returned = provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("UNSUPPORTED", "AFTER_ACL_COLLECTION_READ"), new Object[] {new Object(), new Object()}); + assertTrue(returned instanceof Object[]); + assertTrue(((Object[])returned).length == 0); + } + + @Test + public void accessIsGrantedIfNoAttributesDefined() throws Exception { + AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(mock(AclService.class), Arrays.asList(mock(Permission.class))); + Object returned = new Object(); + + assertSame(returned, provider.decide(mock(Authentication.class), new Object(), Collections.emptyList(), returned)); + } + + @Test + public void nullReturnObjectIsIgnored() throws Exception { + AclService service = mock(AclService.class); + AclEntryAfterInvocationCollectionFilteringProvider provider = new AclEntryAfterInvocationCollectionFilteringProvider(service, Arrays.asList(mock(Permission.class))); + + assertNull(provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null)); + verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class)); + } + +} diff --git a/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java b/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java new file mode 100644 index 0000000000..53a99f395f --- /dev/null +++ b/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java @@ -0,0 +1,101 @@ +package org.springframework.security.acls.afterinvocation; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.*; + +import org.junit.Test; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.ConfigAttribute; +import org.springframework.security.access.SecurityConfig; +import org.springframework.security.acls.model.*; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.SpringSecurityMessageSource; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author Luke Taylor + */ +@SuppressWarnings({"unchecked"}) +public class AclEntryAfterInvocationProviderTests { + + @Test(expected=IllegalArgumentException.class) + public void rejectsMissingPermissions() throws Exception { + try { + new AclEntryAfterInvocationProvider(mock(AclService.class), null); + fail("Exception expected"); + } catch (IllegalArgumentException expected) { + } + new AclEntryAfterInvocationProvider(mock(AclService.class), Collections.emptyList()); + } + + @Test + public void accessIsAllowedIfPermissionIsGranted() { + AclService service = mock(AclService.class); + Acl acl = mock(Acl.class); + when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(true); + when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(acl); + AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service, Arrays.asList(mock(Permission.class))); + provider.setMessageSource(new SpringSecurityMessageSource()); + provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class)); + provider.setProcessDomainObjectClass(Object.class); + provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class)); + Object returned = new Object(); + + assertSame(returned, provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_READ"), returned)); + } + + @Test + public void accessIsGrantedIfNoAttributesDefined() throws Exception { + AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(mock(AclService.class), Arrays.asList(mock(Permission.class))); + Object returned = new Object(); + + assertSame(returned, provider.decide(mock(Authentication.class), new Object(), Collections.emptyList(), returned)); + } + + @Test + public void accessIsGrantedIfObjectTypeNotSupported() throws Exception { + AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(mock(AclService.class), Arrays.asList(mock(Permission.class))); + provider.setProcessDomainObjectClass(String.class); + // Not a String + Object returned = new Object(); + + assertSame(returned, provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_READ"), returned)); + } + + + @Test(expected= AccessDeniedException.class) + public void accessIsDeniedIfPermissionIsNotGranted() { + AclService service = mock(AclService.class); + Acl acl = mock(Acl.class); + when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenReturn(false); + // Try a second time with no permissions found + when(acl.isGranted(any(List.class), any(List.class), anyBoolean())).thenThrow(new NotFoundException("")); + when(service.readAclById(any(ObjectIdentity.class), any(List.class))).thenReturn(acl); + AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service, Arrays.asList(mock(Permission.class))); + provider.setProcessConfigAttribute("MY_ATTRIBUTE"); + provider.setMessageSource(new SpringSecurityMessageSource()); + provider.setObjectIdentityRetrievalStrategy(mock(ObjectIdentityRetrievalStrategy.class)); + provider.setProcessDomainObjectClass(Object.class); + provider.setSidRetrievalStrategy(mock(SidRetrievalStrategy.class)); + try { + provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object()); + fail(); + } catch (AccessDeniedException expected) { + } + // Second scenario with no acls found + provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("UNSUPPORTED", "MY_ATTRIBUTE"), new Object()); + } + + @Test + public void nullReturnObjectIsIgnored() throws Exception { + AclService service = mock(AclService.class); + AclEntryAfterInvocationProvider provider = new AclEntryAfterInvocationProvider(service, Arrays.asList(mock(Permission.class))); + + assertNull(provider.decide(mock(Authentication.class), new Object(), SecurityConfig.createList("AFTER_ACL_COLLECTION_READ"), null)); + verify(service, never()).readAclById(any(ObjectIdentity.class), any(List.class)); + } +}