/* Copyright 2013 Rigas Grigoropoulos * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package eu.europeana.aas.acl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.acls.domain.BasePermission; import org.springframework.security.acls.domain.GrantedAuthoritySid; import org.springframework.security.acls.domain.ObjectIdentityImpl; import org.springframework.security.acls.domain.PrincipalSid; import org.springframework.security.acls.model.AccessControlEntry; import org.springframework.security.acls.model.Acl; import org.springframework.security.acls.model.AlreadyExistsException; import org.springframework.security.acls.model.MutableAcl; import org.springframework.security.acls.model.MutableAclService; import org.springframework.security.acls.model.NotFoundException; import org.springframework.security.acls.model.ObjectIdentity; import org.springframework.security.acls.model.Sid; import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.annotation.ExpectedException; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.datastax.driver.core.Session; import eu.europeana.aas.acl.repository.CassandraAclRepository; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:/default-context.xml"}) public class CassandraAclServiceTestAdvanced extends CassandraTestBase { private static final String sid1 = "sid1@system"; private static final String sid2 = "sid2@system"; private static final String aoi_id = "123"; private static final String aoi_class = "a.b.c.Class"; private static final String ROLE_ADMIN = "ROLE_ADMIN"; @Autowired private MutableAclService service; @Autowired private CassandraAclRepository repository; @Before public void setUp() throws Exception { repository.createAoisTable(); repository.createAclsTable(); repository.createChilrenTable(); SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken(sid1, "password", Arrays.asList(new SimpleGrantedAuthority[] { new SimpleGrantedAuthority( ROLE_ADMIN) }))); } @After public void tearDown() throws Exception { } @Test public void testDeleteAclWithChildrenReccursion() { // Create parent ObjectIdentity parentObjectIdentity = createDefaultTestOI(); MutableAcl parentMutableAcl = service.createAcl(parentObjectIdentity); assertAcl(parentObjectIdentity, parentMutableAcl, sid1); // Create 1st level child ObjectIdentity firstChildObjectIdentity = new ObjectIdentityImpl(aoi_class, "456"); MutableAcl firstChildMutableAcl = service.createAcl(firstChildObjectIdentity); assertAcl(firstChildObjectIdentity, firstChildMutableAcl, sid1); // Set parent to 1st level child firstChildMutableAcl.setParent(parentMutableAcl); MutableAcl updatedFirstChildMutableAcl = service.updateAcl(firstChildMutableAcl); assertAcl(firstChildMutableAcl, updatedFirstChildMutableAcl); // Create 2nd level child ObjectIdentity secondChildObjectIdentity = new ObjectIdentityImpl(aoi_class, "789"); MutableAcl secondChildMutableAcl = service.createAcl(secondChildObjectIdentity); assertAcl(secondChildObjectIdentity, secondChildMutableAcl, sid1); // Set parent to 2nd level child secondChildMutableAcl.setParent(updatedFirstChildMutableAcl); MutableAcl updatedSecondChildMutableAcl = service.updateAcl(secondChildMutableAcl); assertAcl(secondChildMutableAcl, updatedSecondChildMutableAcl); // Delete parent service.deleteAcl(parentObjectIdentity, true); // Check all objects deleted List<ObjectIdentity> deletedObjects = Arrays.asList(new ObjectIdentity[] { parentObjectIdentity, firstChildObjectIdentity, secondChildObjectIdentity }); for (ObjectIdentity oi : deletedObjects) { try { service.readAclById(oi); fail("Expected NotFoundException"); } catch (NotFoundException e) { // Expected exception } } } @Test public void testCreateFindUpdateDeleteAclWithParent() { // Test createAcl ObjectIdentity parentObjectIdentity = createDefaultTestOI(); MutableAcl parentMutableAcl = service.createAcl(parentObjectIdentity); assertAcl(parentObjectIdentity, parentMutableAcl, sid1); // Test readAclById(ObjectIdentity) Acl parentAcl = service.readAclById(parentObjectIdentity); assertAcl(parentObjectIdentity, parentAcl, sid1); // Test updateAcl parentMutableAcl.setEntriesInheriting(true); parentMutableAcl.setOwner(new GrantedAuthoritySid(ROLE_ADMIN)); MutableAcl updatedParentMutableAcl = service.updateAcl(parentMutableAcl); assertAcl(parentMutableAcl, updatedParentMutableAcl); // Test createAcl ObjectIdentity childObjectIdentity = new ObjectIdentityImpl(aoi_class, "567"); MutableAcl childMutableAcl = service.createAcl(childObjectIdentity); assertAcl(childObjectIdentity, childMutableAcl, sid1); // Test updateAcl childMutableAcl.setParent(updatedParentMutableAcl); childMutableAcl.insertAce(0, BasePermission.READ, new PrincipalSid(sid1), true); childMutableAcl.insertAce(1, BasePermission.WRITE, new PrincipalSid(sid2), true); childMutableAcl.insertAce(2, BasePermission.DELETE, new PrincipalSid(sid2), true); MutableAcl updatedchildMutableAcl = service.updateAcl(childMutableAcl); assertAcl(childMutableAcl, updatedchildMutableAcl); // Test readAclById(ObjectIdentity) Acl childAcl = service.readAclById(childObjectIdentity); assertAcl(updatedchildMutableAcl, childAcl); // Test readAclById(ObjectIdentity, List<Sid>) without Sid filter childAcl = service.readAclById(childObjectIdentity, null); assertAcl(updatedchildMutableAcl, childAcl); // Test readAclById(ObjectIdentity, List<Sid>) with all Sids in filter childAcl = service.readAclById(childObjectIdentity, Arrays.asList(new Sid[] { new PrincipalSid(sid1), new PrincipalSid(sid2) })); assertAcl(updatedchildMutableAcl, childAcl); // Test readAclById(ObjectIdentity, List<Sid>) with one Sid in filter childAcl = service.readAclById(childObjectIdentity, Arrays.asList(new Sid[] { new PrincipalSid(sid1) })); assertAcl(updatedchildMutableAcl, childAcl); // Test readAclsById(List<ObjectIdentity>) Map<ObjectIdentity, Acl> resultMap = service.readAclsById(Arrays.asList(new ObjectIdentity[] { childObjectIdentity })); assertEquals(1, resultMap.size()); assertAcl(updatedchildMutableAcl, resultMap.values().iterator().next()); // Test readAclsById(List<ObjectIdentity>, List<Sid) without Sid filter resultMap = service.readAclsById(Arrays.asList(new ObjectIdentity[] { childObjectIdentity }), null); assertEquals(1, resultMap.size()); assertAcl(updatedchildMutableAcl, resultMap.values().iterator().next()); // Test readAclsById(List<ObjectIdentity>, List<Sid) with all Sids in filter resultMap = service.readAclsById(Arrays.asList(new ObjectIdentity[] { childObjectIdentity }), Arrays.asList(new Sid[] { new PrincipalSid(sid1), new PrincipalSid(sid2) })); assertEquals(1, resultMap.size()); assertAcl(updatedchildMutableAcl, resultMap.values().iterator().next()); // Test readAclsById(List<ObjectIdentity>, List<Sid) with one Sid in filter resultMap = service.readAclsById(Arrays.asList(new ObjectIdentity[] { childObjectIdentity }), Arrays.asList(new Sid[] { new PrincipalSid(sid1) })); assertEquals(1, resultMap.size()); assertAcl(updatedchildMutableAcl, resultMap.values().iterator().next()); // Test findChildren List<ObjectIdentity> children = service.findChildren(updatedParentMutableAcl.getObjectIdentity()); assertNotNull(children); assertEquals(1, children.size()); assertEquals(childObjectIdentity, children.get(0)); // Test deleteAcl service.deleteAcl(parentObjectIdentity, true); try { service.readAclById(childObjectIdentity); fail("Expected NotFoundException"); } catch (NotFoundException e) { // Expected exception } try { service.readAclById(parentObjectIdentity); fail("Expected NotFoundException"); } catch (NotFoundException e) { // Expected exception } children = service.findChildren(updatedParentMutableAcl.getObjectIdentity()); assertNull(children); } @Test(expected = IllegalArgumentException.class) public void testCreateNullAcl() { service.createAcl(null); } @Test(expected = AlreadyExistsException.class) public void testCreateAlreadyExisting() { ObjectIdentity oi = createDefaultTestOI(); service.createAcl(oi); service.createAcl(oi); } @Test(expected = IllegalArgumentException.class) public void testDeleteNullAcl() { service.deleteAcl(null, false); } @Test public void testDeleteAclNotExisting() { ObjectIdentity oi = createDefaultTestOI(); service.deleteAcl(oi, false); } @Test(expected = IllegalArgumentException.class) public void testUpdateNullAcl() { service.updateAcl(null); } @Test(expected = NotFoundException.class) public void testUpdateAclNotExisting() { ObjectIdentity oi = createDefaultTestOI(); MutableAcl acl = service.createAcl(oi); service.deleteAcl(oi, false); service.updateAcl(acl); } @Test(expected = IllegalArgumentException.class) public void testFindChildrenNullAcl() { service.findChildren(null); } @Test public void testFindChildrenAclNotExisting() { ObjectIdentity oi = createDefaultTestOI(); List<ObjectIdentity> result = service.findChildren(oi); assertNull(result); } @Test(expected = IllegalArgumentException.class) public void testReadAclByIdNullAcl() { service.readAclById(null); } @Test(expected = NotFoundException.class) public void testReadAclByIdAclNotExisting() { ObjectIdentity oi = createDefaultTestOI(); service.readAclById(oi); } @Test(expected = IllegalArgumentException.class) public void testReadAclByIdWithSidFilteringNullAcl() { service.readAclById(null, null); } @Test(expected = NotFoundException.class) public void testReadAclByIdWithSidFilteringAclNotExisting() { ObjectIdentity oi = createDefaultTestOI(); service.readAclById(oi); } @Test(expected = IllegalArgumentException.class) public void testReadAclsByIdNullAclList() { service.readAclsById(null); } @Test(expected = IllegalArgumentException.class) public void testReadAclsByIdEmptyAclList() { service.readAclsById(new ArrayList<ObjectIdentity>()); } @Test(expected = NotFoundException.class) public void testReadAclsByIdAclNotExisting() { ObjectIdentity oi = createDefaultTestOI(); service.readAclsById(Arrays.asList(new ObjectIdentity[] { oi })); } @Test(expected = NotFoundException.class) public void testReadAclsByIdOneAclNotExisting() { ObjectIdentity oi1 = createDefaultTestOI(); service.createAcl(oi1); ObjectIdentity oi2 = new ObjectIdentityImpl(aoi_class, "invalid"); service.readAclsById(Arrays.asList(new ObjectIdentity[] { oi1, oi2 })); } @Test(expected = IllegalArgumentException.class) public void testReadAclsByIdWithSidFilteringNullAclList() { service.readAclsById(null, null); } @Test(expected = IllegalArgumentException.class) public void testReadAclsByIdWithSidFilteringEmptyAclList() { service.readAclsById(new ArrayList<ObjectIdentity>(), null); } @Test(expected = NotFoundException.class) public void testReadAclsByIdWithSidFilteringAclNotExisting() { ObjectIdentity oi = createDefaultTestOI(); service.readAclsById(Arrays.asList(new ObjectIdentity[] { oi }), null); } private ObjectIdentity createDefaultTestOI() { ObjectIdentity oi = new ObjectIdentityImpl(aoi_class, aoi_id); return oi; } private void assertAcl(ObjectIdentity expected, Acl actual, String owner) { assertEquals(expected.getType(), actual.getObjectIdentity().getType()); assertEquals(expected.getIdentifier(), actual.getObjectIdentity().getIdentifier()); if (owner.startsWith("ROLE_")) { assertEquals(new GrantedAuthoritySid(owner), actual.getOwner()); } else { assertEquals(new PrincipalSid(owner), actual.getOwner()); } } private void assertAcl(Acl expected, Acl actual) { assertEquals(expected.getObjectIdentity().getType(), actual.getObjectIdentity().getType()); assertEquals(expected.getObjectIdentity().getIdentifier(), actual.getObjectIdentity().getIdentifier()); assertEquals(expected.getOwner(), actual.getOwner()); assertEquals(expected.isEntriesInheriting(), actual.isEntriesInheriting()); if (expected.getEntries() != null && actual.getEntries() != null) { assertEquals(expected.getEntries().size(), actual.getEntries().size()); for (int i = 0; i < expected.getEntries().size(); i++) { assertAclEntry(expected.getEntries().get(i), actual.getEntries().get(i)); } } else { assertEquals(expected.getEntries(), actual.getEntries()); } if (expected.getParentAcl() != null && actual.getParentAcl() != null) { assertAcl(expected.getParentAcl(), actual.getParentAcl()); } else { assertEquals(expected.getParentAcl(), actual.getParentAcl()); } } private void assertAclEntry(AccessControlEntry expected, AccessControlEntry actual) { StringBuilder sb = new StringBuilder(); sb.append(expected.getAcl().getObjectIdentity().getType()).append(":"); sb.append(expected.getAcl().getObjectIdentity().getIdentifier()).append(":"); if (expected.getSid() instanceof GrantedAuthoritySid) { sb.append(((GrantedAuthoritySid) expected.getSid()).getGrantedAuthority()); } else if (expected.getSid() instanceof PrincipalSid) { sb.append(((PrincipalSid) expected.getSid()).getPrincipal()); } sb.append(":").append(expected.getAcl().getEntries().indexOf(expected)); assertEquals(sb.toString(), actual.getId()); assertEquals(expected.getPermission(), actual.getPermission()); assertEquals(expected.getSid(), actual.getSid()); assertEquals(expected.isGranting(), actual.isGranting()); } }