Skip to content

Commit

Permalink
Fix creation of non-existent parent directory authZ with WLCG scopes (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
enricovianello authored Oct 16, 2024
1 parent 577ec80 commit dd7ae26
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class WlcgStructuredPathAuthorizationPdp
public static final String STORAGE_MODIFY = "storage.modify";
public static final String STORAGE_CREATE = "storage.create";

protected static final Set<String> READ_SCOPES = Sets.newHashSet(STORAGE_READ, STORAGE_STAGE);
protected static final Set<String> WRITE_SCOPES = Sets.newHashSet(STORAGE_CREATE, STORAGE_MODIFY);
protected static final Set<String> ALL_STORAGE_SCOPES =
Sets.newHashSet(STORAGE_READ, STORAGE_MODIFY, STORAGE_CREATE, STORAGE_STAGE);

Expand Down Expand Up @@ -128,35 +130,35 @@ boolean filterMatcherByRequest(HttpServletRequest request, String method,
StructuredPathScopeMatcher m, boolean requestedResourceExists) {

if (CATCHALL_METHODS.contains(method)) {
return ALL_STORAGE_SCOPES.stream().anyMatch(prefix -> m.getPrefix().equals(prefix));
return ALL_STORAGE_SCOPES.stream().anyMatch(prefix -> prefix.equals(m.getPrefix()));
}

if (READONLY_METHODS.contains(method)) {
return m.getPrefix().equals(STORAGE_READ) || m.getPrefix().equals(STORAGE_STAGE);
return READ_SCOPES.contains(m.getPrefix());
}
if (REPLACE_METHODS.contains(method)) {
if (requestedResourceExists) {
return m.getPrefix().equals(STORAGE_MODIFY);
return STORAGE_MODIFY.equals(m.getPrefix());
}
return m.getPrefix().equals(STORAGE_CREATE);
return WRITE_SCOPES.contains(m.getPrefix());
}
if (MODIFY_METHODS.contains(method)) {
return m.getPrefix().equals(STORAGE_MODIFY);
return STORAGE_MODIFY.equals(m.getPrefix());
}
if (COPY_METHOD.equals(method)) {

if (isPullTpc(request, localUrlService)) {
if (requestedResourceExists) {
return m.getPrefix().equals(STORAGE_MODIFY);
return STORAGE_MODIFY.equals(m.getPrefix());
}
return m.getPrefix().equals(STORAGE_CREATE);
return WRITE_SCOPES.contains(m.getPrefix());
}
return m.getPrefix().equals(STORAGE_READ);
return READ_SCOPES.contains(m.getPrefix());

}

if (MOVE_METHOD.equals(method)) {
return m.getPrefix().equals(STORAGE_MODIFY);
return STORAGE_MODIFY.equals(m.getPrefix());
}

throw new IllegalArgumentException(format(ERROR_UNSUPPORTED_METHOD_PATTERN, method));
Expand Down Expand Up @@ -212,10 +214,17 @@ public PathAuthorizationResult authorizeRequest(PathAuthorizationRequest authzRe
final boolean requestedResourceExists = pathResolver.pathExists(requestPath);
final String saPath = getStorageAreaPath(requestPath, sa);

scopeMatchers = scopeMatchers.stream()
.filter(m -> filterMatcherByRequest(request, method, m, requestedResourceExists))
.filter(m -> m.matchesPath(saPath))
.collect(toList());
if ("MKCOL".equals(method)) {
scopeMatchers = scopeMatchers.stream()
.filter(m -> filterMatcherByRequest(request, method, m, requestedResourceExists))
.filter(m -> m.matchesPathIncludingParents(saPath))
.collect(toList());
} else {
scopeMatchers = scopeMatchers.stream()
.filter(m -> filterMatcherByRequest(request, method, m, requestedResourceExists))
.filter(m -> m.matchesPath(saPath))
.collect(toList());
}

if (scopeMatchers.isEmpty()) {
return deny(ERROR_INSUFFICIENT_TOKEN_SCOPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Objects.nonNull;

import java.nio.file.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -37,15 +38,15 @@ public class StructuredPathScopeMatcher implements ScopeMatcher {
private static final String SEP_STR = SEP.toString();

private final String prefix;
private final String path;
private final Path path;

private final Pattern prefixMatchPattern;
private final Pattern pathMatchPattern;

private StructuredPathScopeMatcher(String prefix, String path) {

this.prefix = prefix;
this.path = path;
this.path = Path.of(path);

final String prefixMatchRegexp = String.format("^%s%c", prefix, SEP);
prefixMatchPattern = Pattern.compile(prefixMatchRegexp);
Expand Down Expand Up @@ -75,6 +76,11 @@ public boolean matchesScope(String scope) {
public boolean matchesPath(String path) {
return pathMatchPattern.matcher(path).matches();
}

public boolean matchesPathIncludingParents(String path) {
Path targetPath = Path.of(path);
return this.path.startsWith(targetPath) || matchesPath(path);
}

public static StructuredPathScopeMatcher fromString(String scope) {
final int sepIndex = scope.indexOf(SEP);
Expand Down Expand Up @@ -135,7 +141,7 @@ public String getPrefix() {
}

public String getPath() {
return path;
return path.toString();
}

}
Loading

0 comments on commit dd7ae26

Please sign in to comment.