Return-Path: X-Original-To: apmail-sling-commits-archive@www.apache.org Delivered-To: apmail-sling-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6C3E99659 for ; Fri, 22 Jun 2012 12:45:09 +0000 (UTC) Received: (qmail 45674 invoked by uid 500); 22 Jun 2012 12:45:09 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 45621 invoked by uid 500); 22 Jun 2012 12:45:08 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 45601 invoked by uid 99); 22 Jun 2012 12:45:07 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 22 Jun 2012 12:45:07 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 22 Jun 2012 12:45:04 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id D9C112388865; Fri, 22 Jun 2012 12:44:42 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1352865 - in /sling/trunk: bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/ launchpad/integration-tests/src/main/java/or... Date: Fri, 22 Jun 2012 12:44:42 -0000 To: commits@sling.apache.org From: bdelacretaz@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120622124442.D9C112388865@eris.apache.org> Author: bdelacretaz Date: Fri Jun 22 12:44:41 2012 New Revision: 1352865 URL: http://svn.apache.org/viewvc?rev=1352865&view=rev Log: SLING-2517 - validity checks for CopyFrom paths, with tests Added: sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java?rev=1352865&r1=1352864&r2=1352865&view=diff ============================================================================== --- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java (original) +++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java Fri Jun 22 12:44:41 2012 @@ -97,6 +97,11 @@ public class CopyOperation extends Abstr static Item copy(Node src, Node dstParent, String name) throws RepositoryException { + if(isAncestorOrSameNode(src, dstParent)) { + throw new RepositoryException( + "Cannot copy ancestor " + src.getPath() + " to descendant " + dstParent.getPath()); + } + // ensure destination name if (name == null) { name = src.getName(); @@ -127,6 +132,19 @@ public class CopyOperation extends Abstr } return dst; } + + /** @return true if src is an ancestor node of dest, or if + * both are the same node */ + static boolean isAncestorOrSameNode(Node src, Node dest) throws RepositoryException { + if(src.getPath().equals("/")) { + return true; + } else if(src.getPath().equals(dest.getPath())) { + return true; + } else if(dest.getPath().startsWith(src.getPath() + "/")) { + return true; + } + return false; + } /** * Copy the src property into the dstParent Added: sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java?rev=1352865&view=auto ============================================================================== --- sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java (added) +++ sling/trunk/bundles/servlets/post/src/test/java/org/apache/sling/servlets/post/impl/operations/CopyOperationTest.java Fri Jun 22 12:44:41 2012 @@ -0,0 +1,77 @@ +/* + * 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.sling.servlets.post.impl.operations; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import junit.framework.TestCase; + +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.jmock.integration.junit4.JMock; +import org.jmock.integration.junit4.JUnit4Mockery; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(JMock.class) +public class CopyOperationTest extends TestCase { + private Mockery context = new JUnit4Mockery(); + private int counter; + + private void assertResult(final String srcPath, final String destPath, Boolean expectedResult) throws RepositoryException { + counter++; + final Node src = context.mock(Node.class, "src" + counter); + final Node dest = context.mock(Node.class, "dest" + counter); + + context.checking(new Expectations() { + { + allowing(src).getPath(); + will(returnValue(srcPath)); + allowing(dest).getPath(); + will(returnValue(destPath)); + } + }); + + final boolean result = CopyOperation.isAncestorOrSameNode(src, dest); + assertEquals( + "Expecting isAncestorOrSameNode to be " + expectedResult + " for " + srcPath + " and " + destPath, + expectedResult.booleanValue(), result); + } + + @Test + public void testIsAncestorOrSameNode() throws RepositoryException { + final Object [] testCases = { + "/", "/", true, + "/a", "/a", true, + "/a/bee/ceee", "/a/bee/ceee", true, + "/", "/tmp", true, + "/a", "/a/b", true, + "/a", "/a/b/c/dee/eeee", true, + "/a", "/ab", false, + "/ab/cd", "/ab/cde", false, + "/ab", "/cd", false, + }; + + for(int i=0; i < testCases.length; i+=3) { + assertResult((String)testCases[i], (String)testCases[i+1], (Boolean)(testCases[i+2])); + } + + } +} \ No newline at end of file Modified: sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java?rev=1352865&r1=1352864&r2=1352865&view=diff ============================================================================== --- sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java (original) +++ sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletAtCopyTest.java Fri Jun 22 12:44:41 2012 @@ -17,9 +17,14 @@ package org.apache.sling.launchpad.webapp.integrationtest.servlets.post; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.httpclient.NameValuePair; import org.apache.sling.commons.testing.integration.HttpTestBase; /** Test item copy support by @CopyFrom suffix (SLING-455) */ @@ -195,5 +200,35 @@ public class PostServletAtCopyTest exten String content = getContent(HTTP_BASE_URL + testPath + "/some/not/existing/structure.json", CONTENT_TYPE_JSON); assertJavascript("Hello", content, "out.println(data.text)"); } - + + /** Copying siblings should work */ + public void testCopySibling() throws IOException { + final String testPath = TEST_BASE_PATH + "/AT_sibling/" + System.currentTimeMillis(); + final Map props = new HashMap(); + props.put("text", "Hello ATcsp"); + testClient.createNode(HTTP_BASE_URL + testPath + "/a/1", props); + testClient.createNode(HTTP_BASE_URL + testPath + "/a/12", props); + + final List opt = new ArrayList(); + opt.add(new NameValuePair(testPath + "/a/12/13@CopyFrom", testPath + "/a/1")); + + final int expectedStatus = HttpServletResponse.SC_OK; + assertPostStatus(HTTP_BASE_URL + testPath, expectedStatus, opt, "Expecting status " + expectedStatus); + + // assert content at old and new locations + for(String path : new String[] { "/a/1", "/a/12", "/a/12/13" }) { + final String content = getContent(HTTP_BASE_URL + testPath + path + ".json", CONTENT_TYPE_JSON); + assertJavascript("Hello ATcsp", content, "out.println(data.text)", "at path " + path); + } + } + + public void testCopyAncestor() throws IOException { + final String testPath = TEST_BASE_PATH + "/AT_tcanc/" + System.currentTimeMillis(); + + final List opt = new ArrayList(); + opt.add(new NameValuePair(testPath + "./@CopyFrom", "../")); + + final int expectedStatus = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + assertPostStatus(HTTP_BASE_URL + testPath, expectedStatus, opt, "Expecting status " + expectedStatus); + } } \ No newline at end of file Modified: sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java?rev=1352865&r1=1352864&r2=1352865&view=diff ============================================================================== --- sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java (original) +++ sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java Fri Jun 22 12:44:41 2012 @@ -578,4 +578,43 @@ public class PostServletCopyTest extends testClient.delete(testRoot); } + + /** Copying siblings should work */ + public void testCopySibling() throws IOException { + final String testPath = TEST_BASE_PATH + "/csp/" + System.currentTimeMillis(); + final Map props = new HashMap(); + props.put("text", "Hello csp"); + testClient.createNode(HTTP_BASE_URL + testPath + "/a/1", props); + testClient.createNode(HTTP_BASE_URL + testPath + "/a/12", props); + + props.clear(); + props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY); + props.put(SlingPostConstants.RP_DEST, testPath + "/a/12/13"); + testClient.createNode(HTTP_BASE_URL + testPath + "/a/1", props); + + // assert content at old and new locations + for(String path : new String[] { "/a/1", "/a/12", "/a/12/13" }) { + final String content = getContent(HTTP_BASE_URL + testPath + path + ".json", CONTENT_TYPE_JSON); + assertJavascript("Hello csp", content, "out.println(data.text)", "at path " + path); + } + } + + /** Copying an ancestor to a descendant should fail */ + public void testCopyAncestor() throws IOException { + final String testPath = TEST_BASE_PATH + "/tcanc/" + System.currentTimeMillis(); + final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath, null); + final String parentPath = testPath + "/a/b"; + final String childPath = parentPath + "/child"; + + final String parentUrl = testClient.createNode(HTTP_BASE_URL + parentPath, null); + assertFalse("child node must not exist before copy", + getContent(parentUrl + ".2.json", CONTENT_TYPE_JSON).contains("child")); + + final List opt = new ArrayList(); + opt.add(new NameValuePair(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY)); + opt.add(new NameValuePair(SlingPostConstants.RP_DEST, childPath)); + + final int expectedStatus = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + assertPostStatus(testRoot, expectedStatus, opt, "Expecting status " + expectedStatus); + } } \ No newline at end of file