use of uk.gov.di.authentication.shared.exceptions.ClientNotFoundException in project di-authentication-api by alphagov.
the class AuthCodeHandler method handleRequest.
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent input, Context context) {
return isWarming(input).orElseGet(() -> {
Session session = sessionService.getSessionFromRequestHeaders(input.getHeaders()).orElse(null);
if (Objects.isNull(session)) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1000);
}
String clientSessionId = getHeaderValueFromHeaders(input.getHeaders(), CLIENT_SESSION_ID_HEADER, configurationService.getHeadersCaseInsensitive());
if (Objects.isNull(clientSessionId)) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1018);
}
attachSessionIdToLogs(session);
attachLogFieldToLogs(CLIENT_SESSION_ID, clientSessionId);
LOG.info("Processing request");
AuthenticationRequest authenticationRequest;
ClientSession clientSession;
try {
clientSession = clientSessionService.getClientSessionFromRequestHeaders(input.getHeaders()).orElse(null);
if (Objects.isNull(clientSession)) {
LOG.info("ClientSession not found");
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1018);
}
authenticationRequest = AuthenticationRequest.parse(clientSession.getAuthRequestParams());
} catch (ParseException e) {
if (e.getRedirectionURI() == null) {
LOG.warn("Authentication request could not be parsed: redirect URI or Client ID is missing from auth request", e);
throw new RuntimeException("Redirect URI or Client ID is missing from auth request", e);
}
AuthenticationErrorResponse errorResponse = authorizationService.generateAuthenticationErrorResponse(e.getRedirectionURI(), e.getState(), e.getResponseMode(), e.getErrorObject());
LOG.warn("Authentication request could not be parsed", e);
return generateResponse(new AuthCodeResponse(errorResponse.toURI().toString()));
}
try {
if (!authorizationService.isClientRedirectUriValid(authenticationRequest.getClientID(), authenticationRequest.getRedirectionURI())) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1016);
}
VectorOfTrust requestedVectorOfTrust = clientSession.getEffectiveVectorOfTrust();
if (isNull(session.getCurrentCredentialStrength()) || requestedVectorOfTrust.getCredentialTrustLevel().compareTo(session.getCurrentCredentialStrength()) > 0) {
session.setCurrentCredentialStrength(requestedVectorOfTrust.getCredentialTrustLevel());
}
AuthorizationCode authCode = authorisationCodeService.generateAuthorisationCode(clientSessionId, session.getEmailAddress());
AuthenticationSuccessResponse authenticationResponse = authorizationService.generateSuccessfulAuthResponse(authenticationRequest, authCode);
LOG.info("Successfully processed request");
cloudwatchMetricsService.incrementCounter("SignIn", Map.of("Account", session.isNewAccount().name(), "Environment", configurationService.getEnvironment(), "Client", authenticationRequest.getClientID().getValue()));
sessionService.save(session.setAuthenticated(true).setNewAccount(EXISTING));
auditService.submitAuditEvent(OidcAuditableEvent.AUTH_CODE_ISSUED, context.getAwsRequestId(), session.getSessionId(), authenticationRequest.getClientID().getValue(), AuditService.UNKNOWN, session.getEmailAddress(), IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders()));
return generateResponse(new AuthCodeResponse(authenticationResponse.toURI().toString()));
} catch (ClientNotFoundException e) {
AuthenticationErrorResponse errorResponse = authorizationService.generateAuthenticationErrorResponse(authenticationRequest, OAuth2Error.INVALID_CLIENT);
return generateResponse(new AuthCodeResponse(errorResponse.toURI().toString()));
} catch (URISyntaxException e) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1016);
}
});
}
use of uk.gov.di.authentication.shared.exceptions.ClientNotFoundException in project di-authentication-api by alphagov.
the class AuthorizationServiceTest method shouldThrowClientNotFoundExceptionWhenClientDoesNotExist.
@Test
void shouldThrowClientNotFoundExceptionWhenClientDoesNotExist() {
when(dynamoClientService.getClient(CLIENT_ID.toString())).thenReturn(Optional.empty());
ClientNotFoundException exception = Assertions.assertThrows(ClientNotFoundException.class, () -> authorizationService.isClientRedirectUriValid(CLIENT_ID, REDIRECT_URI), "Expected to throw exception");
assertThat(exception.getMessage(), equalTo(format("No Client found for ClientID: %s", CLIENT_ID)));
}
use of uk.gov.di.authentication.shared.exceptions.ClientNotFoundException in project di-authentication-api by alphagov.
the class SendNotificationHandler method handleRequestWithUserContext.
@Override
public APIGatewayProxyResponseEvent handleRequestWithUserContext(APIGatewayProxyRequestEvent input, Context context, SendNotificationRequest request, UserContext userContext) {
attachSessionIdToLogs(userContext.getSession());
attachLogFieldToLogs(PERSISTENT_SESSION_ID, extractPersistentIdFromHeaders(input.getHeaders()));
attachLogFieldToLogs(LogFieldName.CLIENT_ID, userContext.getClient().map(ClientRegistry::getClientID).orElse("unknown"));
try {
if (!userContext.getSession().validateSession(request.getEmail())) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1000);
}
if (request.getNotificationType().equals(ACCOUNT_CREATED_CONFIRMATION)) {
LOG.info("Placing message on queue for AccountCreatedConfirmation");
NotifyRequest notifyRequest = new NotifyRequest(request.getEmail(), ACCOUNT_CREATED_CONFIRMATION);
if (notTestClientWithValidTestEmail(userContext, ACCOUNT_CREATED_CONFIRMATION)) {
sqsClient.send(objectMapper.writeValueAsString((notifyRequest)));
LOG.info("AccountCreatedConfirmation email placed on queue");
}
return generateEmptySuccessApiGatewayResponse();
}
Optional<ErrorResponse> codeRequestValid = isCodeRequestAttemptValid(request.getEmail(), userContext.getSession(), request.getNotificationType());
if (codeRequestValid.isPresent()) {
return generateApiGatewayProxyErrorResponse(400, codeRequestValid.get());
}
switch(request.getNotificationType()) {
case VERIFY_EMAIL:
return handleNotificationRequest(request.getEmail(), request.getNotificationType(), userContext.getSession(), userContext);
case VERIFY_PHONE_NUMBER:
if (request.getPhoneNumber() == null) {
return generateApiGatewayProxyResponse(400, ERROR_1011);
}
return handleNotificationRequest(PhoneNumberHelper.removeWhitespaceFromPhoneNumber(request.getPhoneNumber()), request.getNotificationType(), userContext.getSession(), userContext);
}
return generateApiGatewayProxyErrorResponse(400, ERROR_1002);
} catch (SdkClientException ex) {
LOG.error("Error sending message to queue");
return generateApiGatewayProxyResponse(500, "Error sending message to queue");
} catch (JsonException e) {
return generateApiGatewayProxyErrorResponse(400, ERROR_1001);
} catch (ClientNotFoundException e) {
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1015);
}
}
use of uk.gov.di.authentication.shared.exceptions.ClientNotFoundException in project di-authentication-api by alphagov.
the class VerifyCodeHandler method getOtpCodeForTestClient.
private Optional<String> getOtpCodeForTestClient(UserContext userContext, NotificationType notificationType) throws ClientNotFoundException {
LOG.warn("TestClients are ENABLED");
final String emailAddress = userContext.getSession().getEmailAddress();
final Optional<String> generatedOTPCode = codeStorageService.getOtpCode(emailAddress, notificationType);
return userContext.getClient().map(clientRegistry -> {
if (clientRegistry.isTestClient() && clientRegistry.getTestClientEmailAllowlist().contains(emailAddress)) {
LOG.info("Using TestClient with NotificationType {}", notificationType);
switch(notificationType) {
case VERIFY_EMAIL:
return configurationService.getTestClientVerifyEmailOTP();
case VERIFY_PHONE_NUMBER:
return configurationService.getTestClientVerifyPhoneNumberOTP();
case MFA_SMS:
return configurationService.getTestClientVerifyPhoneNumberOTP();
default:
LOG.info("Returning the generated OTP for NotificationType {}", notificationType);
return generatedOTPCode;
}
} else {
return generatedOTPCode;
}
}).orElseThrow(() -> new ClientNotFoundException(userContext.getSession()));
}
use of uk.gov.di.authentication.shared.exceptions.ClientNotFoundException in project di-authentication-api by alphagov.
the class MfaHandler method handleRequestWithUserContext.
@Override
public APIGatewayProxyResponseEvent handleRequestWithUserContext(APIGatewayProxyRequestEvent input, Context context, MfaRequest request, UserContext userContext) {
try {
String persistentSessionId = PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders());
attachSessionIdToLogs(userContext.getSession().getSessionId());
attachLogFieldToLogs(PERSISTENT_SESSION_ID, persistentSessionId);
attachLogFieldToLogs(CLIENT_ID, userContext.getClient().map(ClientRegistry::getClientID).orElse("unknown"));
LOG.info("MfaHandler received request");
String email = request.getEmail().toLowerCase(Locale.ROOT);
Optional<ErrorResponse> codeRequestValid = validateCodeRequestAttempts(email, userContext);
if (codeRequestValid.isPresent()) {
auditService.submitAuditEvent(FrontendAuditableEvent.MFA_INVALID_CODE_REQUEST, context.getAwsRequestId(), userContext.getSession().getSessionId(), userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN), AuditService.UNKNOWN, email, IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, persistentSessionId);
return generateApiGatewayProxyErrorResponse(400, codeRequestValid.get());
}
if (!userContext.getSession().validateSession(email)) {
LOG.warn("Email does not match Email in Request");
auditService.submitAuditEvent(FrontendAuditableEvent.MFA_MISMATCHED_EMAIL, context.getAwsRequestId(), userContext.getSession().getSessionId(), userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN), AuditService.UNKNOWN, email, IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, persistentSessionId);
return generateApiGatewayProxyErrorResponse(400, ERROR_1000);
}
String phoneNumber = authenticationService.getPhoneNumber(email).orElse(null);
if (phoneNumber == null) {
auditService.submitAuditEvent(FrontendAuditableEvent.MFA_MISSING_PHONE_NUMBER, context.getAwsRequestId(), userContext.getSession().getSessionId(), userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN), AuditService.UNKNOWN, email, IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, persistentSessionId);
return generateApiGatewayProxyErrorResponse(400, ERROR_1014);
}
String code = codeGeneratorService.sixDigitCode();
codeStorageService.saveOtpCode(email, code, configurationService.getCodeExpiry(), MFA_SMS);
sessionService.save(userContext.getSession().incrementCodeRequestCount());
NotifyRequest notifyRequest = new NotifyRequest(phoneNumber, MFA_SMS, code);
AuditableEvent auditableEvent;
if (!isTestClientAndAllowedEmail(userContext, MFA_SMS)) {
sqsClient.send(objectMapper.writeValueAsString(notifyRequest));
auditableEvent = FrontendAuditableEvent.MFA_CODE_SENT;
} else {
auditableEvent = FrontendAuditableEvent.MFA_CODE_SENT_FOR_TEST_CLIENT;
}
auditService.submitAuditEvent(auditableEvent, context.getAwsRequestId(), userContext.getSession().getSessionId(), userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN), AuditService.UNKNOWN, email, IpAddressHelper.extractIpAddress(input), phoneNumber, persistentSessionId);
LOG.info("Successfully processed request");
return generateEmptySuccessApiGatewayResponse();
} catch (JsonException e) {
return generateApiGatewayProxyErrorResponse(400, ERROR_1001);
} catch (ClientNotFoundException e) {
LOG.warn("Client not found");
return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1015);
}
}
Aggregations