/** * Resolve given table path relative to source resolve it to a valid path in filesystem. * If the resolved path refers to an entity not under the base of the source then a permission error is thrown. * @param tablePath * @return */ public Path resolveTablePathToValidPath(String tablePath) { String relativePathClean = PathUtils.removeLeadingSlash(tablePath); Path combined = new Path(basePath, relativePathClean); PathUtils.verifyNoAccessOutsideBase(basePath, combined); return combined; }
/** * Helper method which resolves the table name to actual file/folder on the filesystem. * If the resolved path refers to an entity not under the base of the source then a permission error is thrown. * * Ex. For given source named "dfs" which has base path of "/base" tableSchemaPath * [dfs, tmp, a] -> "/base/tmp/a" * [dfs, "/tmp/b"] -> "/base/tmp/b" * [dfs, "value", tbl] -> "/base/value/tbl" * @param tableSchemaPath * @return */ public List<String> resolveTableNameToValidPath(List<String> tableSchemaPath) { List<String> fullPath = new ArrayList<>(); fullPath.addAll(PathUtils.toPathComponents(basePath)); for (String pathComponent : tableSchemaPath.subList(1 /* need to skip the source name */, tableSchemaPath.size())) { fullPath.add(PathUtils.removeQuotes(pathComponent)); } PathUtils.verifyNoAccessOutsideBase(basePath, PathUtils.toFSPath(fullPath)); return fullPath; }
@Test public void testVerifyNoAccessOutsideBase() { PathUtils.verifyNoAccessOutsideBase(new Path("/"), new Path("/")); PathUtils.verifyNoAccessOutsideBase(new Path("/"), new Path("/a")); PathUtils.verifyNoAccessOutsideBase(new Path("/"), new Path("/a/b")); PathUtils.verifyNoAccessOutsideBase(new Path("/a"), new Path("/a/b")); PathUtils.verifyNoAccessOutsideBase(new Path("/a"), new Path("/a/b/c")); PathUtils.verifyNoAccessOutsideBase(new Path("/a"), new Path("/a/b/c")); try { PathUtils.verifyNoAccessOutsideBase(new Path("/a"), new Path("/a/../b/c")); fail(); } catch (UserException ex) { } try { PathUtils.verifyNoAccessOutsideBase(new Path("/a"), new Path("/a/b/../../c")); fail(); } catch (UserException ex) { } } }