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 2015/03/03 18:58:04 UTC

svn commit: r1663755 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/security/privilege/ main/java/org/apache/jackrabbit/oak/spi/security/privilege/ test/java/org/apache/jackrabbit/oak/spi/security/privilege/

Author: angela
Date: Tue Mar  3 17:58:03 2015
New Revision: 1663755

URL: http://svn.apache.org/r1663755
Log:
OAK-1268 : Add support for composite authorization setup  (WIP, tests)

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConstants.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProviderTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java?rev=1663755&r1=1663754&r2=1663755&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeDefinitionWriter.java Tue Mar  3 17:58:03 2015
@@ -23,7 +23,6 @@ import java.util.Map;
 import javax.annotation.Nonnull;
 import javax.jcr.RepositoryException;
 
-import com.google.common.collect.ImmutableMap;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
@@ -42,28 +41,6 @@ import static java.util.Arrays.asList;
  */
 class PrivilegeDefinitionWriter implements PrivilegeConstants {
 
-    /**
-     * The internal names of all built-in privileges that are not aggregates.
-     */
-    private static final String[] NON_AGGR_PRIVILEGES = new String[]{
-            REP_READ_NODES, REP_READ_PROPERTIES,
-            REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES,
-            JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE,
-            JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL, JCR_NODE_TYPE_MANAGEMENT,
-            JCR_VERSION_MANAGEMENT, JCR_LOCK_MANAGEMENT, JCR_LIFECYCLE_MANAGEMENT,
-            JCR_RETENTION_MANAGEMENT, JCR_WORKSPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT,
-            JCR_NAMESPACE_MANAGEMENT, REP_PRIVILEGE_MANAGEMENT, REP_USER_MANAGEMENT, REP_INDEX_DEFINITION_MANAGEMENT};
-
-    /**
-     * The internal names and aggregation definition of all built-in privileges
-     * that are aggregates (except for jcr:all).
-     */
-    private static final Map<String, String[]> AGGREGATE_PRIVILEGES = ImmutableMap.of(
-            JCR_READ, new String[]{REP_READ_NODES, REP_READ_PROPERTIES},
-            JCR_MODIFY_PROPERTIES, new String[]{REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES},
-            JCR_WRITE, new String[]{JCR_MODIFY_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE},
-            REP_WRITE, new String[]{JCR_WRITE, JCR_NODE_TYPE_MANAGEMENT});
-
     private final Root root;
     private final PrivilegeBitsProvider bitsMgr;
 
@@ -170,7 +147,7 @@ class PrivilegeDefinitionWriter implemen
 
     private static Collection<PrivilegeDefinition> getBuiltInDefinitions() {
         Map<String, PrivilegeDefinition> definitions = new LinkedHashMap<String, PrivilegeDefinition>();
-        for (String privilegeName : NON_AGGR_PRIVILEGES) {
+        for (String privilegeName : NON_AGGREGATE_PRIVILEGES) {
             PrivilegeDefinition def = new ImmutablePrivilegeDefinition(privilegeName, false, null);
             definitions.put(privilegeName, def);
         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java?rev=1663755&r1=1663754&r2=1663755&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProvider.java Tue Mar  3 17:58:03 2015
@@ -28,6 +28,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.security.Privilege;
 
 import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
@@ -186,53 +187,79 @@ public final class PrivilegeBitsProvider
     }
 
     /**
-     * TODO
+     * Return the names of the non-aggregate privileges corresponding to the
+     * specified {@code privilegeNames}.
      *
-     * @param privilegeNames
-     * @return
+     * @param privilegeNames The privilege names to be converted.
+     * @return The names of the non-aggregate privileges that correspond to the
+     * given {@code privilegeNames}.
      */
     @Nonnull
     public Iterable<String> getAggregatedPrivilegeNames(@Nonnull String... privilegeNames) {
         if (privilegeNames.length == 0) {
             return Collections.emptySet();
+        } else if (privilegeNames.length == 1) {
+            String privName = privilegeNames[0];
+            if (NON_AGGREGATE_PRIVILEGES.contains(privName)) {
+                return ImmutableSet.of(privName);
+            } else if (aggregation.containsKey(privName)) {
+                return aggregation.get(privName);
+            } else {
+                return extractAggregatedPrivileges(Collections.singleton(privName));
+            }
         } else {
-            Tree privilegesTree = getPrivilegesTree();
-            if (!privilegesTree.exists()) {
-                return Collections.emptySet();
+            Set<String> pNames = ImmutableSet.copyOf(privilegeNames);
+            if (NON_AGGREGATE_PRIVILEGES.containsAll(pNames)) {
+                return pNames;
+            } else {
+                return extractAggregatedPrivileges(pNames);
             }
+        }
+    }
 
-            Set<String> aggregates = Sets.newHashSet();
-            for (String privName : privilegeNames) {
-                if (aggregation.containsKey(privName)) {
-                    aggregates.addAll(aggregation.get(privName));
-                } else if (privilegesTree.hasChild(privName)) {
-                    Tree privTree = privilegesTree.getChild(privName);
-                    if (JCR_ALL.equals(privName)) {
-                        // aggregation for jcr:all must not be cached
-                        return fillAggregation(privTree, aggregates);
-                    } else {
-                        Set<String> aggSet = fillAggregation(privTree, Sets.<String>newHashSet());
-                        aggregation.put(privName, aggSet);
-                        aggregates.addAll(aggSet);
+    private Iterable<String> extractAggregatedPrivileges(@Nonnull Iterable<String> privilegeNames) {
+        return FluentIterable.from(privilegeNames).transformAndConcat(new ExtractAggregatedPrivileges());
+    }
+
+    private final class ExtractAggregatedPrivileges implements Function<String, Iterable<String>> {
+        @Nonnull
+        @Override
+        public Iterable<String> apply(@Nullable String privName) {
+            if (privName == null) {
+                return Collections.emptySet();
+            } else {
+                if (NON_AGGREGATE_PRIVILEGES.contains(privName)) {
+                    return Collections.singleton(privName);
+                } if (aggregation.containsKey(privName)) {
+                    return aggregation.get(privName);
+                } else {
+                    Set<String> aggregates = Sets.newHashSet();
+                    fillAggregation(getPrivilegesTree().getChild(privName), aggregates);
+                    if (!JCR_ALL.equals(privName) && !aggregates.isEmpty()) {
+                        aggregation.put(privName, aggregates);
                     }
+                    return aggregates;
                 }
             }
-            return aggregates;
         }
-    }
 
-    private Set<String> fillAggregation(@Nonnull Tree privTree, @Nonnull Set<String> aggSet) {
-        if (privTree.hasProperty(REP_AGGREGATES)) {
-            for (String name : privTree.getProperty(REP_AGGREGATES).getValue(Type.NAMES)) {
-                if (aggregation.containsKey(name)) {
-                    aggSet.addAll(aggregation.get(name));
-                } else {
-                    fillAggregation(privTree.getParent().getChild(name), aggSet);
+        private void fillAggregation(@Nonnull Tree privTree, @Nonnull Set<String> aggSet) {
+            if (!privTree.exists()) {
+                return;
+            }
+            if (privTree.hasProperty(REP_AGGREGATES)) {
+                for (String name : privTree.getProperty(REP_AGGREGATES).getValue(Type.NAMES)) {
+                    if (NON_AGGREGATE_PRIVILEGES.contains(name)) {
+                        aggSet.add(name);
+                    } else if (aggregation.containsKey(name)) {
+                        aggSet.addAll(aggregation.get(name));
+                    } else {
+                        fillAggregation(privTree.getParent().getChild(name), aggSet);
+                    }
                 }
+            } else {
+                aggSet.add(privTree.getName());
             }
-        } else {
-            aggSet.add(privTree.getName());
         }
-        return aggSet;
     }
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConstants.java?rev=1663755&r1=1663754&r2=1663755&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConstants.java Tue Mar  3 17:58:03 2015
@@ -16,8 +16,10 @@
  */
 package org.apache.jackrabbit.oak.spi.security.privilege;
 
+import java.util.Map;
 import java.util.Set;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import org.apache.jackrabbit.JcrConstants;
 
@@ -223,4 +225,28 @@ public interface PrivilegeConstants {
      * @since OAK 1.0
      */
     String REP_INDEX_DEFINITION_MANAGEMENT = "rep:indexDefinitionManagement";
+
+    /**
+     * The internal names of all built-in privileges that are not aggregates.
+     */
+    Set<String> NON_AGGREGATE_PRIVILEGES = ImmutableSet.of(
+            REP_READ_NODES, REP_READ_PROPERTIES,
+                        REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES,
+                        JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE,
+                        JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL, JCR_NODE_TYPE_MANAGEMENT,
+                        JCR_VERSION_MANAGEMENT, JCR_LOCK_MANAGEMENT, JCR_LIFECYCLE_MANAGEMENT,
+                        JCR_RETENTION_MANAGEMENT, JCR_WORKSPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT,
+                        JCR_NAMESPACE_MANAGEMENT, REP_PRIVILEGE_MANAGEMENT, REP_USER_MANAGEMENT, REP_INDEX_DEFINITION_MANAGEMENT
+
+    );
+
+    /**
+     * The internal names and aggregation definition of all built-in privileges
+     * that are aggregates (except for jcr:all).
+     */
+    Map<String, String[]> AGGREGATE_PRIVILEGES = ImmutableMap.of(
+            JCR_READ, new String[]{REP_READ_NODES, REP_READ_PROPERTIES},
+            JCR_MODIFY_PROPERTIES, new String[]{REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES},
+            JCR_WRITE, new String[]{JCR_MODIFY_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE},
+            REP_WRITE, new String[]{JCR_WRITE, JCR_NODE_TYPE_MANAGEMENT});
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProviderTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProviderTest.java?rev=1663755&r1=1663754&r2=1663755&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProviderTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeBitsProviderTest.java Tue Mar  3 17:58:03 2015
@@ -18,13 +18,17 @@ package org.apache.jackrabbit.oak.spi.se
 
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 import javax.annotation.Nullable;
 import javax.jcr.RepositoryException;
 import javax.jcr.security.Privilege;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
 import org.apache.jackrabbit.oak.AbstractSecurityTest;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -151,6 +155,38 @@ public class PrivilegeBitsProviderTest e
 
     @Test
     public void testGetAggregatedNames() throws Exception {
-        // TODO
+        assertFalse(bitsProvider.getAggregatedPrivilegeNames().iterator().hasNext());
+        assertFalse(bitsProvider.getAggregatedPrivilegeNames("unknown").iterator().hasNext());
+
+        for (String nonAggregate : PrivilegeConstants.NON_AGGREGATE_PRIVILEGES) {
+            assertEquals(Collections.singleton(nonAggregate), bitsProvider.getAggregatedPrivilegeNames(nonAggregate));
+        }
+
+        Map<String[], Set<String>> testMap = Maps.newHashMap();
+        testMap.put(new String[] {JCR_READ}, ImmutableSet.of(REP_READ_NODES, REP_READ_PROPERTIES));
+        testMap.put(new String[] {JCR_MODIFY_PROPERTIES}, ImmutableSet.of(REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES));
+        testMap.put(new String[] {JCR_WRITE}, ImmutableSet.of(JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES));
+        testMap.put(new String[] {REP_WRITE}, ImmutableSet.of(JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES, JCR_NODE_TYPE_MANAGEMENT));
+        testMap.put(new String[] {JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL}, ImmutableSet.of(JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL));
+        testMap.put(new String[] {JCR_READ, JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL}, ImmutableSet.of(REP_READ_NODES, REP_READ_PROPERTIES, JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL));
+        testMap.put(new String[] {JCR_ALL}, NON_AGGREGATE_PRIVILEGES);
+        testMap.put(new String[] {JCR_READ, JCR_WRITE, JCR_ALL}, NON_AGGREGATE_PRIVILEGES);
+
+        for (String[] prvNames : testMap.keySet()) {
+            Set<String> expected = testMap.get(prvNames);
+            assertEquals(expected, ImmutableSet.copyOf(bitsProvider.getAggregatedPrivilegeNames(prvNames)));
+            assertEquals(expected, ImmutableSet.copyOf(bitsProvider.getAggregatedPrivilegeNames(prvNames)));
+        }
+
+        PrivilegeManager pMgr = getPrivilegeManager(root);
+        pMgr.registerPrivilege("test1", true, null);
+
+        assertEquals(ImmutableSet.of("test1"), ImmutableSet.copyOf(bitsProvider.getAggregatedPrivilegeNames("test1")));
+
+        Set<String> expected = Sets.newHashSet(NON_AGGREGATE_PRIVILEGES);
+        expected.add("test1");
+        assertEquals(expected, ImmutableSet.copyOf(bitsProvider.getAggregatedPrivilegeNames(JCR_ALL)));
+        assertEquals(expected, ImmutableSet.copyOf(bitsProvider.getAggregatedPrivilegeNames(JCR_ALL)));
+
     }
 }
\ No newline at end of file