SENTRY-2032: Leading Slashes need to removed when creating HMS path entries (Arjun Mishra, reviewed by Alexander Kolbasov, Vadim Spector)
Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/9c541adf Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/9c541adf Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/9c541adf Branch: refs/heads/akolb-cli Commit: 9c541adf15194c44800555f0fb161463df68feac Parents: 5fc1e97 Author: Vadim Spector <[email protected]> Authored: Fri Nov 17 08:51:41 2017 -0800 Committer: Vadim Spector <[email protected]> Committed: Fri Nov 17 08:51:41 2017 -0800 ---------------------------------------------------------------------- .../sentry/core/common/utils/PathUtils.java | 8 ++- .../sentry/core/common/utils/TestPathUtils.java | 27 ++++++++++ .../db/service/persistent/TestSentryStore.java | 57 ++++++++++++++++++++ 3 files changed, 90 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/9c541adf/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PathUtils.java ---------------------------------------------------------------------- diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PathUtils.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PathUtils.java index cef8bd7..2d67a5b 100644 --- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PathUtils.java +++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PathUtils.java @@ -215,9 +215,13 @@ public class PathUtils { * Split path into elements. * May evolve to do something smarter, e.g. path canonicalization, * but for now simple split on "/" is sufficient. + * + * Remove leading, following, and consecutive slashes from path so + * input like "//a/b//c///" when split gives + * {a,b,c} instead of {"","",a,b,"",c,"","",""} */ public static String[] splitPath(String path) { - return (path != null) ? path.split("/+") : null; + path = path.replaceAll("(^/+)|(/+$)", ""); + return path.split("/+"); } - } http://git-wip-us.apache.org/repos/asf/sentry/blob/9c541adf/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestPathUtils.java ---------------------------------------------------------------------- diff --git a/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestPathUtils.java b/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestPathUtils.java index 8419b9d..329e668 100644 --- a/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestPathUtils.java +++ b/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestPathUtils.java @@ -21,8 +21,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.Lists; import java.net.URI; +import java.util.Arrays; +import java.util.List; import org.junit.Test; public class TestPathUtils { @@ -146,4 +149,28 @@ public class TestPathUtils { assertEquals("file://localhost:9999/tmp/hive-user", PathUtils.parseLocalURI("file://localhost:9999/tmp/hive-user")); } + + @Test + public void testStripSurplusSlashesAndSplitPath() throws Exception { + + List<String> expected = Arrays.asList("a", "b", "c"); + + String path = "a/b/c"; + assertEquals("Invalid split doesn't match expected output", expected, Lists.newArrayList(PathUtils.splitPath(path))); + + path = "/a/b/c"; + assertEquals("Invalid split doesn't match expected output", expected, Lists.newArrayList(PathUtils.splitPath(path))); + + path = "a/b/c/"; + assertEquals("Invalid split doesn't match expected output", expected, Lists.newArrayList(PathUtils.splitPath(path))); + + path = "/a/b/c/"; + assertEquals("Invalid split doesn't match expected output", expected, Lists.newArrayList(PathUtils.splitPath(path))); + + path = "/////a/b/c///"; + assertEquals("Invalid split doesn't match expected output", expected, Lists.newArrayList(PathUtils.splitPath(path))); + + path = "/////a//b//c///"; + assertEquals("Invalid split doesn't match expected output", expected, Lists.newArrayList(PathUtils.splitPath(path))); + } } http://git-wip-us.apache.org/repos/asf/sentry/blob/9c541adf/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java index cf83e77..90f35f1 100644 --- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java +++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStore.java @@ -3461,4 +3461,61 @@ public class TestSentryStore extends org.junit.Assert { } } + /** + * Test paths with multiple leading slashes + * @throws Exception + */ + @Test + public void testRetrievePathImageWithMultipleLeadingSlashes() throws Exception { + //Test with no leading slashes + String prefix = "user/hive/warehouse"; + String []prefixes = {"/" + prefix}; + Map<String, Collection<String>> authzPaths = new HashMap<>(); + // Makes sure that authorizable object could be associated + // with different paths and can be properly persisted into database. + String tablePath = prefix + "/loc1/db2.db/table1.1"; + authzPaths.put("db1.table1", Sets.newHashSet(tablePath)); + long notificationID = 1; + sentryStore.persistFullPathsImage(authzPaths, notificationID); + PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes); + assertEquals(notificationID, pathsUpdate.getImgNum()); + TPathsUpdate tPathsUpdate = pathsUpdate.toThrift(); + TPathsDump pathDump = tPathsUpdate.getPathsDump(); + Map<Integer, TPathEntry> nodeMap = pathDump.getNodeMap(); + assertEquals(7, nodeMap.size()); + + //Test with single leading slashes + prefix = "/user/hive/warehouse"; + prefixes = new String[]{prefix}; + authzPaths = new HashMap<>(); + // Makes sure that authorizable object could be associated + // with different paths and can be properly persisted into database. + tablePath = prefix + "/loc1/db2.db/table1.1"; + authzPaths.put("db1.table1", Sets.newHashSet(tablePath)); + notificationID = 2; + sentryStore.persistFullPathsImage(authzPaths, notificationID); + pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes); + assertEquals(notificationID, pathsUpdate.getImgNum()); + tPathsUpdate = pathsUpdate.toThrift(); + pathDump = tPathsUpdate.getPathsDump(); + nodeMap = pathDump.getNodeMap(); + assertEquals(7, nodeMap.size()); + + //Test with multiple leading slash + prefix = "///user/hive/warehouse"; + prefixes = new String[]{prefix}; + authzPaths = new HashMap<>(); + // Makes sure that authorizable object could be associated + // with different paths and can be properly persisted into database. + tablePath = prefix + "/loc1/db2.db/table1.1"; + authzPaths.put("db1.table1", Sets.newHashSet(tablePath)); + notificationID = 3; + sentryStore.persistFullPathsImage(authzPaths, notificationID); + pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes); + assertEquals(notificationID, pathsUpdate.getImgNum()); + tPathsUpdate = pathsUpdate.toThrift(); + pathDump = tPathsUpdate.getPathsDump(); + nodeMap = pathDump.getNodeMap(); + assertEquals(7, nodeMap.size()); + } }
