/*
* 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.jcr2spi.security.authorization.jackrabbit.acl;
import java.security.Principal;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.security.AccessControlList;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.AccessControlPolicyIterator;
import javax.jcr.security.Privilege;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
import org.apache.jackrabbit.test.NotExecutableException;
import org.apache.jackrabbit.test.api.security.AbstractAccessControlTest;
public class AccessControlManagerImplTest extends AbstractAccessControlTest {
@Override
public void setUp() throws Exception {
super.setUp();
}
private Principal getUnknownPrincipal() throws NotExecutableException, RepositoryException {
return getHelper().getUnknownPrincipal(superuser);
}
public void testGetAndHasPrivileges() throws Exception {
Privilege[] privileges = acMgr.getPrivileges(testRoot);
assertNotNull(privileges);
assertTrue(acMgr.hasPrivileges(testRoot, privileges));
}
/**
* Tests the binding state of a policy.
* @throws Exception
*/
public void testGetPolicesAfterSetPoliciesCall() throws Exception {
try {
AccessControlPolicyIterator policies = acMgr.getApplicablePolicies(testRoot);
AccessControlPolicy policy = null;
while (policies.hasNext()) {
policy = policies.nextAccessControlPolicy();
acMgr.setPolicy(testRoot, policy);
AccessControlPolicy[] acl = acMgr.getPolicies(testRoot);
assertNotNull(acl);
}
} finally {
superuser.refresh(false);
}
}
/**
* This should be able to return the policies that has been transiently added
* to the node at testRoot, as the getPolicies api specifies that the method should
* take the transient changes into account.
* @throws Exception
*/
public void testRemovePolicyAfterASetPoliciesCall() throws Exception {
try {
AccessControlPolicyIterator policies = acMgr.getApplicablePolicies(testRoot);
while (policies.hasNext()) {
AccessControlList acl = (AccessControlListImpl) policies.nextAccessControlPolicy();
// GRANT read privilege
acl.addAccessControlEntry(getUnknownPrincipal(), privilegesFromName(Privilege.JCR_READ));
acMgr.setPolicy(testRoot, acl);
AccessControlPolicy[] transientPolicy = acMgr.getPolicies(testRoot);
acMgr.removePolicy(testRoot, transientPolicy[0]);
assertEquals(0, acMgr.getPolicies(testRoot).length);
}
} finally {
superuser.refresh(false);
}
}
/**
* Test removing an effective policy.
*/
public void testRemovePolicyAfterASaveCall() throws Exception {
try {
AccessControlList[] acl = (AccessControlList[]) acMgr.getPolicies(testRoot);
if (acl.length > 0) {
acMgr.removePolicy(testRoot, acl[0]);
} else {
AccessControlPolicy policy = acMgr.getApplicablePolicies(testRoot).nextAccessControlPolicy();
acMgr.setPolicy(testRoot, policy);
acMgr.removePolicy(testRoot, policy);
}
// transient removal
AccessControlPolicy[] noPolicies = acMgr.getPolicies(testRoot);
assertEquals(0, noPolicies.length);
// save changes -> removal of protected items on jcr-server
superuser.save();
} catch (Exception e) {
throw new RepositoryException(e.getMessage());
} finally {
superuser.refresh(false);
}
}
/**
* JCR mandates that the path specified for getPrivileges method must
* be absolute and points to an existing node.
* @throws Exception
*/
public void testGetPrivilegesOnNonExistingNode() throws Exception {
try {
acMgr.getPrivileges(getPathToNonExistingNode());
fail("Must throw a PathNotFoundException");
} catch (PathNotFoundException e) {
// success
}
}
/**
* Add an AccessControlList with four entries. This will result in having the result in:
* Transient-space: An ACL node that has four child-nodes.
* Persistent-state: An ACL node that has one child-node.
* NOTE: That Jackrabbit-core tries to internally merge the entries that belongs to the same
* principal, which is not the case for the client-side ACM implementation.
*/
public void testAddingFourAccessControlEntries() throws Exception {
try {
AccessControlList acl = (AccessControlList) getACL(testRoot);
// check precondition,see JCR-3995
if (testRootNode.hasNode("rep:policy")) {
assertEquals("should not have any ace nodes at this point", 0,
testRootNode.getNode("rep:policy").getNodes().getSize());
}
acl.addAccessControlEntry(getUnknownPrincipal(), privilegesFromName(Privilege.JCR_READ));
acl.addAccessControlEntry(getUnknownPrincipal(), privilegesFromName(Privilege.JCR_READ));
acl.addAccessControlEntry(getUnknownPrincipal(), privilegesFromName(Privilege.JCR_READ));
acl.addAccessControlEntry(getUnknownPrincipal(), privilegesFromName(Privilege.JCR_READ));
acMgr.setPolicy(testRoot, acl);
// Transient-space: Must contain FOUR ace nodes.
assertEquals(4, testRootNode.getNode("rep:policy").getNodes().getSize());
superuser.save();
// Persistent-state: Must contain a single ace node -> entries were
// merged
assertEquals(1, testRootNode.getNode("rep:policy").getNodes().getSize());
} finally {
superuser.refresh(false);
}
}
/**
* Test retrieving a policy after a save call.
* @throws Exception
*/
public void testGetPoliciesAfterASaveCall() throws Exception {
try {
JackrabbitAccessControlList policy = (JackrabbitAccessControlList) getACL(testRoot);
String aclPath = policy.getPath();
assertEquals(aclPath, testRoot);
// GRANT 'read' privilege to principal
policy.addAccessControlEntry(getUnknownPrincipal(), privilegesFromName(Privilege.JCR_READ));
// GRANT 'add_child_nodes' privilege
policy.addAccessControlEntry(getUnknownPrincipal(), privilegesFromName(Privilege.JCR_ADD_CHILD_NODES));
// bind the policy and save changes
acMgr.setPolicy(testRoot, policy);
superuser.save();
Node aclNode = testRootNode.getNode("rep:policy");
assertNotNull(aclNode);
NodeIterator nit = aclNode.getNodes();
// Jackrabbit-core will merge the two entries -> only a single aceNode will be created.
assertEquals(1, nit.getSize());
} finally {
superuser.refresh(false);
}
}
private AccessControlPolicy getACL(String absPath) throws RepositoryException {
AccessControlList acl = null;
if (acMgr.getPolicies(absPath).length > 0) {
acl = (AccessControlList) acMgr.getPolicies(absPath)[0];
} else {
acl = (AccessControlList) acMgr.getApplicablePolicies(absPath).nextAccessControlPolicy();
}
return acl;
}
}