use of io.pravega.auth.TokenExpiredException in project pravega by pravega.
the class SegmentHelper method processAndRethrowException.
@VisibleForTesting
<T extends Request & WireCommand> void processAndRethrowException(long callerRequestId, T request, Throwable e) {
Throwable unwrap = Exceptions.unwrap(e);
WireCommandFailedException ex = null;
if (unwrap instanceof ConnectionFailedException || unwrap instanceof ConnectionClosedException) {
log.warn(callerRequestId, "Connection dropped {}", request.getRequestId());
throw new WireCommandFailedException(request.getType(), WireCommandFailedException.Reason.ConnectionFailed);
} else if (unwrap instanceof AuthenticationException) {
log.warn(callerRequestId, "Authentication Exception {}", request.getRequestId());
throw new WireCommandFailedException(request.getType(), WireCommandFailedException.Reason.AuthFailed);
} else if (unwrap instanceof TokenExpiredException) {
log.warn(callerRequestId, "Token expired {}", request.getRequestId());
throw new WireCommandFailedException(request.getType(), WireCommandFailedException.Reason.AuthFailed);
} else if (unwrap instanceof TimeoutException) {
log.warn(callerRequestId, "Request timed out. {}", request.getRequestId());
throw new WireCommandFailedException(request.getType(), WireCommandFailedException.Reason.ConnectionFailed);
} else {
log.error(callerRequestId, "Request failed {}", request.getRequestId(), e);
throw new CompletionException(e);
}
}
use of io.pravega.auth.TokenExpiredException in project pravega by pravega.
the class PravegaRequestProcessor method handleException.
private Void handleException(long requestId, String segment, long offset, String operation, Throwable u) {
if (u == null) {
IllegalStateException exception = new IllegalStateException("No exception to handle.");
log.error(requestId, "Error (Segment = '{}', Operation = '{}')", segment, operation, exception);
throw exception;
}
u = Exceptions.unwrap(u);
String clientReplyStackTrace = replyWithStackTraceOnError ? Throwables.getStackTraceAsString(u) : EMPTY_STACK_TRACE;
final Consumer<Throwable> failureHandler = t -> {
log.error(requestId, "Error (Segment = '{}', Operation = '{}')", segment, "handling result of " + operation, t);
connection.close();
};
if (u instanceof StreamSegmentExistsException) {
log.info(requestId, "Segment '{}' already exists and cannot perform operation '{}'.", segment, operation);
invokeSafely(connection::send, new SegmentAlreadyExists(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (u instanceof StreamSegmentNotExistsException) {
log.warn(requestId, "Segment '{}' does not exist and cannot perform operation '{}'.", segment, operation);
invokeSafely(connection::send, new NoSuchSegment(requestId, segment, clientReplyStackTrace, offset), failureHandler);
} else if (u instanceof StreamSegmentSealedException) {
log.info(requestId, "Segment '{}' is sealed and cannot perform operation '{}'.", segment, operation);
invokeSafely(connection::send, new SegmentIsSealed(requestId, segment, clientReplyStackTrace, offset), failureHandler);
} else if (u instanceof ContainerNotFoundException) {
int containerId = ((ContainerNotFoundException) u).getContainerId();
log.warn(requestId, "Wrong host. Segment = '{}' (Container {}) is not owned. Operation = '{}').", segment, containerId, operation);
invokeSafely(connection::send, new WrongHost(requestId, segment, "", clientReplyStackTrace), failureHandler);
} else if (u instanceof ReadCancellationException) {
log.info(requestId, "Sending empty response on connection {} while reading segment {} due to CancellationException.", connection, segment);
invokeSafely(connection::send, new SegmentRead(segment, offset, true, false, EMPTY_BUFFER, requestId), failureHandler);
} else if (u instanceof CancellationException) {
log.info(requestId, "Closing connection {} while performing {} due to {}.", connection, operation, u.toString());
connection.close();
} else if (u instanceof TokenExpiredException) {
log.warn(requestId, "Expired token during operation {}", operation);
invokeSafely(connection::send, new AuthTokenCheckFailed(requestId, clientReplyStackTrace, AuthTokenCheckFailed.ErrorCode.TOKEN_EXPIRED), failureHandler);
} else if (u instanceof TokenException) {
log.warn(requestId, "Token exception encountered during operation {}.", operation, u);
invokeSafely(connection::send, new AuthTokenCheckFailed(requestId, clientReplyStackTrace, AuthTokenCheckFailed.ErrorCode.TOKEN_CHECK_FAILED), failureHandler);
} else if (u instanceof UnsupportedOperationException) {
log.warn(requestId, "Unsupported Operation '{}'.", operation, u);
invokeSafely(connection::send, new OperationUnsupported(requestId, operation, clientReplyStackTrace), failureHandler);
} else if (u instanceof BadOffsetException) {
BadOffsetException badOffset = (BadOffsetException) u;
log.info(requestId, "Segment '{}' is truncated and cannot perform operation '{}' at offset '{}'", segment, operation, offset);
invokeSafely(connection::send, new SegmentIsTruncated(requestId, segment, badOffset.getExpectedOffset(), clientReplyStackTrace, offset), failureHandler);
} else if (u instanceof TableSegmentNotEmptyException) {
log.warn(requestId, "Table segment '{}' is not empty to perform '{}'.", segment, operation);
invokeSafely(connection::send, new TableSegmentNotEmpty(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (u instanceof KeyNotExistsException) {
log.warn(requestId, "Conditional update on Table segment '{}' failed as the key does not exist.", segment);
invokeSafely(connection::send, new WireCommands.TableKeyDoesNotExist(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (u instanceof BadKeyVersionException) {
log.warn(requestId, "Conditional update on Table segment '{}' failed due to bad key version.", segment);
invokeSafely(connection::send, new WireCommands.TableKeyBadVersion(requestId, segment, clientReplyStackTrace), failureHandler);
} else if (errorCodeExists(u)) {
log.warn(requestId, "Operation on segment '{}' failed due to a {}.", segment, u.getClass());
invokeSafely(connection::send, new WireCommands.ErrorMessage(requestId, segment, u.getMessage(), WireCommands.ErrorMessage.ErrorCode.valueOf(u.getClass())), failureHandler);
} else {
logError(requestId, segment, operation, u);
// Closing connection should reinitialize things, and hopefully fix the problem
connection.close();
throw new IllegalStateException("Unknown exception.", u);
}
return null;
}
use of io.pravega.auth.TokenExpiredException in project pravega by pravega.
the class TokenVerifierImpl method verifyToken.
@Override
public JsonWebToken verifyToken(@NonNull String resource, String token, @NonNull AuthHandler.Permissions expectedLevel) throws TokenExpiredException, InvalidTokenException, InvalidClaimException, TokenException {
if (Strings.isNullOrEmpty(token)) {
throw new InvalidTokenException("Token is null or empty");
}
// All key value pairs inside the payload are returned, including standard fields such as sub (for subject),
// aud (for audience), iat, exp, as well as custom fields of the form "<resource> -> <permission>" set by
// Pravega.
JsonWebToken jwt = JwtParser.parse(token, tokenSigningKey);
Map<String, Object> permissionsByResource = jwt.getPermissionsByResource();
Optional<Map.Entry<String, Object>> matchingClaim = permissionsByResource.entrySet().stream().filter(entry -> resourceMatchesClaimKey(entry.getKey(), resource) && expectedLevel.compareTo(AuthHandler.Permissions.valueOf(entry.getValue().toString())) <= 0).findFirst();
if (!matchingClaim.isPresent()) {
log.debug(String.format("No matching claim found for resource [%s] and permission [%s] in token.", resource, expectedLevel));
throw new InvalidClaimException(String.format("No matching claim found for resource: [%s] and permission: [%s] in the delegation token.", resource, expectedLevel));
}
return jwt;
}
use of io.pravega.auth.TokenExpiredException in project pravega by pravega.
the class ConditionalOutputStreamTest method handleUnexpectedReplythrowsAppropriateTokenExceptions.
@Test
public void handleUnexpectedReplythrowsAppropriateTokenExceptions() {
@Cleanup MockConnectionFactoryImpl connectionFactory = new MockConnectionFactoryImpl();
@Cleanup MockController controller = new MockController("localhost", 0, connectionFactory, true);
ConditionalOutputStreamFactory factory = new ConditionalOutputStreamFactoryImpl(controller, connectionFactory);
Segment segment = new Segment("scope", "testWrite", 1);
@Cleanup ConditionalOutputStreamImpl objectUnderTest = (ConditionalOutputStreamImpl) factory.createConditionalOutputStream(segment, DelegationTokenProviderFactory.create("token", controller, segment, AccessOperation.ANY), EventWriterConfig.builder().build());
AssertExtensions.assertThrows("AuthenticationException wasn't thrown", () -> objectUnderTest.handleUnexpectedReply(new WireCommands.AuthTokenCheckFailed(1L, "SomeException", WireCommands.AuthTokenCheckFailed.ErrorCode.TOKEN_CHECK_FAILED), "test"), e -> e instanceof AuthenticationException);
AssertExtensions.assertThrows("AuthenticationException wasn't thrown", () -> objectUnderTest.handleUnexpectedReply(new WireCommands.AuthTokenCheckFailed(1L, "SomeException", WireCommands.AuthTokenCheckFailed.ErrorCode.UNSPECIFIED), "test"), e -> e instanceof AuthenticationException);
AssertExtensions.assertThrows("TokenExpiredException wasn't thrown", () -> objectUnderTest.handleUnexpectedReply(new WireCommands.AuthTokenCheckFailed(1L, "SomeException", WireCommands.AuthTokenCheckFailed.ErrorCode.TOKEN_EXPIRED), "test"), e -> e instanceof TokenExpiredException);
AssertExtensions.assertThrows("InvalidEventNumber wasn't treated as a connection failure", () -> objectUnderTest.handleUnexpectedReply(new WireCommands.InvalidEventNumber(UUID.randomUUID(), 1, "SomeException"), "test"), e -> e instanceof ConnectionFailedException);
AssertExtensions.assertThrows("Hello wasn't treated as a connection failure", () -> objectUnderTest.handleUnexpectedReply(new WireCommands.Hello(1, 1), "test"), e -> e instanceof ConnectionFailedException);
}
use of io.pravega.auth.TokenExpiredException in project pravega by pravega.
the class ConditionalOutputStreamImpl method handleUnexpectedReply.
@VisibleForTesting
RuntimeException handleUnexpectedReply(Reply reply, String expectation) {
log.warn("Unexpected reply {} observed instead of {} for conditional writer {}", reply, expectation, writerId);
closeConnection(reply.toString());
if (reply instanceof WireCommands.NoSuchSegment) {
throw new NoSuchSegmentException(reply.toString());
} else if (reply instanceof SegmentIsSealed) {
throw Exceptions.sneakyThrow(new SegmentSealedException(reply.toString()));
} else if (reply instanceof WrongHost) {
throw Exceptions.sneakyThrow(new ConnectionFailedException(reply.toString()));
} else if (reply instanceof InvalidEventNumber) {
InvalidEventNumber ien = (InvalidEventNumber) reply;
throw Exceptions.sneakyThrow(new ConnectionFailedException(ien.getWriterId() + " Got stale data from setupAppend on segment " + segmentId + " for ConditionalOutputStream. Event number was " + ien.getEventNumber()));
} else if (reply instanceof AuthTokenCheckFailed) {
AuthTokenCheckFailed authTokenCheckFailed = (WireCommands.AuthTokenCheckFailed) reply;
if (authTokenCheckFailed.isTokenExpired()) {
this.tokenProvider.signalTokenExpired();
throw Exceptions.sneakyThrow(new TokenExpiredException(authTokenCheckFailed.getServerStackTrace()));
} else {
throw Exceptions.sneakyThrow(new AuthenticationException(authTokenCheckFailed.toString()));
}
} else {
throw Exceptions.sneakyThrow(new ConnectionFailedException("Unexpected reply of " + reply + " when expecting an " + expectation));
}
}
Aggregations