Skip to content

Commit

Permalink
PYIC-6243: dcmaw async poll can return journey response (#2644)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeCollingwood authored Nov 15, 2024
2 parents 493ebd6 + c92ff03 commit 2c9bcdc
Show file tree
Hide file tree
Showing 20 changed files with 326 additions and 118 deletions.
7 changes: 7 additions & 0 deletions deploy/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,7 @@ Resources:
CRI_RESPONSE_TABLE_NAME: !Ref CRIResponseTable
CLIENT_OAUTH_SESSIONS_TABLE_NAME: !Ref ClientOAuthSessionsTable
USER_ISSUED_CREDENTIALS_TABLE_NAME: !Ref UserIssuedCredentialsV2Table
SESSION_CREDENTIALS_TABLE_NAME: !Ref SessionCredentialsTable
VpcConfig:
SubnetIds:
- Fn::ImportValue: !Sub ${VpcStackName}-ProtectedSubnetIdA
Expand All @@ -1258,8 +1259,14 @@ Resources:
TableName: !Ref CRIResponseTable
- DynamoDBReadPolicy:
TableName: !Ref UserIssuedCredentialsV2Table
- DynamoDBReadPolicy:
TableName: !Ref SessionCredentialsTable
- SSMParameterReadPolicy:
ParameterName: !Sub ${Environment}/core/*
- AWSSecretsManagerGetSecretValuePolicy:
SecretArn: !Sub arn:aws:secretsmanager:eu-west-2:*:secret:/${Environment}/core/self/ciConfig-*
- AWSSecretsManagerGetSecretValuePolicy:
SecretArn: !Sub arn:aws:secretsmanager:eu-west-2:*:secret:/${Environment}/core/cimitApi/apiKey-*
- Statement:
- Sid: EnforceStayinSpecificVpc
Effect: Allow
Expand Down
6 changes: 5 additions & 1 deletion lambdas/check-mobile-app-vc-receipt/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ plugins {
dependencies {

implementation libs.bundles.awsLambda,
project(":libs:audit-service"),
project(":libs:common-services"),
project(":libs:cri-response-service"),
project(":libs:verifiable-credentials")
project(":libs:verifiable-credentials"),
project(":libs:cimit-service"),
project(":libs:user-identity-service"),
project(":lambdas:process-cri-callback")

aspect libs.powertoolsLogging,
libs.powertoolsTracing,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,63 @@
import uk.gov.di.ipv.core.checkmobileappvcreceipt.dto.CheckMobileAppVcReceiptRequest;
import uk.gov.di.ipv.core.checkmobileappvcreceipt.exception.InvalidCheckMobileAppVcReceiptRequestException;
import uk.gov.di.ipv.core.library.annotations.ExcludeFromGeneratedCoverageReport;
import uk.gov.di.ipv.core.library.cimit.exception.CiRetrievalException;
import uk.gov.di.ipv.core.library.domain.Cri;
import uk.gov.di.ipv.core.library.domain.ErrorResponse;
import uk.gov.di.ipv.core.library.exceptions.ClientOauthSessionNotFoundException;
import uk.gov.di.ipv.core.library.domain.JourneyErrorResponse;
import uk.gov.di.ipv.core.library.domain.JourneyResponse;
import uk.gov.di.ipv.core.library.exceptions.ConfigException;
import uk.gov.di.ipv.core.library.exceptions.CredentialParseException;
import uk.gov.di.ipv.core.library.exceptions.HttpResponseExceptionWithErrorBody;
import uk.gov.di.ipv.core.library.exceptions.IpvSessionNotFoundException;
import uk.gov.di.ipv.core.library.exceptions.VerifiableCredentialException;
import uk.gov.di.ipv.core.library.helpers.ApiGatewayResponseGenerator;
import uk.gov.di.ipv.core.library.helpers.LogHelper;
import uk.gov.di.ipv.core.library.helpers.RequestHelper;
import uk.gov.di.ipv.core.library.service.AuditService;
import uk.gov.di.ipv.core.library.service.CimitService;
import uk.gov.di.ipv.core.library.service.CimitUtilityService;
import uk.gov.di.ipv.core.library.service.ClientOAuthSessionDetailsService;
import uk.gov.di.ipv.core.library.service.ConfigService;
import uk.gov.di.ipv.core.library.service.CriResponseService;
import uk.gov.di.ipv.core.library.service.IpvSessionService;
import uk.gov.di.ipv.core.library.service.UserIdentityService;
import uk.gov.di.ipv.core.library.service.exception.InvalidCriResponseException;
import uk.gov.di.ipv.core.library.verifiablecredential.service.SessionCredentialsService;
import uk.gov.di.ipv.core.library.verifiablecredential.service.VerifiableCredentialService;
import uk.gov.di.ipv.core.processcricallback.service.CriCheckingService;

import static uk.gov.di.ipv.core.library.helpers.LogHelper.buildErrorMessage;
import java.util.List;

import static uk.gov.di.ipv.core.library.journeys.JourneyUris.JOURNEY_ABANDON_PATH;
import static uk.gov.di.ipv.core.library.journeys.JourneyUris.JOURNEY_ERROR_PATH;

public class CheckMobileAppVcReceiptHandler
implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
private static final Logger LOGGER = LogManager.getLogger();
private static final JourneyResponse JOURNEY_ABANDON =
new JourneyResponse(JOURNEY_ABANDON_PATH);
private static final JourneyResponse JOURNEY_ERROR = new JourneyResponse(JOURNEY_ERROR_PATH);
private final ConfigService configService;
private final IpvSessionService ipvSessionService;
private final ClientOAuthSessionDetailsService clientOAuthSessionDetailsService;
private final CriResponseService criResponseService;
private final VerifiableCredentialService verifiableCredentialService;
private final CriCheckingService criCheckingService;

public CheckMobileAppVcReceiptHandler(
ConfigService configService,
IpvSessionService ipvSessionService,
ClientOAuthSessionDetailsService clientOAuthSessionDetailsService,
CriResponseService criResponseService,
VerifiableCredentialService verifiableCredentialService) {
VerifiableCredentialService verifiableCredentialService,
CriCheckingService criCheckingService) {
this.configService = configService;
this.ipvSessionService = ipvSessionService;
this.clientOAuthSessionDetailsService = clientOAuthSessionDetailsService;
this.criResponseService = criResponseService;
this.verifiableCredentialService = verifiableCredentialService;
this.criCheckingService = criCheckingService;
}

@ExcludeFromGeneratedCoverageReport
Expand All @@ -59,6 +79,18 @@ public CheckMobileAppVcReceiptHandler() {
clientOAuthSessionDetailsService = new ClientOAuthSessionDetailsService(configService);
criResponseService = new CriResponseService(configService);
verifiableCredentialService = new VerifiableCredentialService(configService);

var sessionCredentialsService = new SessionCredentialsService(configService);
var cimitService = new CimitService(configService);

criCheckingService =
new CriCheckingService(
configService,
AuditService.create(configService),
new UserIdentityService(configService),
cimitService,
new CimitUtilityService(configService),
sessionCredentialsService);
}

@Override
Expand All @@ -69,22 +101,33 @@ public APIGatewayProxyResponseEvent handleRequest(
try {
var request = parseRequest(input);

var status = getStatus(request);
var journeyResponse = getJourneyResponse(request);

if (journeyResponse != null) {
return ApiGatewayResponseGenerator.proxyJsonResponse(
HttpStatus.SC_OK, journeyResponse);
}

return ApiGatewayResponseGenerator.proxyResponse(status);
} catch (InvalidCheckMobileAppVcReceiptRequestException
| ClientOauthSessionNotFoundException e) {
LOGGER.info(buildErrorMessage(e.getErrorResponse()));
return ApiGatewayResponseGenerator.proxyResponse(HttpStatus.SC_BAD_REQUEST);
// Frontend will continue polling
return ApiGatewayResponseGenerator.proxyResponse(HttpStatus.SC_NOT_FOUND);
} catch (HttpResponseExceptionWithErrorBody | VerifiableCredentialException e) {
return buildErrorResponse(e, HttpStatus.SC_BAD_REQUEST, e.getErrorResponse());
} catch (IpvSessionNotFoundException e) {
LOGGER.info(buildErrorMessage(ErrorResponse.IPV_SESSION_NOT_FOUND));
return ApiGatewayResponseGenerator.proxyResponse(HttpStatus.SC_BAD_REQUEST);
return buildErrorResponse(
e, HttpStatus.SC_BAD_REQUEST, ErrorResponse.IPV_SESSION_NOT_FOUND);
} catch (InvalidCriResponseException e) {
LOGGER.info(buildErrorMessage(e.getErrorResponse()));
return ApiGatewayResponseGenerator.proxyResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR);
return buildErrorResponse(e, HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getErrorResponse());
} catch (CredentialParseException e) {
LOGGER.info(buildErrorMessage(ErrorResponse.FAILED_TO_PARSE_ISSUED_CREDENTIALS));
return ApiGatewayResponseGenerator.proxyResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR);
return buildErrorResponse(
e,
HttpStatus.SC_INTERNAL_SERVER_ERROR,
ErrorResponse.FAILED_TO_PARSE_ISSUED_CREDENTIALS);
} catch (ConfigException e) {
return buildErrorResponse(
e, HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorResponse.FAILED_TO_PARSE_CONFIG);
} catch (CiRetrievalException e) {
return buildErrorResponse(
e, HttpStatus.SC_INTERNAL_SERVER_ERROR, ErrorResponse.FAILED_TO_GET_STORED_CIS);
} catch (Exception e) {
LOGGER.error(LogHelper.buildErrorMessage("Unhandled lambda exception", e));
throw e;
Expand All @@ -99,11 +142,11 @@ private CheckMobileAppVcReceiptRequest parseRequest(APIGatewayProxyRequestEvent
RequestHelper.getFeatureSet(input.getHeaders()));
}

private int getStatus(CheckMobileAppVcReceiptRequest request)
throws InvalidCheckMobileAppVcReceiptRequestException, IpvSessionNotFoundException,
ClientOauthSessionNotFoundException, InvalidCriResponseException,
CredentialParseException {
// Validate sessions
private JourneyResponse getJourneyResponse(CheckMobileAppVcReceiptRequest request)
throws IpvSessionNotFoundException, HttpResponseExceptionWithErrorBody,
InvalidCriResponseException, CredentialParseException,
VerifiableCredentialException, ConfigException, CiRetrievalException {
// Validate callback sessions
validateSessionId(request);

// Get/ set session items/ config
Expand All @@ -121,19 +164,27 @@ private int getStatus(CheckMobileAppVcReceiptRequest request)
LogHelper.attachFeatureSetToLogs(request.getFeatureSet());
LogHelper.attachComponentId(configService);

// Retrieve and check cri response
// Retrieve and validate cri response and vc
var criResponse = criResponseService.getCriResponseItem(userId, Cri.DCMAW_ASYNC);

if (criResponse == null) {
return HttpStatus.SC_INTERNAL_SERVER_ERROR;
throw new InvalidCriResponseException(ErrorResponse.CRI_RESPONSE_ITEM_NOT_FOUND);
}

var vc = verifiableCredentialService.getVc(userId, Cri.DCMAW_ASYNC.getId());
if (CriResponseService.STATUS_PENDING.equals(criResponse.getStatus()) && vc == null) {
return null;
}

if (CriResponseService.STATUS_ERROR.equals(criResponse.getStatus())) {
return JOURNEY_ERROR;
}

if (!CriResponseService.STATUS_PENDING.equals(criResponse.getStatus())
|| verifiableCredentialService.getVc(userId, Cri.DCMAW_ASYNC.getId()) != null) {
return HttpStatus.SC_OK;
if (CriResponseService.STATUS_ABANDON.equals(criResponse.getStatus())) {
return JOURNEY_ABANDON;
}

return HttpStatus.SC_NOT_FOUND;
return criCheckingService.checkVcResponse(
List.of(vc), request.getIpAddress(), clientOAuthSessionItem, ipvSessionItem);
}

private void validateSessionId(CheckMobileAppVcReceiptRequest request)
Expand All @@ -145,4 +196,13 @@ private void validateSessionId(CheckMobileAppVcReceiptRequest request)
ErrorResponse.MISSING_IPV_SESSION_ID);
}
}

private APIGatewayProxyResponseEvent buildErrorResponse(
Exception e, int status, ErrorResponse errorResponse) {
LOGGER.error(LogHelper.buildErrorMessage(errorResponse.getMessage(), e));
return ApiGatewayResponseGenerator.proxyJsonResponse(
status,
new JourneyErrorResponse(
JOURNEY_ERROR_PATH, status, errorResponse, e.getMessage()));
}
}
Loading

0 comments on commit 2c9bcdc

Please sign in to comment.