Search in sources :

Example 1 with AuditableEvent

use of uk.gov.di.authentication.shared.domain.AuditableEvent in project di-authentication-api by alphagov.

the class UpdateProfileHandler method handleRequestWithUserContext.

@Override
public APIGatewayProxyResponseEvent handleRequestWithUserContext(APIGatewayProxyRequestEvent input, Context context, UpdateProfileRequest request, UserContext userContext) {
    Session session = userContext.getSession();
    String persistentSessionId = PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders());
    LogLineHelper.attachSessionIdToLogs(session);
    attachLogFieldToLogs(PERSISTENT_SESSION_ID, persistentSessionId);
    LOG.info("Processing request");
    String ipAddress = IpAddressHelper.extractIpAddress(input);
    if (!session.validateSession(request.getEmail())) {
        LOG.info("Invalid session");
        return generateErrorResponse(ErrorResponse.ERROR_1000, context);
    }
    AuditableEvent auditableEvent;
    String auditablePhoneNumber = userContext.getUserProfile().map(UserProfile::getPhoneNumber).orElse(AuditService.UNKNOWN);
    String auditableClientId = userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN);
    switch(request.getUpdateProfileType()) {
        case ADD_PHONE_NUMBER:
            {
                String phoneNumber = PhoneNumberHelper.removeWhitespaceFromPhoneNumber(request.getProfileInformation());
                Optional<ErrorResponse> errorResponse = ValidationHelper.validatePhoneNumber(phoneNumber);
                if (errorResponse.isPresent()) {
                    return generateErrorResponse(errorResponse.get(), context);
                }
                authenticationService.updatePhoneNumber(request.getEmail(), request.getProfileInformation());
                auditableEvent = UPDATE_PROFILE_PHONE_NUMBER;
                auditablePhoneNumber = request.getProfileInformation();
                LOG.info("Phone number updated");
                break;
            }
        case CAPTURE_CONSENT:
            {
                ClientSession clientSession = userContext.getClientSession();
                if (clientSession == null) {
                    return generateErrorResponse(ErrorResponse.ERROR_1000, context);
                }
                AuthenticationRequest authorizationRequest;
                try {
                    authorizationRequest = AuthenticationRequest.parse(clientSession.getAuthRequestParams());
                } catch (ParseException e) {
                    LOG.info("Cannot retrieve auth request params from client session id");
                    return generateErrorResponse(ErrorResponse.ERROR_1001, context);
                }
                String clientId = authorizationRequest.getClientID().getValue();
                attachLogFieldToLogs(CLIENT_ID, clientId);
                Set<String> claimsConsented;
                if (!Boolean.parseBoolean(request.getProfileInformation())) {
                    claimsConsented = OIDCScopeValue.OPENID.getClaimNames();
                } else {
                    claimsConsented = ValidScopes.getClaimsForListOfScopes(authorizationRequest.getScope().toStringList());
                }
                processAndUpdateClientConsent(request.getEmail(), userContext, clientId, claimsConsented);
                auditableEvent = UPDATE_PROFILE_CONSENT_UPDATED;
                auditableClientId = clientId;
                LOG.info("Consent updated");
                break;
            }
        case UPDATE_TERMS_CONDS:
            {
                authenticationService.updateTermsAndConditions(request.getEmail(), configurationService.getTermsAndConditionsVersion());
                auditableEvent = UPDATE_PROFILE_TERMS_CONDS_ACCEPTANCE;
                LOG.info("Updated terms and conditions for Version: {}", configurationService.getTermsAndConditionsVersion());
                break;
            }
        default:
            LOG.error("Encountered unexpected error while processing session: {}", session.getSessionId());
            return generateErrorResponse(ErrorResponse.ERROR_1013, context);
    }
    auditService.submitAuditEvent(auditableEvent, context.getAwsRequestId(), session.getSessionId(), auditableClientId, userContext.getUserProfile().map(UserProfile::getSubjectID).orElse(AuditService.UNKNOWN), userContext.getSession().getEmailAddress(), ipAddress, auditablePhoneNumber, persistentSessionId);
    return generateEmptySuccessApiGatewayResponse();
}
Also used : Set(java.util.Set) Optional(java.util.Optional) UserProfile(uk.gov.di.authentication.shared.entity.UserProfile) ClientSession(uk.gov.di.authentication.shared.entity.ClientSession) ParseException(com.nimbusds.oauth2.sdk.ParseException) AuthenticationRequest(com.nimbusds.openid.connect.sdk.AuthenticationRequest) Session(uk.gov.di.authentication.shared.entity.Session) ClientSession(uk.gov.di.authentication.shared.entity.ClientSession) AuditableEvent(uk.gov.di.authentication.shared.domain.AuditableEvent)

