use of io.pravega.auth.AuthException in project pravega by pravega.
the class StreamMetadataResourceImpl method listStreams.
/**
* Implementation of listStreams REST API.
*
* @param scopeName The scope name of stream.
* @param securityContext The security for API access.
* @param asyncResponse AsyncResponse provides means for asynchronous server side response processing.
*/
@Override
public void listStreams(final String scopeName, final String filterType, final String filterValue, final SecurityContext securityContext, final AsyncResponse asyncResponse) {
long traceId = LoggerHelpers.traceEnter(log, "listStreams");
long requestId = requestIdGenerator.nextLong();
final Principal principal;
final List<String> authHeader = getAuthorizationHeader();
try {
principal = restAuthHelper.authenticate(authHeader);
restAuthHelper.authorize(authHeader, authorizationResource.ofStreamsInScope(scopeName), principal, READ);
} catch (AuthException e) {
log.warn(requestId, "List streams for {} failed due to authentication failure.", scopeName);
asyncResponse.resume(Response.status(Status.fromStatusCode(e.getResponseCode())).build());
LoggerHelpers.traceLeave(log, "listStreams", traceId);
return;
}
boolean showOnlyInternalStreams = filterType != null && filterType.equals("showInternalStreams");
boolean showStreamsWithTag = filterType != null && filterType.equals("tag");
String tag;
if (showStreamsWithTag && filterValue != null) {
tag = filterValue;
List<Stream> streams = new ArrayList<>();
String finalTag = tag;
localController.listStreamsForTag(scopeName, tag).collectRemaining(streams::add).thenCompose(v -> {
List<CompletableFuture<ImmutablePair<Stream, StreamConfiguration>>> streamConfigFutureList = streams.stream().filter(stream -> {
boolean isAuthorized = false;
try {
isAuthorized = restAuthHelper.isAuthorized(authHeader, authorizationResource.ofStreamInScope(scopeName, stream.getStreamName()), principal, READ);
} catch (AuthException e) {
log.warn(requestId, "List Streams with tag {} for scope {} failed due to authentication failure.", finalTag, scopeName);
// Ignore. This exception occurs under abnormal circumstances and not to determine
// whether the user is authorized. In case it does occur, we assume that the user
// is unauthorized.
}
return isAuthorized;
}).map(stream -> localController.getStreamConfiguration(scopeName, stream.getStreamName()).thenApply(config -> new ImmutablePair<>(stream, config))).collect(Collectors.toList());
return Futures.allOfWithResults(streamConfigFutureList);
}).thenApply(streamConfigPairs -> {
StreamsList responseStreams = new StreamsList();
responseStreams.setStreams(new ArrayList<>());
streamConfigPairs.forEach(pair -> responseStreams.addStreamsItem(ModelHelper.encodeStreamResponse(pair.left.getScope(), pair.left.getStreamName(), pair.right)));
log.info(requestId, "Successfully fetched streams for scope: {} with tag: {}", scopeName, finalTag);
return Response.status(Status.OK).entity(responseStreams).build();
}).exceptionally(exception -> {
if (exception.getCause() instanceof StoreException.DataNotFoundException || exception instanceof StoreException.DataNotFoundException) {
log.warn(requestId, "Scope name: {} not found", scopeName);
return Response.status(Status.NOT_FOUND).build();
} else {
log.warn(requestId, "listStreams for {} with tag {} failed with exception: {}", scopeName, finalTag, exception);
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
}).thenApply(asyncResponse::resume).thenAccept(x -> LoggerHelpers.traceLeave(log, "listStreams", traceId));
} else {
controllerService.listStreamsInScope(scopeName, requestId).thenApply(streamsList -> {
StreamsList streams = new StreamsList();
streams.setStreams(new ArrayList<>());
streamsList.forEach((stream, config) -> {
try {
if (restAuthHelper.isAuthorized(authHeader, authorizationResource.ofStreamInScope(scopeName, stream), principal, READ)) {
// otherwise display the regular user created streams.
if (!showOnlyInternalStreams ^ stream.startsWith(INTERNAL_NAME_PREFIX)) {
streams.addStreamsItem(ModelHelper.encodeStreamResponse(scopeName, stream, config));
}
}
} catch (AuthException e) {
log.warn(requestId, "Read internal streams for scope {} failed due to authentication failure.", scopeName);
// Ignore. This exception occurs under abnormal circumstances and not to determine
// whether the user is authorized. In case it does occur, we assume that the user
// is unauthorized.
}
});
log.info(requestId, "Successfully fetched streams for scope: {}", scopeName);
return Response.status(Status.OK).entity(streams).build();
}).exceptionally(exception -> {
if (exception.getCause() instanceof StoreException.DataNotFoundException || exception instanceof StoreException.DataNotFoundException) {
log.warn(requestId, "Scope name: {} not found", scopeName);
return Response.status(Status.NOT_FOUND).build();
} else {
log.warn(requestId, "listStreams for {} failed with exception: {}", scopeName, exception);
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
}).thenApply(asyncResponse::resume).thenAccept(x -> LoggerHelpers.traceLeave(log, "listStreams", traceId));
}
}
use of io.pravega.auth.AuthException in project pravega by pravega.
the class StreamMetadataResourceImpl method listReaderGroups.
@Override
public void listReaderGroups(final String scopeName, final SecurityContext securityContext, final AsyncResponse asyncResponse) {
long traceId = LoggerHelpers.traceEnter(log, "listReaderGroups");
long requestId = requestIdGenerator.nextLong();
try {
restAuthHelper.authenticateAuthorize(getAuthorizationHeader(), authorizationResource.ofReaderGroupsInScope(scopeName), READ);
} catch (AuthException e) {
log.warn(requestId, "Get reader groups for {} failed due to authentication failure.", scopeName);
asyncResponse.resume(Response.status(Status.fromStatusCode(e.getResponseCode())).build());
LoggerHelpers.traceLeave(log, "listReaderGroups", traceId);
return;
}
// Each reader group is represented by a stream within the mentioned scope.
controllerService.listStreamsInScope(scopeName, requestId).thenApply(streamsList -> {
ReaderGroupsList readerGroups = new ReaderGroupsList();
streamsList.forEach((stream, config) -> {
if (stream.startsWith(READER_GROUP_STREAM_PREFIX)) {
ReaderGroupsListReaderGroups readerGroup = new ReaderGroupsListReaderGroups();
readerGroup.setReaderGroupName(stream.substring(READER_GROUP_STREAM_PREFIX.length()));
readerGroups.addReaderGroupsItem(readerGroup);
}
});
log.info(requestId, "Successfully fetched readerGroups for scope: {}", scopeName);
return Response.status(Status.OK).entity(readerGroups).build();
}).exceptionally(exception -> {
if (exception.getCause() instanceof StoreException.DataNotFoundException || exception instanceof StoreException.DataNotFoundException) {
log.warn(requestId, "Scope name: {} not found", scopeName);
return Response.status(Status.NOT_FOUND).build();
} else {
log.warn(requestId, "listReaderGroups for {} failed with exception: ", scopeName, exception);
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
}).thenApply(asyncResponse::resume).thenAccept(x -> LoggerHelpers.traceLeave(log, "listReaderGroups", traceId));
}
use of io.pravega.auth.AuthException in project pravega by pravega.
the class AuthInterceptor method interceptCall.
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
Context context = Context.current();
// The authorization header has the credentials (e.g., username and password for Basic Authentication).
// The form of the header is: <Method> <Token> (CustomMethod static-token, or Basic XYZ...., for example)
String credentials = headers.get(Metadata.Key.of(AuthConstants.AUTHORIZATION, Metadata.ASCII_STRING_MARSHALLER));
if (!Strings.isNullOrEmpty(credentials)) {
String[] parts = credentials.split("\\s+", 2);
if (parts.length == 2) {
String method = parts[0];
String token = parts[1];
if (!Strings.isNullOrEmpty(method)) {
if (method.equals(handler.getHandlerName())) {
log.debug("Handler [{}] successfully matched auth method [{}]", handler, method);
Principal principal;
try {
if ((principal = handler.authenticate(token)) == null) {
log.warn("Handler for method [{}] returned a null Principal upon authentication for the" + "given token", method);
call.close(Status.fromCode(Status.Code.UNAUTHENTICATED), headers);
return null;
}
} catch (AuthException e) {
log.warn("Authentication failed", e);
call.close(Status.fromCode(Status.Code.UNAUTHENTICATED), headers);
return null;
}
// Creates a new Context with the given key/value pairs.
context = context.withValues(PRINCIPAL_OBJECT_KEY, principal, AUTH_INTERCEPTOR_OBJECT_KEY, this);
}
} else {
log.debug("Credentials are present, but method [{}] is null or empty", method);
}
}
}
// reaching this point means that the handler wasn't applicable to this request.
return Contexts.interceptCall(context, call, headers, next);
}
Aggregations