| 31 | import org.openqa.selenium.internal.Require; |
| 32 | |
| 33 | public class PathResource implements Resource { |
| 34 | |
| 35 | private final Path base; |
| 36 | private final Predicate<Path> allowedSubpaths; |
| 37 | |
| 38 | public PathResource(Path base) { |
| 39 | this(Require.nonNull("Base path", base), str -> true); |
| 40 | } |
| 41 | |
| 42 | private PathResource(Path base, Predicate<Path> allowedSubpaths) { |
| 43 | this.base = Require.nonNull("Base path", base).normalize(); |
| 44 | this.allowedSubpaths = Require.nonNull("Sub-path predicate", allowedSubpaths); |
| 45 | } |
| 46 | |
| 47 | public PathResource limit(String... subpaths) { |
| 48 | return new PathResource( |
| 49 | base, |
| 50 | path -> Arrays.stream(subpaths).anyMatch(subpath -> Files.exists(base.resolve(subpath)))); |
| 51 | } |
| 52 | |
| 53 | @Override |
| 54 | public String name() { |
| 55 | return base.getFileName() == null ? "" : base.getFileName().toString(); |
| 56 | } |
| 57 | |
| 58 | @Override |
| 59 | public Optional<Resource> get(String path) { |
| 60 | // Paths are expected to start with a leading slash. Strip it, if present |
| 61 | if (path.startsWith("/")) { |
| 62 | path = path.length() == 1 ? "" : path.substring(1); |
| 63 | } |
| 64 | |
| 65 | Path normalized = base.resolve(path).normalize(); |
| 66 | if (!normalized.startsWith(base)) { |
| 67 | throw new RuntimeException("Attempt to navigate away from the parent directory"); |
| 68 | } |
| 69 | |
| 70 | if (!allowedSubpaths.test(normalized)) { |
| 71 | return Optional.empty(); |
| 72 | } |
| 73 | |
| 74 | if (Files.exists(normalized)) { |
| 75 | return Optional.of(new PathResource(normalized)); |
| 76 | } |
| 77 | |
| 78 | return Optional.empty(); |
| 79 | } |
| 80 | |
| 81 | @Override |
| 82 | public boolean isDirectory() { |
| 83 | return Files.isDirectory(base); |
| 84 | } |
| 85 | |
| 86 | @Override |
| 87 | public Set<Resource> list() { |
| 88 | try (Stream<Path> files = Files.list(base)) { |
| 89 | return files.filter(allowedSubpaths).map(PathResource::new).collect(toUnmodifiableSet()); |
| 90 | } catch (IOException e) { |
nothing calls this directly
no outgoing calls
no test coverage detected