Skip to content

Commit

Permalink
webdav/macaroon: Fix macaroon creation with multiple path restrictions.
Browse files Browse the repository at this point in the history
Motivation:

When several path restrictions exist, typically the home and upload paths, the macaroon
creation fails with a http error 500 and the error message
"Cannot serialise with multiple path restrictions".

Modification:

The macaroon creation logic has been reviewed to check if the requested path for the
macaroon is contained in each path restriction. If yes, the macaroon creation succeeds.
If not, the macaroon creation fails with the error "Bad request path: Desired path not within existing path".

Result:

The macaroon creation succeeds when multiple path restrictions are defined.

Acked-by: Paul Millar
Target: master, 4.2, 4.1, 4.0, 3.2
Require-notes: yes
Require-book: no
Patch: https://rb.dcache.org/r/11154/
Committed:
Pull-request: https://github.com/dCache/dcache/pull/xxxx
Signed-off-by: Vincent Garonne vgaronne@gmail.com
  • Loading branch information
vingar committed Sep 5, 2018
1 parent 204024b commit 99c726e
Showing 1 changed file with 17 additions and 20 deletions.
Expand Up @@ -240,24 +240,32 @@ private Instant calculateExpiry(MacaroonContext context, Collection<Caveat> befo
return expiry;
}

private MacaroonContext buildContext(String target, Request request) throws ErrorResponseException
{
private MacaroonContext buildContext(String target, Request request) throws ErrorResponseException {

MacaroonContext context = new MacaroonContext();

FsPath userRoot = FsPath.ROOT;
for (LoginAttribute attr : AuthenticationHandler.getLoginAttributes(request)) {
if (attr instanceof HomeDirectory) {
context.setHome(FsPath.ROOT.resolve(((HomeDirectory)attr).getHome()));
context.setHome(FsPath.ROOT.resolve(((HomeDirectory) attr).getHome()));
} else if (attr instanceof RootDirectory) {
userRoot = FsPath.ROOT.resolve(((RootDirectory)attr).getRoot());
userRoot = FsPath.ROOT.resolve(((RootDirectory) attr).getRoot());
} else if (attr instanceof Expiry) {
context.updateExpiry(((Expiry)attr).getExpiry());
context.updateExpiry(((Expiry) attr).getExpiry());
} else if (attr instanceof DenyActivityRestriction) {
context.removeActivities(((DenyActivityRestriction)attr).getDenied());
context.removeActivities(((DenyActivityRestriction) attr).getDenied());
} else if (attr instanceof PrefixRestriction) {
ImmutableSet<FsPath> paths = ((PrefixRestriction)attr).getPrefixes();
checkArgument(paths.size() == 1, "Cannot serialise with multiple path restrictions");
context.setPath(paths.iterator().next());
ImmutableSet<FsPath> paths = ((PrefixRestriction) attr).getPrefixes();
if (target.equals("/")) {
checkArgument(paths.size() == 1, "Cannot serialise with multiple path restrictions");
context.setPath(paths.iterator().next());
} else {
FsPath desiredPath = _pathMapper.asDcachePath(request, target);
if (!paths.stream().anyMatch(desiredPath::hasPrefix)) {
throw new ErrorResponseException(SC_BAD_REQUEST, "Bad request path: Desired path not within existing path");
}
context.setPath(desiredPath);
}
} else if (attr instanceof Restriction) {
throw new ErrorResponseException(SC_BAD_REQUEST, "Cannot serialise restriction " + attr.getClass().getSimpleName());
}
Expand All @@ -267,19 +275,8 @@ private MacaroonContext buildContext(String target, Request request) throws Erro
context.setUid(Subjects.getUid(subject));
context.setGids(Subjects.getGids(subject));
context.setUsername(Subjects.getUserName(subject));

context.setRoot(_pathMapper.effectiveRoot(userRoot, m -> new ErrorResponseException(SC_BAD_REQUEST, m)));

try {
if (!target.equals("/")) {
FsPath desiredPath = _pathMapper.asDcachePath(request, target);
checkCaveat(desiredPath.hasPrefix(context.getPath().orElse(FsPath.ROOT)), "Desired path not within existing path");
context.setPath(desiredPath);
}
} catch (InvalidCaveatException e) {
throw new ErrorResponseException(SC_BAD_REQUEST, "Bad request path: " + e.getMessage());
}

return context;
}

Expand Down

0 comments on commit 99c726e

Please sign in to comment.