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/02/01 15:58:37 UTC

svn commit: r1441473 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/

Author: angela
Date: Fri Feb  1 14:58:37 2013
New Revision: 1441473

URL: http://svn.apache.org/viewvc?rev=1441473&view=rev
Log:
OAK-51 : Access Control Management (subtask OAK-444)

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionablePathsTest.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java?rev=1441473&r1=1441472&r2=1441473&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionConstants.java Fri Feb  1 14:58:37 2013
@@ -51,6 +51,12 @@ public interface VersionConstants extend
     String JCR_CHILD_VERSION_HISTORY = "jcr:childVersionHistory";
 
     /**
+     * @since OAK 1.0
+     */
+    String MIX_REP_VERSIONABLE_PATHS = "rep:VersionablePaths";
+
+
+    /**
      * Quote from JSR 283 Section "15.12.3 Activity Storage"<p/>
      * <p/>
      * Activities are persisted as nodes of type nt:activity under system-generated

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java?rev=1441473&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/VersionablePathHook.java Fri Feb  1 14:58:37 2013
@@ -0,0 +1,118 @@
+/*
+ * 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.oak.plugins.version;
+
+import javax.annotation.Nonnull;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.core.ReadOnlyTree;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Commit hook which is responsible for storing the path of the versionable
+ * node with every version history. This includes creating the path property
+ * for every workspace the version history is represented and updating the
+ * path upon moving around a versionable node.
+ */
+public class VersionablePathHook implements CommitHook {
+
+    @Nonnull
+    @Override
+    public NodeState processCommit(final NodeState before, NodeState after) throws CommitFailedException {
+        NodeBuilder rootBuilder = after.builder();
+        NodeBuilder vsRoot = rootBuilder.child(NodeTypeConstants.JCR_SYSTEM).child(NodeTypeConstants.JCR_VERSIONSTORAGE);
+        ReadWriteVersionManager vMgr = new ReadWriteVersionManager(vsRoot, rootBuilder);
+        after.compareAgainstBaseState(before, new Diff(vMgr, new Node(rootBuilder)));
+        return rootBuilder.getNodeState();
+    }
+
+    private static class Diff extends DefaultNodeStateDiff implements VersionConstants {
+
+        private final ReadWriteVersionManager versionManager;
+        private final Node nodeAfter;
+
+        private Diff(@Nonnull ReadWriteVersionManager versionManager, @Nonnull Node node) {
+            this.versionManager = versionManager;
+            this.nodeAfter = node;
+        }
+
+        @Override
+        public void propertyAdded(PropertyState after) {
+            if (VersionConstants.JCR_VERSIONHISTORY.equals(after.getName())
+                    && nodeAfter.isVersionable(versionManager)) {
+                NodeBuilder vhBuilder = versionManager.getOrCreateVersionHistory(nodeAfter.builder);
+
+                if (vhBuilder.getProperty(JcrConstants.JCR_MIXINTYPES) == null) {
+                    vhBuilder.setProperty(JcrConstants.JCR_MIXINTYPES, MIX_REP_VERSIONABLE_PATHS, Type.PATH);
+                }
+
+                // FIXME: property pass the current workspace name to the processCommit call.
+                String workspaceName = "default";
+                String versionablePath = nodeAfter.path;
+                vhBuilder.setProperty(workspaceName, versionablePath);
+            }
+        }
+
+        @Override
+        public void childNodeAdded(String name, NodeState after) {
+            childNodeChanged(name, MemoryNodeState.EMPTY_NODE, after);
+        }
+
+        @Override
+        public void childNodeChanged(String name, NodeState before, NodeState after) {
+            Node node = new Node(nodeAfter, name);
+            after.compareAgainstBaseState(before, new Diff(versionManager, node));
+        }
+    }
+
+    private static final class Node {
+
+        private final String path;
+        private final NodeBuilder builder;
+
+        private Node(NodeBuilder rootBuilder) {
+            this.path = "/";
+            this.builder = rootBuilder;
+        }
+
+        private Node(Node parent, String name) {
+            this.builder = parent.builder.child(name);
+            this.path = PathUtils.concat(parent.path, name);
+        }
+
+        private boolean isVersionable(ReadWriteVersionManager versionManager) {
+            // FIXME: this readonlytree is not properly connect to it's parent
+            Tree tree = new ReadOnlyTree(null, PathUtils.getName(path), builder.getNodeState());
+            try {
+                return versionManager.isVersionable(tree);
+            } catch (RepositoryException e) {
+                return false;
+            }
+        }
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java?rev=1441473&r1=1441472&r2=1441473&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConfigurationImpl.java Fri Feb  1 14:58:37 2013
@@ -24,8 +24,10 @@ import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.jcr.security.AccessControlManager;
 
+import com.google.common.collect.ImmutableList;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.version.VersionablePathHook;
 import org.apache.jackrabbit.oak.security.authorization.restriction.RestrictionProviderImpl;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
 import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
@@ -91,7 +93,8 @@ public class AccessControlConfigurationI
     @Nonnull
     @Override
     public List<CommitHook> getCommitHooks() {
-        return Collections.<CommitHook>singletonList(new PermissionHook());
+        // TODO: review if VersionablePathHook should be included here
+        return ImmutableList.of(new PermissionHook(), new VersionablePathHook());
     }
 
     @Override

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java?rev=1441473&r1=1441472&r2=1441473&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlConstants.java Fri Feb  1 14:58:37 2013
@@ -65,11 +65,6 @@ public interface AccessControlConstants 
      */
     String PERMISSIONS_STORE_PATH = JcrConstants.JCR_SYSTEM + '/' + REP_PERMISSION_STORE;
 
-    /**
-     * @since OAK 1.0
-     */
-    String MIX_REP_VERSIONABLE_PATH = "rep:VersionablePath";
-
     Collection<String> POLICY_NODE_NAMES = ImmutableSet.of(REP_POLICY, REP_REPO_POLICY);
 
     Collection<String> ACE_PROPERTY_NAMES = ImmutableSet.of(REP_PRINCIPAL_NAME, REP_PRIVILEGES);

Added: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionablePathsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionablePathsTest.java?rev=1441473&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionablePathsTest.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionablePathsTest.java Fri Feb  1 14:58:37 2013
@@ -0,0 +1,104 @@
+/*
+ * 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.oak.jcr.version;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.version.VersionManager;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.test.AbstractJCRTest;
+import org.junit.Test;
+
+/**
+ * VersionablePathsTest... TODO
+ * <p/>
+ * FIXME: versionablePath only adjusted AFTER move/rename has been persisted.
+ */
+public class VersionablePathsTest extends AbstractJCRTest {
+
+    // FIXME: shouldn't be needed (OAK-602)
+    private Session tmpSession;
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (tmpSession != null) {
+            tmpSession.logout();
+        }
+        super.tearDown();
+    }
+
+    private VersionManager getVersionManager() throws RepositoryException {
+        tmpSession = getHelper().getSuperuserSession();
+        return tmpSession.getWorkspace().getVersionManager();
+    }
+
+    @Test
+    public void testVersionablePaths() throws Exception {
+        testRootNode.addMixin(JcrConstants.MIX_VERSIONABLE);
+        superuser.save();
+
+        Node vh = getVersionManager().getVersionHistory(testRootNode.getPath());
+
+        assertTrue(vh.isNodeType("rep:VersionablePaths"));
+        String workspaceName = superuser.getWorkspace().getName();
+        assertTrue(vh.hasProperty(workspaceName));
+        assertEquals(testRootNode.getPath(), vh.getProperty(workspaceName).getString());
+    }
+
+    @Test
+    public void testVersionablePathsAfterRename() throws Exception {
+        Node node1 = testRootNode.addNode(nodeName1);
+        node1.addMixin(JcrConstants.MIX_VERSIONABLE);
+        superuser.save();
+
+        String destPath = testRoot + "/" + nodeName2;
+        superuser.move(node1.getPath(), destPath);
+        superuser.save();
+
+        // FIXME: test node is stale after move
+        node1 = testRootNode.getNode(nodeName2);
+        Node vh = getVersionManager().getVersionHistory(node1.getPath());
+        assertTrue(vh.isNodeType("rep:VersionablePaths"));
+        String workspaceName = superuser.getWorkspace().getName();
+        assertTrue(vh.hasProperty(workspaceName));
+        assertEquals(node1.getPath(), vh.getProperty(workspaceName).getString());
+    }
+
+    @Test
+    public void testVersionablePathsAfterMove() throws Exception {
+        Node node1 = testRootNode.addNode(nodeName1);
+        Node node2 = testRootNode.addNode(nodeName2);
+        node1.addMixin(JcrConstants.MIX_VERSIONABLE);
+        superuser.save();
+
+        String destPath = node2.getPath() + "/" + nodeName1;
+        superuser.move(node1.getPath(), destPath);
+        superuser.save();
+
+        // FIXME: node1 is stale after move
+        node1 = node2.getNode(nodeName1);
+        assertEquals(destPath, node1.getPath());
+
+        Node vh = getVersionManager().getVersionHistory(node1.getPath());
+        assertTrue(vh.isNodeType("rep:VersionablePaths"));
+        String workspaceName = superuser.getWorkspace().getName();
+        assertTrue(vh.hasProperty(workspaceName));
+        assertEquals(node1.getPath(), vh.getProperty(workspaceName).getString());
+    }
+}
\ No newline at end of file