Example 2 with AuditableEvent

use of uk.gov.di.authentication.shared.domain.AuditableEvent in project di-authentication-api by alphagov.

the class VerifyCodeHandler method processBlockedCodeSession.

private void processBlockedCodeSession(ErrorResponse errorResponse, Session session, NotificationType notificationType, APIGatewayProxyRequestEvent input, Context context, UserContext userContext) {
    AuditableEvent auditableEvent;
    if (List.of(ErrorResponse.ERROR_1027, ErrorResponse.ERROR_1033, ErrorResponse.ERROR_1034).contains(errorResponse)) {
        blockCodeForSessionAndResetCount(session);
        auditableEvent = FrontendAuditableEvent.CODE_MAX_RETRIES_REACHED;
    } else {
        auditableEvent = FrontendAuditableEvent.INVALID_CODE_SENT;
    }
    auditService.submitAuditEvent(auditableEvent, context.getAwsRequestId(), session.getSessionId(), userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN), userContext.getUserProfile().map(UserProfile::getSubjectID).orElse(AuditService.UNKNOWN), session.getEmailAddress(), IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, extractPersistentIdFromHeaders(input.getHeaders()), pair("notification-type", notificationType.name()));
}
Also used : UserProfile(uk.gov.di.authentication.shared.entity.UserProfile) ClientRegistry(uk.gov.di.authentication.shared.entity.ClientRegistry) FrontendAuditableEvent(uk.gov.di.authentication.frontendapi.domain.FrontendAuditableEvent) AuditableEvent(uk.gov.di.authentication.shared.domain.AuditableEvent)

Example 3 with AuditableEvent

use of uk.gov.di.authentication.shared.domain.AuditableEvent in project di-authentication-api by alphagov.

the class CheckUserExistsHandler method handleRequestWithUserContext.

