diff --git a/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/api/payment/v3_1_8/vrp/DomesticVrpsApiController.java b/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/api/payment/v3_1_8/vrp/DomesticVrpsApiController.java index c7592ff40..da1482c60 100644 --- a/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/api/payment/v3_1_8/vrp/DomesticVrpsApiController.java +++ b/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/api/payment/v3_1_8/vrp/DomesticVrpsApiController.java @@ -123,6 +123,7 @@ public ResponseEntity domesticVrpPost( f.validateRisk(obDomesticVRPRequest.getRisk()); f.checkRequestAndConsentInitiationMatch(initiation, consent); f.checkRequestAndConsentRiskMatch(obDomesticVRPRequest, consent); + f.checkCreditorAccountIsInInstructionIfNotInConsent(new OBDomesticVRPRequest(), consent); }); ResponseEntity responseEntity = vrpPaymentsEndpointWrapper.execute((String tppId) -> { HttpHeaders additionalHeaders = new HttpHeaders(); diff --git a/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapper.java b/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapper.java index 8d79ef395..b26e85cf4 100644 --- a/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapper.java +++ b/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/main/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapper.java @@ -32,6 +32,8 @@ import com.forgerock.openbanking.model.error.OBRIErrorType; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; +import uk.org.openbanking.datamodel.error.OBError1; +import uk.org.openbanking.datamodel.error.OBStandardErrorCodes1; import uk.org.openbanking.datamodel.payment.OBRisk1; import uk.org.openbanking.datamodel.vrp.OBDomesticVRPInitiation; import uk.org.openbanking.datamodel.vrp.OBDomesticVRPRequest; @@ -113,6 +115,15 @@ public void checkRequestAndConsentRiskMatch(OBDomesticVRPRequest request, FRDome } } + public void checkCreditorAccountIsInInstructionIfNotInConsent(OBDomesticVRPRequest vrpRequest, + FRDomesticVRPConsent frConsent) throws OBErrorException { + if(frConsent.getVrpDetails().getData().getInitiation().getCreditorAccount() == null){ + if(vrpRequest.getData().getInitiation().getCreditorAccount() == null){ + throw new OBErrorException(OBRIErrorType.REQUEST_VRP_CREDITOR_ACCOUNT_NOT_SPECIFIED); + } + } + } + public interface DomesticVrpPaymentRestEndpointContent { ResponseEntity run(String tppId) throws OBErrorException; } diff --git a/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/test/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapperTest.java b/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/test/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapperTest.java index a17b9ca44..8d0d881cd 100644 --- a/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/test/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapperTest.java +++ b/forgerock-openbanking-uk-aspsp-rs/forgerock-openbanking-uk-aspsp-rs-gateway/forgerock-openbanking-uk-aspsp-rs-gateway-server/src/test/java/com/forgerock/openbanking/aspsp/rs/wrappper/endpoints/DomesticVrpPaymentsEndpointWrapperTest.java @@ -33,6 +33,7 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import uk.org.openbanking.datamodel.error.OBStandardErrorCodes1; import uk.org.openbanking.datamodel.vrp.OBDomesticVRPInitiation; import uk.org.openbanking.datamodel.vrp.OBDomesticVRPRequest; import uk.org.openbanking.testsupport.vrp.OBDomesticVRPCommonTestDataFactory; @@ -130,5 +131,63 @@ public void fail_checkRequestAndConsentInitiationMatch() throws OBErrorException // Then assertThat(exception.getObriErrorType()).isEqualTo(OBRIErrorType.REQUEST_VRP_INITIATION_DOESNT_MATCH_CONSENT); + assertThat(exception.getOBError().getErrorCode()).isEqualTo(OBStandardErrorCodes1.UK_OBIE_RESOURCE_CONSENT_MISMATCH.toString()); } + + /** + * If the CreditorAccount was not specified in the consent, the CreditorAccount must be specified in the + * instruction. + */ + @Test + public void success_checkCreditorAccountIsInInstructionIfNotInConsent() throws OBErrorException { + // Given + DomesticVrpPaymentsEndpointWrapper domesticVrpPaymentsEndpointWrapper = + new DomesticVrpPaymentsEndpointWrapper(endpointWrapperService, tppStoreService, + riskValidator); + // Create the request data + OBDomesticVRPRequest vrpRequest = OBDomesticVRPRequestTestDataFactory.aValidOBDomesticVRPRequest(); + + // Create an FR Consent with slightly differing initiation data + FRDomesticVRPConsent frConsent = FRVrpTestDataFactory.aValidFRDomesticVRPConsent(); + frConsent.getVrpDetails().getData().getInitiation().setCreditorAccount(null); + + + // When + domesticVrpPaymentsEndpointWrapper.checkCreditorAccountIsInInstructionIfNotInConsent(vrpRequest, frConsent); + + // Then + + } + + /** + * If the CreditorAccount was not specified in the consent, the CreditorAccount must be specified in the + * instruction. + */ + @Test + public void fail_checkCreditorAccountIsInInstructionIfNotInConsent() throws OBErrorException { + // Given + DomesticVrpPaymentsEndpointWrapper domesticVrpPaymentsEndpointWrapper = + new DomesticVrpPaymentsEndpointWrapper(endpointWrapperService, tppStoreService, + riskValidator); + // Create the request data + OBDomesticVRPRequest vrpRequest = OBDomesticVRPRequestTestDataFactory.aValidOBDomesticVRPRequest(); + vrpRequest.getData().getInitiation().setCreditorAccount(null); + + // Create an FR Consent with slightly differing initiation data + FRDomesticVRPConsent frConsent = FRVrpTestDataFactory.aValidFRDomesticVRPConsent(); + frConsent.getVrpDetails().getData().getInitiation().setCreditorAccount(null); + + + // When + OBErrorException exception = + catchThrowableOfType(() -> + domesticVrpPaymentsEndpointWrapper.checkCreditorAccountIsInInstructionIfNotInConsent(vrpRequest, frConsent), + OBErrorException.class); + + // Then + assertThat(exception.getObriErrorType()).isEqualTo(OBRIErrorType.REQUEST_VRP_CREDITOR_ACCOUNT_NOT_SPECIFIED); + assertThat(exception.getOBError().getErrorCode()).isEqualTo(OBStandardErrorCodes1.UK_OBIE_RESOURCE_CONSENT_MISMATCH.toString()); + + } + } \ No newline at end of file