/** * Copyright (C) 2010 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xcmis.spi.tck; import static org.junit.Assert.fail; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.xcmis.spi.CmisConstants; import org.xcmis.spi.ConstraintException; import org.xcmis.spi.ItemsTree; import org.xcmis.spi.NotSupportedException; import org.xcmis.spi.model.AccessControlEntry; import org.xcmis.spi.model.AccessControlPropagation; import org.xcmis.spi.model.CapabilityACL; import org.xcmis.spi.model.TypeDefinition; import org.xcmis.spi.utils.CmisUtils; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; public class ACLTest extends BaseTest { private static String testRootFolderId; private static TypeDefinition controllableAclType; private static TypeDefinition notControllableAclType; private static String controllableAclObject; private static String notControllableAclObject; private static String principal = "root"; @BeforeClass public static void start() throws Exception { testRootFolderId = createFolder(rootFolderID, CmisConstants.FOLDER, "acl_testroot", null, null, null); List<ItemsTree<TypeDefinition>> allTypes = connection.getTypeDescendants(null, -1, true); controllableAclType = getControllableAclType(allTypes); notControllableAclType = getNotControllableAclType(allTypes); if (controllableAclType != null) { switch (controllableAclType.getBaseId()) { case DOCUMENT : controllableAclObject = createDocument(testRootFolderId, controllableAclType.getId(), generateName(controllableAclType, null), null, null, null, null, null); break; case FOLDER : controllableAclObject = createFolder(testRootFolderId, controllableAclType.getId(), generateName(controllableAclType, null), null, null, null); break; case POLICY : controllableAclObject = createPolicy(testRootFolderId, controllableAclType.getId(), generateName(controllableAclType, null), null, null, null, null); break; case RELATIONSHIP : String sourceId = createDocument(testRootFolderId, CmisConstants.DOCUMENT, generateName(connection .getTypeDefinition(CmisConstants.DOCUMENT), null), null, null, null, null, null); String targetId = createDocument(testRootFolderId, CmisConstants.DOCUMENT, generateName(connection .getTypeDefinition(CmisConstants.DOCUMENT), null), null, null, null, null, null); controllableAclObject = createRelationship(controllableAclType.getId(), generateName(controllableAclType, null), sourceId, targetId, null, null, null); break; } } if (notControllableAclType != null) { switch (notControllableAclType.getBaseId()) { case DOCUMENT : notControllableAclObject = createDocument(testRootFolderId, notControllableAclType.getId(), generateName(notControllableAclType, null), null, null, null, null, null); break; case FOLDER : notControllableAclObject = createFolder(testRootFolderId, notControllableAclType.getId(), generateName(notControllableAclType, null), null, null, null); break; case POLICY : notControllableAclObject = createPolicy(testRootFolderId, notControllableAclType.getId(), generateName(notControllableAclType, null), null, null, null, null); break; case RELATIONSHIP : String sourceId = createDocument(testRootFolderId, CmisConstants.DOCUMENT, generateName(connection .getTypeDefinition(CmisConstants.DOCUMENT), null), null, null, null, null, null); String targetId = createDocument(testRootFolderId, CmisConstants.DOCUMENT, generateName(connection .getTypeDefinition(CmisConstants.DOCUMENT), null), null, null, null, null, null); notControllableAclObject = createRelationship(notControllableAclType.getId(), generateName(notControllableAclType, null), sourceId, targetId, null, null, null); break; } } System.out.println("Running ACL Service tests"); } @AfterClass public static void stop() throws Exception { if (testRootFolderId != null) { clear(testRootFolderId); } } /** * 2.2.10.2 Adds or removes the given ACEs to or from the ACL of document or * folder object. * * @throws Exception */ @Test public void testApplyACL_Add() throws Exception { if (controllableAclObject == null) { return; } if (capabilities.getCapabilityACL() == CapabilityACL.MANAGE) { List<AccessControlEntry> acl = createACL(principal, "cmis:write"); try { connection.applyACL(controllableAclObject, acl, null, aclCapability.getPropagation()); List<AccessControlEntry> actualACL = connection.getACL(controllableAclObject, false); validateACL(acl); checkACL(acl, actualACL); } finally { // Restore previous ACL. connection.applyACL(controllableAclObject, null, acl, aclCapability.getPropagation()); } } } /** * 2.2.10.2.3 At least one of the specified values for permission in ANY of * the ACEs does not match ANY of the permissionNames as returned by * getACLCapability and is not a CMIS Basic permission * * @throws Exception */ @Test public void testApplyACL_ConstraintException_ACLNotMatch() throws Exception { if (notControllableAclObject == null) { return; } if (capabilities.getCapabilityACL() == CapabilityACL.MANAGE) { List<AccessControlEntry> acl = createACL(principal, "cmis:unknown"); try { connection.applyACL(notControllableAclObject, acl, null, aclCapability.getPropagation()); fail("ConstraintException must be thrown since type is not controllable by ACL."); } catch (ConstraintException e) { } } } /** * 2.2.10.2.3 The value for ACLPropagation does not match the values as * returned via getACLCapabilities. * * @throws Exception */ @Test public void testApplyACL_ConstraintException_ACLPropagation() throws Exception { if (controllableAclObject == null) { return; } if (capabilities.getCapabilityACL() == CapabilityACL.MANAGE) { int l = AccessControlPropagation.values().length; AccessControlPropagation propagation = aclCapability.getPropagation(); // Propagation which is not supported. int ord = propagation.ordinal(); int p = ord == l - 1 ? ord - 1 : ord + 1; AccessControlPropagation propagation1 = AccessControlPropagation.values()[p]; if (propagation != AccessControlPropagation.REPOSITORYDETERMINED) { try { connection.applyACL(controllableAclObject, createACL(principal, "cmis:write"), null, propagation1); } catch (ConstraintException e) { } } } } /** * 2.2.10.2.3 The specified object's Object-Type definition's attribute for * controllableACL is FALSE. * * @throws Exception */ @Test public void testApplyACL_ConstraintException_NotControllable() throws Exception { if (notControllableAclObject == null) { return; } if (capabilities.getCapabilityACL() == CapabilityACL.MANAGE) { List<AccessControlEntry> acl = createACL(principal, "cmis:write"); try { connection.applyACL(notControllableAclObject, acl, null, aclCapability.getPropagation()); fail("ConstraintException must be thrown since type is not controllable by ACL."); } catch (ConstraintException e) { } } } /** * Managing of ACL is not supported but discovering may be supported. * * @throws Exception */ @Test public void testApplyACL_NotSupportedException() throws Exception { // If managing is not supported then try to apply ACL to any type and // expect for org.xcmis.spi.NotSupportedException. if (controllableAclObject != null && capabilities.getCapabilityACL() != CapabilityACL.MANAGE) { List<AccessControlEntry> acl = createACL(principal, "cmis:write"); try { connection.applyACL(controllableAclObject, acl, null, aclCapability.getPropagation()); fail("NotSupportedException must be thrown since managing of ACL is not supported."); } catch (NotSupportedException e) { } } } /** * 2.2.10.1 Get the ACL currently applied to the specified document or folder * object. * * @throws Exception */ @Test public void testGetACL() throws Exception { if (capabilities.getCapabilityACL() == CapabilityACL.NONE || controllableAclObject == null) { return; } List<AccessControlEntry> actualACL = connection.getACL(controllableAclObject, false); if (actualACL.size() > 0) { // May contains some ACEs which are inherited from parent or assigned by repository itself. Map<String, Set<String>> m1 = new HashMap<String, Set<String>>(); CmisUtils.addAclToPermissionMap(m1, actualACL); validateACL(actualACL); } else if (capabilities.getCapabilityACL() == CapabilityACL.MANAGE) { // If capability is MANAGE then try add and retrieve ACL. List<AccessControlEntry> acl = createACL(principal, "cmis:write"); try { connection.applyACL(controllableAclObject, acl, null, aclCapability.getPropagation()); actualACL = connection.getACL(controllableAclObject, false); validateACL(actualACL); checkACL(acl, actualACL); } finally { // Restore previous ACL. connection.applyACL(controllableAclObject, null, acl, aclCapability.getPropagation()); } } } }