You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2013/04/23 15:40:21 UTC
svn commit: r1470950 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/security/authorization/
main/java/org/apache/jackrabbit/oak/security/authorization/restriction/
test/java/org/apache/jackrabbit/oak/security/authorization/
Author: angela
Date: Tue Apr 23 13:40:21 2013
New Revision: 1470950
URL: http://svn.apache.org/r1470950
Log:
OAK-758 : Implement AC-editing by principal (Jackrabbit API)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java?rev=1470950&r1=1470949&r2=1470950&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java Tue Apr 23 13:40:21 2013
@@ -20,9 +20,11 @@ import java.security.Principal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
@@ -31,10 +33,10 @@ import javax.jcr.AccessDeniedException;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
import javax.jcr.query.Query;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlException;
-import javax.jcr.security.AccessControlList;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.AccessControlPolicyIterator;
import javax.jcr.security.Privilege;
@@ -216,58 +218,69 @@ public class AccessControlManagerImpl im
checkValidPolicy(oakPath, policy);
if (policy instanceof PrincipalACL) {
- PrincipalACL principalAcl = (PrincipalACL) policy;
- AccessControlPolicy[] plcs = getPolicies(principalAcl.principal);
- PrincipalACL existing = (plcs.length == 0) ? null : (PrincipalACL) plcs[0];
+ setPrincipalBasedAcl((PrincipalACL) policy);
+ } else {
+ Tree tree = getTree(oakPath, Permissions.MODIFY_ACCESS_CONTROL);
+ setNodeBasedAcl(oakPath, tree, (ACL) policy);
+ }
+ }
- List<JackrabbitAccessControlEntry> toAdd = Lists.newArrayList(principalAcl.getEntries());
- List<JackrabbitAccessControlEntry> toRemove = Collections.emptyList();
- if (existing != null) {
- toAdd.removeAll(existing.getEntries());
- toRemove = existing.getEntries();
- toRemove.removeAll(principalAcl.getEntries());
- }
- // add new entries
- for (JackrabbitAccessControlEntry ace : toAdd) {
- String path = getOakPath(ace.getRestriction(REP_NODE_PATH).getString());
- Tree tree = getTree(path, Permissions.MODIFY_ACCESS_CONTROL);
- NodeUtil aclNode = getAclNode(path, tree);
- if (aclNode == null) {
- aclNode = createAclNode(path, tree);
- }
- aclNode.getTree().setOrderableChildren(true);
- writeACE(path, aclNode, ace, principalAcl.rProvider);
- }
+ private void setPrincipalBasedAcl(PrincipalACL principalAcl) throws RepositoryException {
+ AccessControlPolicy[] plcs = getPolicies(principalAcl.principal);
+ PrincipalACL existing = (plcs.length == 0) ? null : (PrincipalACL) plcs[0];
- // remove entries that are not longer present in the acl to write
- for (JackrabbitAccessControlEntry ace : toRemove) {
- String path = getOakPath(ace.getRestriction(REP_NODE_PATH).getString());
- NodeUtil aclNode = checkNotNull(getAclNode(path, getTree(path, Permissions.MODIFY_ACCESS_CONTROL)));
- Iterator<Tree> children = aclNode.getTree().getChildren().iterator();
- while (children.hasNext()) {
- Tree child = children.next();
- if (ace.equals(createACE(path, child, principalAcl.rProvider))) {
- child.remove();
- }
- }
+ List<JackrabbitAccessControlEntry> toAdd = Lists.newArrayList(principalAcl.getEntries());
+ List<JackrabbitAccessControlEntry> toRemove = Collections.emptyList();
+ if (existing != null) {
+ toAdd.removeAll(existing.getEntries());
+ toRemove = existing.getEntries();
+ toRemove.removeAll(principalAcl.getEntries());
+ }
+ // add new entries
+ for (JackrabbitAccessControlEntry ace : toAdd) {
+ String path = getOakPath(ace.getRestriction(REP_NODE_PATH).getString());
+ Tree tree = getTree(path, Permissions.MODIFY_ACCESS_CONTROL);
+
+ ACL acl = (ACL) createACL(path, tree, false);
+ if (acl == null) {
+ acl = new NodeACL(path);
}
- } else {
- Tree tree = getTree(oakPath, Permissions.MODIFY_ACCESS_CONTROL);
- NodeUtil aclNode = getAclNode(oakPath, tree);
- if (aclNode != null) {
- // remove all existing aces
- for (Tree aceTree : aclNode.getTree().getChildren()) {
- aceTree.remove();
+
+ Map<String, Value> restrictions = new HashMap();
+ for (String name : ace.getRestrictionNames()) {
+ if (!REP_NODE_PATH.equals(name)) {
+ restrictions.put(name, ace.getRestriction(name));
}
- } else {
- aclNode = createAclNode(oakPath, tree);
}
- aclNode.getTree().setOrderableChildren(true);
+ acl.addEntry(ace.getPrincipal(), ace.getPrivileges(), ace.isAllow(), restrictions);
+ setNodeBasedAcl(path, tree, acl);
+ }
+
+ // remove entries that are not longer present in the acl to write
+ for (JackrabbitAccessControlEntry ace : toRemove) {
+ String path = getOakPath(ace.getRestriction(REP_NODE_PATH).getString());
+ Tree tree = getTree(path, Permissions.MODIFY_ACCESS_CONTROL);
+
+ ACL acl = (ACL) createACL(path, tree, false);
+ acl.removeAccessControlEntry(ace);
+ setNodeBasedAcl(path, tree, acl);
+ }
+ }
- ACL acl = (ACL) policy;
- for (JackrabbitAccessControlEntry ace : acl.getEntries()) {
- writeACE(oakPath, aclNode, ace, restrictionProvider);
+ private void setNodeBasedAcl(@Nullable String oakPath, @Nonnull Tree tree,
+ @Nonnull ACL acl) throws RepositoryException {
+ NodeUtil aclNode = getAclNode(oakPath, tree);
+ if (aclNode != null) {
+ // remove all existing aces
+ for (Tree aceTree : aclNode.getTree().getChildren()) {
+ aceTree.remove();
}
+ } else {
+ aclNode = createAclNode(oakPath, tree);
+ }
+ aclNode.getTree().setOrderableChildren(true);
+ for (JackrabbitAccessControlEntry ace : acl.getEntries()) {
+ writeACE(oakPath, aclNode, ace, restrictionProvider);
}
}
@@ -280,16 +293,21 @@ public class AccessControlManagerImpl im
PrincipalACL principalAcl = (PrincipalACL) policy;
for (JackrabbitAccessControlEntry ace : principalAcl.getEntries()) {
String path = getOakPath(ace.getRestriction(REP_NODE_PATH).getString());
- Tree tree = getTree(path, Permissions.MODIFY_ACCESS_CONTROL);
- NodeUtil aclNode = checkNotNull(getAclNode(oakPath, tree));
-
- Iterator<Tree> children = aclNode.getTree().getChildren().iterator();
+ NodeUtil aclNode = getAclNode(path, getTree(path, Permissions.MODIFY_ACCESS_CONTROL));
+ if (aclNode == null) {
+ throw new AccessControlException("Unable to retrieve policy node at " + path);
+ }
+ Tree aclTree = aclNode.getTree();
+ Iterator<Tree> children = aclTree.getChildren().iterator();
while (children.hasNext()) {
Tree child = children.next();
if (ace.equals(createACE(path, child, principalAcl.rProvider))) {
child.remove();
}
}
+ if (!aclTree.getChildren().iterator().hasNext()) {
+ aclTree.remove();
+ }
}
} else {
Tree tree = getTree(oakPath, Permissions.MODIFY_ACCESS_CONTROL);
@@ -480,10 +498,10 @@ public class AccessControlManagerImpl im
}
@CheckForNull
- private AccessControlList createACL(@Nullable String oakPath,
- @Nullable Tree accessControlledTree,
- boolean isReadOnly) throws RepositoryException {
- AccessControlList acl = null;
+ private JackrabbitAccessControlList createACL(@Nullable String oakPath,
+ @Nullable Tree accessControlledTree,
+ boolean isReadOnly) throws RepositoryException {
+ JackrabbitAccessControlList acl = null;
String aclName = getAclName(oakPath);
String mixinName = getMixinName(oakPath);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java?rev=1470950&r1=1470949&r2=1470950&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java Tue Apr 23 13:40:21 2013
@@ -26,6 +26,7 @@ import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.security.AccessControlException;
+import com.google.common.collect.Sets;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
@@ -63,7 +64,12 @@ public class PrincipalRestrictionProvide
@Nonnull
@Override
public Restriction createRestriction(@Nullable String oakPath, @Nonnull String jcrName, @Nonnull Value value) throws RepositoryException {
- return base.createRestriction(oakPath, jcrName, value);
+ String oakName = namePathMapper.getOakName(jcrName);
+ if (REP_NODE_PATH.equals(oakName) && PropertyType.PATH == value.getType()) {
+ return new RestrictionImpl(PropertyStates.createProperty(oakName, value), true, namePathMapper);
+ } else {
+ return base.createRestriction(oakPath, jcrName, value);
+ }
}
@Override
@@ -77,7 +83,7 @@ public class PrincipalRestrictionProvide
@Override
public void writeRestrictions(String oakPath, Tree aceTree, Set<Restriction> restrictions) throws AccessControlException {
- Iterator<Restriction> it = restrictions.iterator();
+ Iterator<Restriction> it = Sets.newHashSet(restrictions).iterator();
while (it.hasNext()) {
Restriction r = it.next();
if (REP_NODE_PATH.equals(r.getName())) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java?rev=1470950&r1=1470949&r2=1470950&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/RestrictionProviderImpl.java Tue Apr 23 13:40:21 2013
@@ -74,13 +74,13 @@ public class RestrictionProviderImpl imp
@Override
public Restriction createRestriction(String oakPath, String jcrName, Value value) throws RepositoryException {
if (isUnsupportedPath(oakPath)) {
- throw new AccessControlException("Unsupported restriction: " + oakPath);
+ throw new AccessControlException("Unsupported restriction at " + oakPath);
}
String oakName = namePathMapper.getOakName(jcrName);
RestrictionDefinition definition = supported.get(oakName);
if (definition == null) {
- throw new AccessControlException("Unsupported restriction: " + oakPath);
+ throw new AccessControlException("Unsupported restriction: " + oakName);
}
int requiredType = definition.getRequiredType();
if (requiredType != PropertyType.UNDEFINED && requiredType != value.getType()) {
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java?rev=1470950&r1=1470949&r2=1470950&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImplTest.java Tue Apr 23 13:40:21 2013
@@ -20,6 +20,7 @@ import java.security.Principal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -30,6 +31,7 @@ import javax.annotation.Nullable;
import javax.jcr.AccessDeniedException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.PathNotFoundException;
+import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
@@ -45,6 +47,7 @@ import com.google.common.collect.Immutab
import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.oak.TestNameMapper;
@@ -1564,8 +1567,91 @@ public class AccessControlManagerImplTes
}
//-----------------------------------------------< setPrincipalPolicy() >---
- // TODO
+ @Test
+ public void testSetPrincipalPolicy() throws Exception {
+ JackrabbitAccessControlPolicy[] applicable = acMgr.getApplicablePolicies(testPrincipal);
+ assertNotNull(applicable);
+ assertEquals(1, applicable.length);
+ assertTrue(applicable[0] instanceof ACL);
+
+ ACL acl = (ACL) applicable[0];
+ Value pathValue = getValueFactory().createValue(testPath, PropertyType.PATH);
+ assertTrue(acl.addEntry(testPrincipal, testPrivileges, true, Collections.singletonMap(REP_NODE_PATH, pathValue)));
+ acMgr.setPolicy(acl.getPath(), acl);
+ root.commit();
+
+ Root root2 = adminSession.getLatestRoot();
+ AccessControlPolicy[] policies = getAccessControlManager(root2).getPolicies(testPath);
+ assertEquals(1, policies.length);
+ assertEquals(1, ((ACL) policies[0]).getAccessControlEntries().length);
+
+ policies = getAccessControlManager(root2).getPolicies(testPrincipal);
+ assertEquals(1, policies.length);
+ assertArrayEquals(acl.getAccessControlEntries(), ((ACL) policies[0]).getAccessControlEntries());
+ }
+
+ @Test
+ public void testSetPrincipalPolicy2() throws Exception {
+ setupPolicy(testPath);
+ root.commit();
+
+ JackrabbitAccessControlPolicy[] policies = acMgr.getPolicies(testPrincipal);
+ assertNotNull(policies);
+ assertEquals(1, policies.length);
+ assertTrue(policies[0] instanceof ACL);
+
+ ACL acl = (ACL) policies[0];
+ Map<String, Value> restrictions = new HashMap<String, Value>();
+ restrictions.put(REP_NODE_PATH, getValueFactory().createValue(testPath, PropertyType.PATH));
+
+ assertTrue(acl.addEntry(testPrincipal, testPrivileges, true, restrictions));
+
+ restrictions.putAll(getGlobRestriction("*"));
+ assertFalse(acl.addEntry(testPrincipal, testPrivileges, true, restrictions));
+
+ acMgr.setPolicy(acl.getPath(), acl);
+ assertEquals(2, ((ACL) acMgr.getPolicies(testPath)[0]).getAccessControlEntries().length);
+ }
//--------------------------------------------< removePrincipalPolicy() >---
- // TODO
+
+ @Test
+ public void testRemovePrincipalPolicy() throws Exception {
+ JackrabbitAccessControlPolicy[] applicable = acMgr.getApplicablePolicies(testPrincipal);
+ assertNotNull(applicable);
+ assertEquals(1, applicable.length);
+ assertTrue(applicable[0] instanceof ACL);
+
+ ACL acl = (ACL) applicable[0];
+ Value pathValue = getValueFactory().createValue(testPath, PropertyType.PATH);
+ assertTrue(acl.addEntry(testPrincipal, testPrivileges, true, Collections.singletonMap(REP_NODE_PATH, pathValue)));
+ acMgr.setPolicy(acl.getPath(), acl);
+ root.commit();
+
+ acMgr.removePolicy(acl.getPath(), acl);
+ root.commit();
+
+ assertEquals(0, acMgr.getPolicies(testPrincipal).length);
+ assertEquals(0, acMgr.getPolicies(testPath).length);
+ }
+
+ @Test
+ public void testRemovePrincipalPolicy2() throws Exception {
+ setupPolicy(testPath);
+ root.commit();
+
+ AccessControlPolicy[] policies = acMgr.getPolicies(testPrincipal);
+ assertNotNull(policies);
+ assertEquals(1, policies.length);
+ assertTrue(policies[0] instanceof ACL);
+
+ ACL acl = (ACL) policies[0];
+ acMgr.removePolicy(acl.getPath(), acl);
+
+ policies = acMgr.getPolicies(testPath);
+ assertEquals(0, policies.length);
+
+ policies = acMgr.getPolicies(testPrincipal);
+ assertEquals(0, policies.length);
+ }
}