@Override
public APIGatewayProxyResponseEvent handleRequestWithUserContext(APIGatewayProxyRequestEvent input, Context context, CheckUserExistsRequest request, UserContext userContext) {
    attachSessionIdToLogs(userContext.getSession());
    attachLogFieldToLogs(PERSISTENT_SESSION_ID, extractPersistentIdFromHeaders(input.getHeaders()));
    attachLogFieldToLogs(CLIENT_ID, userContext.getClient().map(ClientRegistry::getClientID).orElse("unknown"));
    try {
        LOG.info("Processing request");
        String emailAddress = request.getEmail().toLowerCase();
        Optional<ErrorResponse> errorResponse = ValidationHelper.validateEmailAddress(emailAddress);
        String persistentSessionId = PersistentIdHelper.extractPersistentIdFromHeaders(input.getHeaders());
        if (errorResponse.isPresent()) {
            auditService.submitAuditEvent(FrontendAuditableEvent.CHECK_USER_INVALID_EMAIL, context.getAwsRequestId(), userContext.getSession().getSessionId(), userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN), AuditService.UNKNOWN, emailAddress, IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, persistentSessionId);
            return generateApiGatewayProxyErrorResponse(400, errorResponse.get());
        }
        boolean userExists = authenticationService.userExists(emailAddress);
        userContext.getSession().setEmailAddress(emailAddress);
        AuditableEvent auditableEvent;
        if (userExists) {
            auditableEvent = FrontendAuditableEvent.CHECK_USER_KNOWN_EMAIL;
        } else {
            auditableEvent = FrontendAuditableEvent.CHECK_USER_NO_ACCOUNT_WITH_EMAIL;
        }
        auditService.submitAuditEvent(auditableEvent, context.getAwsRequestId(), userContext.getSession().getSessionId(), userContext.getClient().map(ClientRegistry::getClientID).orElse(AuditService.UNKNOWN), AuditService.UNKNOWN, emailAddress, IpAddressHelper.extractIpAddress(input), AuditService.UNKNOWN, persistentSessionId);
        CheckUserExistsResponse checkUserExistsResponse = new CheckUserExistsResponse(emailAddress, userExists);
        sessionService.save(userContext.getSession());
        LOG.info("Successfully processed request");
        return generateApiGatewayProxyResponse(200, checkUserExistsResponse);
    } catch (JsonException e) {
        return generateApiGatewayProxyErrorResponse(400, ErrorResponse.ERROR_1001);
    }
}
Also used : JsonException(uk.gov.di.authentication.shared.serialization.Json.JsonException) CheckUserExistsResponse(uk.gov.di.authentication.frontendapi.entity.CheckUserExistsResponse) ClientRegistry(uk.gov.di.authentication.shared.entity.ClientRegistry) ErrorResponse(uk.gov.di.authentication.shared.entity.ErrorResponse) ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse(uk.gov.di.authentication.shared.helpers.ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse) FrontendAuditableEvent(uk.gov.di.authentication.frontendapi.domain.FrontendAuditableEvent) AuditableEvent(uk.gov.di.authentication.shared.domain.AuditableEvent)

Example 4 with AuditableEvent

use of uk.gov.di.authentication.shared.domain.AuditableEvent 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);
    }
}
Also used : JsonException(uk.gov.di.authentication.shared.serialization.Json.JsonException) ClientNotFoundException(uk.gov.di.authentication.shared.exceptions.ClientNotFoundException) ClientRegistry(uk.gov.di.authentication.shared.entity.ClientRegistry) NotifyRequest(uk.gov.di.authentication.shared.entity.NotifyRequest) ErrorResponse(uk.gov.di.authentication.shared.entity.ErrorResponse) ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse(uk.gov.di.authentication.shared.helpers.ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse) FrontendAuditableEvent(uk.gov.di.authentication.frontendapi.domain.FrontendAuditableEvent) AuditableEvent(uk.gov.di.authentication.shared.domain.AuditableEvent)

Aggregations

AuditableEvent (uk.gov.di.authentication.shared.domain.AuditableEvent)4 FrontendAuditableEvent (uk.gov.di.authentication.frontendapi.domain.FrontendAuditableEvent)3 ClientRegistry (uk.gov.di.authentication.shared.entity.ClientRegistry)3 ErrorResponse (uk.gov.di.authentication.shared.entity.ErrorResponse)2 UserProfile (uk.gov.di.authentication.shared.entity.UserProfile)2 ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse (uk.gov.di.authentication.shared.helpers.ApiGatewayResponseHelper.generateApiGatewayProxyErrorResponse)2 JsonException (uk.gov.di.authentication.shared.serialization.Json.JsonException)2 ParseException (com.nimbusds.oauth2.sdk.ParseException)1 AuthenticationRequest (com.nimbusds.openid.connect.sdk.AuthenticationRequest)1 Optional (java.util.Optional)1 Set (java.util.Set)1 CheckUserExistsResponse (uk.gov.di.authentication.frontendapi.entity.CheckUserExistsResponse)1 ClientSession (uk.gov.di.authentication.shared.entity.ClientSession)1 NotifyRequest (uk.gov.di.authentication.shared.entity.NotifyRequest)1 Session (uk.gov.di.authentication.shared.entity.Session)1 ClientNotFoundException (uk.gov.di.authentication.shared.exceptions.ClientNotFoundException)1