use of org.dcache.macaroons.InvalidCaveatException in project dcache by dCache.
the class MacaroonRequestHandler method buildMacaroon.
private String buildMacaroon(String target, Request request) throws ErrorResponseException {
checkValidRequest(request.isSecure(), "Not secure transport");
if (Subjects.isNobody(getSubject())) {
throw new ErrorResponseException(SC_UNAUTHORIZED, "Authentication required");
}
MacaroonContext context = buildContext(target, request);
MacaroonRequest macaroonRequest = parseJSON(request);
try {
List<Caveat> caveats = new ArrayList<>();
List<Caveat> beforeCaveats = new ArrayList<>();
for (String serialisedCaveat : macaroonRequest.getCaveats()) {
Caveat caveat = new Caveat(serialisedCaveat);
(caveat.hasType(BEFORE) ? beforeCaveats : caveats).add(caveat);
}
macaroonRequest.getValidity().map(Duration::parse).map(Instant.now()::plus).map(i -> new Caveat(BEFORE, i)).ifPresent(beforeCaveats::add);
Instant expiry = calculateExpiry(context, beforeCaveats);
MacaroonProcessor.MacaroonBuildResult result = _processor.buildMacaroon(expiry, context, caveats);
request.setAttribute(MACAROON_ID_ATTRIBUTE, result.getId());
return result.getMacaroon();
} catch (DateTimeParseException e) {
throw new ErrorResponseException(SC_BAD_REQUEST, "Bad validity value: " + e.getMessage());
} catch (InvalidCaveatException e) {
throw new ErrorResponseException(SC_BAD_REQUEST, "Bad requested caveat: " + e.getMessage());
} catch (InternalErrorException e) {
throw new ErrorResponseException(SC_INTERNAL_SERVER_ERROR, "Internal error: " + e.getMessage());
}
}
use of org.dcache.macaroons.InvalidCaveatException in project dcache by dCache.
the class MacaroonRequestHandler method buildContext.
private MacaroonContext buildContext(String target, Request request) throws ErrorResponseException {
MacaroonContext context = new MacaroonContext();
FsPath desiredPath = _pathMapper.asDcachePath(request, target);
FsPath userRoot = FsPath.ROOT;
FsPath prefixRestrictionPath = null;
for (LoginAttribute attr : AuthenticationHandler.getLoginAttributes(request)) {
if (attr instanceof HomeDirectory) {
context.setHome(FsPath.ROOT.resolve(((HomeDirectory) attr).getHome()));
} else if (attr instanceof RootDirectory) {
userRoot = FsPath.ROOT.resolve(((RootDirectory) attr).getRoot());
} else if (attr instanceof Expiry) {
context.updateExpiry(((Expiry) attr).getExpiry());
} else if (attr instanceof DenyActivityRestriction) {
context.removeActivities(((DenyActivityRestriction) attr).getDenied());
} else if (attr instanceof PrefixRestriction) {
ImmutableSet<FsPath> paths = ((PrefixRestriction) attr).getPrefixes();
if (target.equals("/")) {
checkArgument(paths.size() == 1, "Cannot serialise with multiple path restrictions");
prefixRestrictionPath = paths.iterator().next();
} else {
prefixRestrictionPath = paths.stream().filter(desiredPath::hasPrefix).findFirst().orElseThrow(() -> new ErrorResponseException(SC_BAD_REQUEST, "Bad request path: Desired path not within existing path"));
}
} else if (attr instanceof Restriction) {
throw new ErrorResponseException(SC_BAD_REQUEST, "Cannot serialise restriction " + attr.getClass().getSimpleName());
} else if (attr instanceof MaxUploadSize) {
try {
context.updateMaxUpload(((MaxUploadSize) attr).getMaximumSize());
} catch (InvalidCaveatException e) {
throw new ErrorResponseException(SC_BAD_REQUEST, "Cannot add max-upload: " + e.getMessage());
}
}
}
Subject subject = getSubject();
context.setUid(Subjects.getUid(subject));
context.setGids(Subjects.getGids(subject));
context.setUsername(Subjects.getUserName(subject));
FsPath effectiveRoot = _pathMapper.effectiveRoot(userRoot, m -> new ErrorResponseException(SC_BAD_REQUEST, m));
context.setRoot(effectiveRoot);
FsPath path = prefixRestrictionPath != null ? prefixRestrictionPath : target.equals("/") ? null : desiredPath;
if (path != null) {
context.setPath(path.stripPrefix(effectiveRoot));
}
return context;
}
Aggregations