From 6eb2d40fb9049c31c502a86e99c5464a7242ccf2 Mon Sep 17 00:00:00 2001 From: Ancuta Morarasu Date: Wed, 11 May 2016 11:14:51 +0000 Subject: [PATCH] Merged HEAD (5.2) to 5.2.N (5.2.1) 126419 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 121799 jvonka: FileFolder API - minor validation fix when listing children via "relativePath" - also check type of parentId (to be a folder) before (as well as after) resolving relative path RA-753 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126765 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/rest/api/impl/NodesImpl.java | 45 ++++++++++++++----- .../alfresco/rest/api/tests/NodeApiTest.java | 4 ++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/source/java/org/alfresco/rest/api/impl/NodesImpl.java b/source/java/org/alfresco/rest/api/impl/NodesImpl.java index 089ed44196..115a734b2f 100644 --- a/source/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -275,6 +275,8 @@ public class NodesImpl implements Nodes new HashSet<>(Arrays.asList(new String[] {PARAM_ISFOLDER, PARAM_NODETYPE, PARAM_SUBTYPES})); /* + * Validates that node exists. + * * Note: assumes workspace://SpacesStore */ public NodeRef validateNode(String nodeId) @@ -312,9 +314,17 @@ public class NodesImpl implements Nodes return nodeRef; } + /* + * Check that nodes exists and matches given expected/excluded type(s). + */ public boolean nodeMatches(NodeRef nodeRef, Set expectedTypes, Set excludedTypes) { - if (!nodeService.exists(nodeRef)) + return nodeMatches(nodeRef, expectedTypes, excludedTypes, true); + } + + public boolean nodeMatches(NodeRef nodeRef, Set expectedTypes, Set excludedTypes, boolean existsCheck) + { + if (existsCheck && (! nodeService.exists(nodeRef))) { throw new EntityNotFoundException(nodeRef.getId()); } @@ -334,6 +344,13 @@ public class NodesImpl implements Nodes protected boolean typeMatches(QName type, Set expectedTypes, Set excludedTypes) { + if (((expectedTypes != null) && (expectedTypes.size() == 1)) && + ((excludedTypes == null) || (excludedTypes.size() == 0))) + { + // use isSubClass if checking against single expected type (and no excluded types) + return isSubClass(type, expectedTypes.iterator().next()); + } + Set allExpectedTypes = new HashSet<>(); if (expectedTypes != null) { @@ -537,6 +554,12 @@ public class NodesImpl implements Nodes if (path != null) { + // check that parent is a folder before resolving relative path + if (! nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null, false)) + { + throw new InvalidArgumentException("NodeId of folder is expected"); + } + // resolve path relative to current nodeId parentNodeRef = resolveNodeByPath(parentNodeRef, path, true); } @@ -677,7 +700,7 @@ public class NodesImpl implements Nodes if (selectParam.contains(PARAM_SELECT_ISLINK)) { - boolean isLink = typeMatches(nodeTypeQName, Collections.singleton(ContentModel.TYPE_LINK), null); + boolean isLink = isSubClass(nodeTypeQName, ContentModel.TYPE_LINK); node.setIsLink(isLink); } @@ -870,8 +893,15 @@ public class NodesImpl implements Nodes public CollectionWithPagingInfo listChildren(String parentFolderNodeId, Parameters parameters) { String path = parameters.getParameter(PARAM_RELATIVE_PATH); + final NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, path); + // check that resolved node is a folder + if (! nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null, false)) + { + throw new InvalidArgumentException("NodeId of folder is expected"); + } + final List selectParam = parameters.getSelectedProperties(); boolean includeFolders = true; @@ -938,11 +968,6 @@ public class NodesImpl implements Nodes Paging paging = parameters.getPaging(); - if (!nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null)) - { - throw new InvalidArgumentException("NodeId of folder is expected"); - } - PagingRequest pagingRequest = Util.getPagingRequest(paging); final PagingResults pagingResults; @@ -1052,7 +1077,7 @@ public class NodesImpl implements Nodes // check that requested parent node exists and it's type is a (sub-)type of folder final NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null); - if (! nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null)) + if (! nodeMatches(parentNodeRef, Collections.singleton(ContentModel.TYPE_FOLDER), null, false)) { throw new InvalidArgumentException("NodeId of folder is expected: "+parentNodeRef); } @@ -1356,7 +1381,7 @@ public class NodesImpl implements Nodes { final NodeRef nodeRef = validateNode(fileNodeId); - if (! nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null)) + if (! nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null, false)) { throw new InvalidArgumentException("NodeId of content is expected: "+nodeRef); } @@ -1401,7 +1426,7 @@ public class NodesImpl implements Nodes { final NodeRef nodeRef = validateNode(fileNodeId); - if (!nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null)) + if (!nodeMatches(nodeRef, Collections.singleton(ContentModel.TYPE_CONTENT), null, false)) { throw new InvalidArgumentException("NodeId of content is expected: " + nodeRef); } diff --git a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java index 7bb7118010..a43146d375 100644 --- a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java @@ -498,6 +498,10 @@ public class NodeApiTest extends AbstractBaseApiTest // -ve test - try to list children using relative path to node that is of wrong type (ie. not a folder/container) params = Collections.singletonMap("relativePath", folder1 + "/" + contentF1); getAll(myChildrenUrl, user1, paging, params, 400); + + // -ve test - list folder children for non-folder node with relative path should return 400 + params = Collections.singletonMap("relativePath", "/unknown"); + getAll(getChildrenUrl(contentNodeRef), user1, paging, params, 400); } /**