/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.jackrabbit.core.xml;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
import org.apache.jackrabbit.commons.xml.ParsingContentHandler;
import org.apache.jackrabbit.core.NodeImpl;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.config.ImportConfig;
import org.apache.jackrabbit.core.security.authorization.AccessControlConstants;
import org.apache.jackrabbit.core.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.test.AbstractJCRTest;
import org.apache.jackrabbit.test.NotExecutableException;
import org.xml.sax.SAXException;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.Privilege;
import javax.jcr.security.AccessControlPolicyIterator;
import javax.jcr.security.AccessControlList;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
/**
* <code>AccessControlImporterTest</code>: Testing import of resource based
* ACLs.
*/
public class AccessControlImporterTest extends AbstractJCRTest {
private static final String XML_POLICY_TREE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sv:node sv:name=\"test\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>nt:unstructured</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"jcr:mixinTypes\" sv:type=\"Name\">" +
"<sv:value>rep:AccessControllable</sv:value>" +
"<sv:value>mix:versionable</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"jcr:uuid\" sv:type=\"String\">" +
"<sv:value>0a0ca2e9-ab98-4433-a12b-d57283765207</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"jcr:baseVersion\" sv:type=\"Reference\">" +
"<sv:value>35d0d137-a3a4-4af3-8cdd-ce565ea6bdc9</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"jcr:isCheckedOut\" sv:type=\"Boolean\">" +
"<sv:value>true</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"jcr:predecessors\" sv:type=\"Reference\">" +
"<sv:value>35d0d137-a3a4-4af3-8cdd-ce565ea6bdc9</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"jcr:versionHistory\" sv:type=\"Reference\">" +
"<sv:value>428c9ef2-78e5-4f1c-95d3-16b4ce72d815</sv:value>" +
"</sv:property>" +
"<sv:node sv:name=\"rep:policy\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:ACL</sv:value>" +
"</sv:property>" +
"<sv:node sv:name=\"allow\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:GrantACE</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:principalName\" sv:type=\"String\">" +
"<sv:value>everyone</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:privileges\" sv:type=\"Name\">" +
"<sv:value>jcr:write</sv:value>" +
"</sv:property>" +
"</sv:node>" +
"</sv:node>" +
"</sv:node>";
private static final String XML_POLICY_TREE_3 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sv:node sv:name=\"rep:policy\" " +
"xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:ACL</sv:value>" +
"</sv:property>" +
"<sv:node sv:name=\"allow\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:GrantACE</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:principalName\" sv:type=\"String\">" +
"<sv:value>everyone</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:privileges\" sv:type=\"Name\">" +
"<sv:value>jcr:write</sv:value>" +
"</sv:property>" +
"</sv:node>" +
"<sv:node sv:name=\"allow0\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:GrantACE</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:principalName\" sv:type=\"String\">" +
"<sv:value>admin</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:privileges\" sv:type=\"Name\">" +
"<sv:value>jcr:write</sv:value>" +
"</sv:property>" +
"</sv:node>" +
"</sv:node>";
private static final String XML_POLICY_TREE_5 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sv:node sv:name=\"rep:policy\" " +
"xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:ACL</sv:value>" +
"</sv:property>" +
"<sv:node sv:name=\"allow0\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:GrantACE</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:principalName\" sv:type=\"String\">" +
"<sv:value>admin</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:privileges\" sv:type=\"Name\">" +
"<sv:value>jcr:write</sv:value>" +
"</sv:property>" +
"</sv:node>" +
"</sv:node>";
private static final String XML_POLICY_TREE_4 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<sv:node sv:name=\"rep:policy\" " +
"xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:ACL</sv:value>" +
"</sv:property>" +
"<sv:node sv:name=\"allow\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:GrantACE</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:principalName\" sv:type=\"String\">" +
"<sv:value>unknownprincipal</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:privileges\" sv:type=\"Name\">" +
"<sv:value>jcr:write</sv:value>" +
"</sv:property>" +
"</sv:node>" +
"<sv:node sv:name=\"allow0\">" +
"<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
"<sv:value>rep:GrantACE</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:principalName\" sv:type=\"String\">" +
"<sv:value>admin</sv:value>" +
"</sv:property>" +
"<sv:property sv:name=\"rep:privileges\" sv:type=\"Name\">" +
"<sv:value>jcr:write</sv:value>" +
"</sv:property>" +
"</sv:node>" +
"</sv:node>";
private static final String XML_POLICY_TREE_2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sv:node sv:name=\"rep:policy\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:ACL</sv:value></sv:property><sv:node sv:name=\"allow\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:GrantACE</sv:value></sv:property><sv:property sv:name=\"rep:principalName\" sv:type=\"String\"><sv:value>everyone</sv:value></sv:property><sv:property sv:name=\"rep:privileges\" sv:type=\"Name\"><sv:value>jcr:write</sv:value></sv:property></sv:node></sv:node>";
private static final String XML_AC_TREE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sv:node sv:name=\"rep:security\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:crx=\"http://www.day.com/crx/1.0\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:repl=\"http://www.day.com/crx/replication/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:AccessControl</sv:value></sv:property><sv:node sv:name=\"rep:authorizables\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:AccessControl</sv:value></sv:property><sv:node sv:name=\"rep:groups\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:AccessControl</sv:value></sv:property><sv:node sv:name=\"administrators\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:PrincipalAccessControl</sv:value></sv:property><sv:node sv:name=\"rep:policy\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:ACL</sv:value></sv:property><sv:node sv:name=\"entry\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:GrantACE</sv:value></sv:property><sv:property sv:name=\"rep:glob\" sv:type=\"String\"><sv:value>*</sv:value></sv:property><sv:property sv:name=\"rep:nodePath\" sv:type=\"Path\"><sv:value>/</sv:value></sv:property><sv:property sv:name=\"rep:principalName\" sv:type=\"String\"><sv:value>administrators</sv:value></sv:property><sv:property sv:name=\"rep:privileges\" sv:type=\"Name\"><sv:value>jcr:all</sv:value></sv:property></sv:node></sv:node></sv:node></sv:node><sv:node sv:name=\"rep:users\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:AccessControl</sv:value></sv:property><sv:node sv:name=\"admin\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:AccessControl</sv:value></sv:property><sv:node sv:name=\"t\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:PrincipalAccessControl</sv:value></sv:property></sv:node><sv:node sv:name=\"a\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:PrincipalAccessControl</sv:value></sv:property></sv:node></sv:node><sv:node sv:name=\"anonymous\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:PrincipalAccessControl</sv:value></sv:property></sv:node></sv:node></sv:node></sv:node>";
private static final String XML_POLICY_ONLY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sv:node sv:name=\"test\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>nt:unstructured</sv:value></sv:property><sv:property sv:name=\"jcr:mixinTypes\" sv:type=\"Name\"><sv:value>rep:AccessControllable</sv:value><sv:value>mix:versionable</sv:value></sv:property><sv:property sv:name=\"jcr:uuid\" sv:type=\"String\"><sv:value>0a0ca2e9-ab98-4433-a12b-d57283765207</sv:value></sv:property><sv:property sv:name=\"jcr:baseVersion\" sv:type=\"Reference\"><sv:value>35d0d137-a3a4-4af3-8cdd-ce565ea6bdc9</sv:value></sv:property><sv:property sv:name=\"jcr:isCheckedOut\" sv:type=\"Boolean\"><sv:value>true</sv:value></sv:property><sv:property sv:name=\"jcr:predecessors\" sv:type=\"Reference\"><sv:value>35d0d137-a3a4-4af3-8cdd-ce565ea6bdc9</sv:value></sv:property><sv:property sv:name=\"jcr:versionHistory\" sv:type=\"Reference\"><sv:value>428c9ef2-78e5-4f1c-95d3-16b4ce72d815</sv:value></sv:property><sv:node sv:name=\"rep:policy\"><sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:ACL</sv:value></sv:property></sv:node></sv:node>";
private SessionImpl sImpl;
@Override
protected void setUp() throws Exception {
super.setUp();
if (!(superuser instanceof SessionImpl)) {
throw new NotExecutableException("SessionImpl expected");
}
sImpl = (SessionImpl) superuser;
// make sure the repository provides resource based policies.
AccessControlPolicyIterator it = sImpl.getAccessControlManager().getApplicablePolicies("/");
if (!it.hasNext()) {
AccessControlPolicy[] pcs = sImpl.getAccessControlManager().getPolicies("/");
if (pcs == null || pcs.length == 0) {
throw new NotExecutableException();
}
} // ok resource based acl
}
private NodeImpl createPolicyNode(NodeImpl target) throws Exception {
try {
InputStream in = new ByteArrayInputStream(XML_POLICY_ONLY.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
return (NodeImpl) target.getNode("test/rep:policy");
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
superuser.refresh(false);
if (superuser.nodeExists("/test")) {
NodeIterator it = superuser.getRootNode().getNodes("test");
while (it.hasNext()) {
it.nextNode().remove();
}
}
superuser.save();
}
}
private static ProtectedNodeImporter createImporter() {
return new AccessControlImporter();
}
public void testWorkspaceImport() throws Exception {
boolean isWorkspaceImport = true;
ProtectedNodeImporter protectedImporter = new AccessControlImporter();
protectedImporter.init(sImpl, sImpl, isWorkspaceImport, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, null);
NodeImpl n = createPolicyNode((NodeImpl) testRootNode);
assertFalse(protectedImporter.start(n));
}
public void testNonProtectedNode() throws Exception {
if (!testRootNode.getDefinition().isProtected()) {
ProtectedNodeImporter piImporter = createImporter();
piImporter.init(sImpl, sImpl, false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, null);
assertFalse(piImporter.start((NodeImpl) testRootNode));
} else {
throw new NotExecutableException();
}
}
public void testUnsupportedProtectedNode() throws Exception {
Node n = testRootNode.addNode(nodeName1);
n.addMixin(mixVersionable);
ProtectedNodeImporter piImporter = createImporter();
piImporter.init(sImpl, sImpl, false, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, null);
assertFalse(piImporter.start((NodeImpl) n));
}
/**
* Imports a resource-based ACL containing a single entry.
*
* @throws Exception
*/
public void testImportACL() throws Exception {
NodeImpl target = (NodeImpl) testRootNode;
try {
InputStream in = new ByteArrayInputStream(XML_POLICY_TREE.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl,
ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, new PseudoConfig());
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
assertTrue(target.hasNode("test"));
String path = target.getNode("test").getPath();
AccessControlManager acMgr = sImpl.getAccessControlManager();
AccessControlPolicy[] policies = acMgr.getPolicies(path);
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof JackrabbitAccessControlList);
AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
assertEquals(1, entries.length);
AccessControlEntry entry = entries[0];
assertEquals("everyone", entry.getPrincipal().getName());
assertEquals(1, entry.getPrivileges().length);
assertEquals(acMgr.privilegeFromName(Privilege.JCR_WRITE), entry.getPrivileges()[0]);
if(entry instanceof JackrabbitAccessControlEntry) {
assertTrue(((JackrabbitAccessControlEntry) entry).isAllow());
}
} finally {
superuser.refresh(false);
}
}
/**
* Imports a resource-based ACL containing a single entry.
*
* @throws Exception
*/
public void testImportACLOnly() throws Exception {
try {
NodeImpl target = (NodeImpl) testRootNode.addNode(nodeName1);
target.addMixin("rep:AccessControllable");
InputStream in = new ByteArrayInputStream(XML_POLICY_TREE_3.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl,
ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, new PseudoConfig());
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
String path = target.getPath();
AccessControlManager acMgr = sImpl.getAccessControlManager();
AccessControlPolicy[] policies = acMgr.getPolicies(path);
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof JackrabbitAccessControlList);
AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
assertEquals(2, entries.length);
AccessControlEntry entry = entries[0];
assertEquals("everyone", entry.getPrincipal().getName());
assertEquals(1, entry.getPrivileges().length);
assertEquals(acMgr.privilegeFromName(Privilege.JCR_WRITE), entry.getPrivileges()[0]);
entry = entries[1];
assertEquals("admin", entry.getPrincipal().getName());
assertEquals(1, entry.getPrivileges().length);
assertEquals(acMgr.privilegeFromName(Privilege.JCR_WRITE), entry.getPrivileges()[0]);
if(entry instanceof JackrabbitAccessControlEntry) {
assertTrue(((JackrabbitAccessControlEntry) entry).isAllow());
}
} finally {
superuser.refresh(false);
}
}
/**
* Imports a resource-based ACL containing a single entry.
*
* @throws Exception
*/
public void testImportACLRemoveACE() throws Exception {
try {
NodeImpl target = (NodeImpl) testRootNode.addNode(nodeName1);
target.addMixin("rep:AccessControllable");
InputStream in = new ByteArrayInputStream(XML_POLICY_TREE_3.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl,
ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, new PseudoConfig());
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
in = new ByteArrayInputStream(XML_POLICY_TREE_5.getBytes("UTF-8"));
importer = new SessionImporter(target, sImpl,
ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, new PseudoConfig());
ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
String path = target.getPath();
AccessControlManager acMgr = sImpl.getAccessControlManager();
AccessControlPolicy[] policies = acMgr.getPolicies(path);
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof JackrabbitAccessControlList);
AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
assertEquals(1, entries.length);
AccessControlEntry entry = entries[0];
assertEquals("admin", entry.getPrincipal().getName());
assertEquals(1, entry.getPrivileges().length);
assertEquals(acMgr.privilegeFromName(Privilege.JCR_WRITE), entry.getPrivileges()[0]);
if(entry instanceof JackrabbitAccessControlEntry) {
assertTrue(((JackrabbitAccessControlEntry) entry).isAllow());
}
} finally {
superuser.refresh(false);
}
}
/**
* Imports a resource-based ACL containing a single entry.
*
* @throws Exception
*/
public void testImportACLUnknown() throws Exception {
try {
NodeImpl target = (NodeImpl) testRootNode.addNode(nodeName1);
target.addMixin("rep:AccessControllable");
InputStream in = new ByteArrayInputStream(XML_POLICY_TREE_4.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl,
ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, new PseudoConfig());
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
String path = target.getPath();
AccessControlManager acMgr = sImpl.getAccessControlManager();
AccessControlPolicy[] policies = acMgr.getPolicies(path);
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof JackrabbitAccessControlList);
AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
assertEquals(2, entries.length);
AccessControlEntry entry = entries[0];
assertEquals("unknownprincipal", entry.getPrincipal().getName());
assertEquals(1, entry.getPrivileges().length);
assertEquals(acMgr.privilegeFromName(Privilege.JCR_WRITE), entry.getPrivileges()[0]);
entry = entries[1];
assertEquals("admin", entry.getPrincipal().getName());
assertEquals(1, entry.getPrivileges().length);
assertEquals(acMgr.privilegeFromName(Privilege.JCR_WRITE), entry.getPrivileges()[0]);
if(entry instanceof JackrabbitAccessControlEntry) {
assertTrue(((JackrabbitAccessControlEntry) entry).isAllow());
}
} finally {
superuser.refresh(false);
}
}
/**
* Imports a resource-based ACL containing a single entry for a policy that
* already exists.
*
* @throws Exception
*/
public void testImportPolicyExists() throws Exception {
// this test does not work anymore, since the normal behavior is replace
// all ACEs for an import. maybe control this behavior via uuid-flag.
if (true) {
return;
}
NodeImpl target = (NodeImpl) testRootNode;
target = (NodeImpl) target.addNode("test", "test:sameNameSibsFalseChildNodeDefinition");
AccessControlManager acMgr = sImpl.getAccessControlManager();
for (AccessControlPolicyIterator it = acMgr.getApplicablePolicies(target.getPath()); it.hasNext();) {
AccessControlPolicy policy = it.nextAccessControlPolicy();
if (policy instanceof AccessControlList) {
Privilege[] privs = new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_LOCK_MANAGEMENT)};
((AccessControlList) policy).addAccessControlEntry(sImpl.getPrincipalManager().getEveryone(), privs);
acMgr.setPolicy(target.getPath(), policy);
}
}
try {
InputStream in = new ByteArrayInputStream(XML_POLICY_TREE_2.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW, new PseudoConfig());
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
AccessControlPolicy[] policies = acMgr.getPolicies(target.getPath());
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof JackrabbitAccessControlList);
AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
assertEquals(1, entries.length);
AccessControlEntry entry = entries[0];
assertEquals("everyone", entry.getPrincipal().getName());
List<Privilege> privs = Arrays.asList(entry.getPrivileges());
assertEquals(2, privs.size());
assertTrue(privs.contains(acMgr.privilegeFromName(Privilege.JCR_WRITE)) &&
privs.contains(acMgr.privilegeFromName(Privilege.JCR_LOCK_MANAGEMENT)));
assertEquals(acMgr.privilegeFromName(Privilege.JCR_WRITE), entry.getPrivileges()[0]);
if(entry instanceof JackrabbitAccessControlEntry) {
assertTrue(((JackrabbitAccessControlEntry) entry).isAllow());
}
} finally {
superuser.refresh(false);
}
}
/**
* Imports an empty resource-based ACL for a policy that already exists.
*
* @throws Exception
*/
public void testImportEmptyExistingPolicy() throws Exception {
NodeImpl target = (NodeImpl) testRootNode;
target = (NodeImpl) target.addNode("test", "test:sameNameSibsFalseChildNodeDefinition");
AccessControlManager acMgr = sImpl.getAccessControlManager();
for (AccessControlPolicyIterator it = acMgr.getApplicablePolicies(target.getPath()); it.hasNext();) {
AccessControlPolicy policy = it.nextAccessControlPolicy();
if (policy instanceof AccessControlList) {
acMgr.setPolicy(target.getPath(), policy);
}
}
try {
InputStream in = new ByteArrayInputStream(XML_POLICY_ONLY.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW, new PseudoConfig());
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
AccessControlPolicy[] policies = acMgr.getPolicies(target.getPath());
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof JackrabbitAccessControlList);
AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
assertEquals(0, entries.length);
} finally {
superuser.refresh(false);
}
}
/**
* Imports a principal-based ACL containing a single entry mist fail with
* the default configuration.
*
* @throws Exception
*/
public void testImportPrincipalBasedACL() throws Exception {
JackrabbitAccessControlManager acMgr = (JackrabbitAccessControlManager) sImpl.getAccessControlManager();
if (acMgr.getApplicablePolicies(EveryonePrincipal.getInstance()).length > 0 ||
acMgr.getPolicies(EveryonePrincipal.getInstance()).length > 0) {
// test expects that only resource-based acl is supported
throw new NotExecutableException();
}
NodeImpl target;
NodeImpl root = (NodeImpl) sImpl.getRootNode();
if (!root.hasNode(AccessControlConstants.N_ACCESSCONTROL)) {
target = root.addNode(AccessControlConstants.N_ACCESSCONTROL, AccessControlConstants.NT_REP_ACCESS_CONTROL, null);
} else {
target = root.getNode(AccessControlConstants.N_ACCESSCONTROL);
if (!target.isNodeType(AccessControlConstants.NT_REP_ACCESS_CONTROL)) {
target.setPrimaryType(sImpl.getJCRName(AccessControlConstants.NT_REP_ACCESS_CONTROL));
}
}
try {
InputStream in = new ByteArrayInputStream(XML_AC_TREE.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, new PseudoConfig());
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
fail("Default config only allows resource-based ACL -> protected import must fail");
} catch (SAXException e) {
if (e.getException() instanceof ConstraintViolationException) {
// success
} else {
throw e;
}
} finally {
superuser.refresh(false);
}
}
/**
* With the default importer that isn't able to deal with ACEs the
* policy will be created but any ACEs will be ignored.
*
* @throws Exception
*/
public void testImportWithDefaultImporter() throws Exception {
NodeImpl target = (NodeImpl) testRootNode;
try {
InputStream in = new ByteArrayInputStream(XML_POLICY_TREE.getBytes("UTF-8"));
SessionImporter importer = new SessionImporter(target, sImpl, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW, null);
ImportHandler ih = new ImportHandler(importer, sImpl);
new ParsingContentHandler(ih).parse(in);
assertTrue(target.hasNode("test"));
String path = target.getNode("test").getPath();
AccessControlManager acMgr = sImpl.getAccessControlManager();
AccessControlPolicy[] policies = acMgr.getPolicies(path);
assertEquals(1, policies.length);
assertTrue(policies[0] instanceof JackrabbitAccessControlList);
AccessControlEntry[] entries = ((JackrabbitAccessControlList) policies[0]).getAccessControlEntries();
assertEquals(0, entries.length);
} finally {
superuser.refresh(false);
}
}
private final class PseudoConfig extends ImportConfig {
private final ProtectedNodeImporter aci;
private PseudoConfig() {
this.aci = createImporter();
}
@Override
public List<ProtectedNodeImporter> getProtectedNodeImporters() {
return Collections.singletonList(aci);
}
}
}