You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2016/09/09 11:39:38 UTC

svn commit: r1759987 - in /jackrabbit/branches/2.12: ./ jackrabbit-core/pom.xml jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/UtilsGetPathTest.java jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JcrUtils.java

Author: reschke
Date: Fri Sep  9 11:39:38 2016
New Revision: 1759987

URL: http://svn.apache.org/viewvc?rev=1759987&view=rev
Log:
JCR-4015: jackrabbit-jcr-commons JcrUtils.getOrCreateByPath fails if session is not allowed to read root (ported to 2.12)

Modified:
    jackrabbit/branches/2.12/   (props changed)
    jackrabbit/branches/2.12/jackrabbit-core/pom.xml
    jackrabbit/branches/2.12/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/UtilsGetPathTest.java
    jackrabbit/branches/2.12/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JcrUtils.java

Propchange: jackrabbit/branches/2.12/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Sep  9 11:39:38 2016
@@ -1,3 +1,3 @@
 /jackrabbit/branches/JCR-2272:1173165-1176545
 /jackrabbit/sandbox/JCR-2415-lucene-3.0:1060860-1064038
-/jackrabbit/trunk:1732436,1751279,1752165,1753226,1758600
+/jackrabbit/trunk:1732436,1751279,1752165,1753226,1758600,1759607,1759782

Modified: jackrabbit/branches/2.12/jackrabbit-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.12/jackrabbit-core/pom.xml?rev=1759987&r1=1759986&r2=1759987&view=diff
==============================================================================
--- jackrabbit/branches/2.12/jackrabbit-core/pom.xml (original)
+++ jackrabbit/branches/2.12/jackrabbit-core/pom.xml Fri Sep  9 11:39:38 2016
@@ -343,6 +343,12 @@ org.apache.jackrabbit.test.api.query.qom
       <version>1.3.149</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>1.10.19</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <profiles>

Modified: jackrabbit/branches/2.12/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/UtilsGetPathTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.12/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/UtilsGetPathTest.java?rev=1759987&r1=1759986&r2=1759987&view=diff
==============================================================================
--- jackrabbit/branches/2.12/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/UtilsGetPathTest.java (original)
+++ jackrabbit/branches/2.12/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/UtilsGetPathTest.java Fri Sep  9 11:39:38 2016
@@ -16,31 +16,73 @@
  */
 package org.apache.jackrabbit.core.integration;
 
+import javax.jcr.AccessDeniedException;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 
 import org.apache.jackrabbit.commons.JcrUtils;
 import org.apache.jackrabbit.test.AbstractJCRTest;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 /**
  * @see <a href="https://issues.apache.org/jira/browse/JCR-3992">JCR-3992</a>
+ *      and
+ *      <a href="https://issues.apache.org/jira/browse/JCR-4015">JCR-4015</a>
  */
 public class UtilsGetPathTest extends AbstractJCRTest {
 
     @Test
     public void testGetOrCreateByPath1() throws RepositoryException {
-        String path ="/foo";
+        String path = testRoot + "/foo";
         Node node = JcrUtils.getOrCreateByPath(path, "nt:unstructured", superuser);
         superuser.save();
         assertEquals(path, node.getPath());
         assertTrue(superuser.nodeExists(path));
 
         // existing top-level node, two new descendant nodes
-        String path2 ="/foo/a/b";
+        String path2 = testRoot + "/foo/a/b";
         Node node2 = JcrUtils.getOrCreateByPath(path2, "nt:unstructured", superuser);
         superuser.save();
         assertEquals(path2, node2.getPath());
         assertTrue(superuser.nodeExists(path2));
     }
+
+    @Test
+    public void testGetOrCreateByPathNoRoot() throws RepositoryException {
+        String base = testRoot + "/foo";
+        Node inter = JcrUtils.getOrCreateByPath(base, "nt:unstructured", superuser);
+        assertEquals(base, inter.getPath());
+        superuser.save();
+
+        // test what happens if getRootNode() throws
+        Session mockedSession = Mockito.spy(superuser);
+        Mockito.when(mockedSession.getRootNode()).thenThrow(new AccessDeniedException("access denied"));
+        Mockito.when(mockedSession.getNode("/")).thenThrow(new AccessDeniedException("access denied"));
+        Mockito.when(mockedSession.getItem("/")).thenThrow(new AccessDeniedException("access denied"));
+        Mockito.when(mockedSession.nodeExists("/")).thenReturn(false);
+
+        Node result = JcrUtils.getOrCreateByPath(base + "/bar", false, null, null, mockedSession, false);
+        mockedSession.save();
+        assertEquals(base + "/bar", result.getPath());
+
+        // already exists -> nop
+        Node result2 = JcrUtils.getOrCreateByPath(base + "/bar", false, null, null, mockedSession, false);
+        mockedSession.save();
+        assertEquals(base + "/bar", result2.getPath());
+
+        // create unique
+        Node result3 = JcrUtils.getOrCreateByPath(base + "/bar", true, null, null, mockedSession, false);
+        mockedSession.save();
+        assertEquals(base + "/bar0", result3.getPath());
+
+        // already exists with createUnique == false should pass even when parent isn't readable
+        Mockito.when(mockedSession.getNode(base)).thenThrow(new AccessDeniedException("access denied"));
+        Mockito.when(mockedSession.getItem(base)).thenThrow(new AccessDeniedException("access denied"));
+        Mockito.when(mockedSession.nodeExists(base)).thenReturn(false);
+        Node result4 = JcrUtils.getOrCreateByPath(base + "/bar", false, null, null, mockedSession, false);
+        mockedSession.save();
+        assertEquals(base + "/bar", result4.getPath());
+    }
 }

Modified: jackrabbit/branches/2.12/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JcrUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.12/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JcrUtils.java?rev=1759987&r1=1759986&r2=1759987&view=diff
==============================================================================
--- jackrabbit/branches/2.12/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JcrUtils.java (original)
+++ jackrabbit/branches/2.12/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/JcrUtils.java Fri Sep  9 11:39:38 2016
@@ -1448,10 +1448,27 @@ public class JcrUtils {
         if (absolutePath == null || absolutePath.length() == 0 || "/".equals(absolutePath)) {
             // path denotes root node
             return session.getRootNode();
+        } else if (!absolutePath.startsWith("/")) {
+            throw new IllegalArgumentException("not an absolute path: " + absolutePath);
+        } else if (session.nodeExists(absolutePath) && !createUniqueLeaf) {
+            return session.getNode(absolutePath);
+        } else {
+            // find deepest existing parent node
+            String path = absolutePath;
+            int currentIndex = path.lastIndexOf('/');
+            String existingPath = null;
+            while (currentIndex > 0 && existingPath == null) {
+                path = path.substring(0, currentIndex);
+                if (session.nodeExists(path)) {
+                    existingPath = path;
+                } else {
+                    currentIndex = path.lastIndexOf('/');
+                }
+            }
+            // create path relative to the root node
+            return getOrCreateByPath(existingPath == null ? session.getRootNode() : session.getNode(existingPath),
+                    absolutePath.substring(currentIndex + 1), createUniqueLeaf, intermediateNodeType, nodeType, autoSave);
         }
-        // create path relative to the root node
-        return getOrCreateByPath(session.getRootNode(), absolutePath.substring(1),
-                createUniqueLeaf, intermediateNodeType, nodeType, autoSave);
     }
 
     /**