Skip to content

Commit

Permalink
Merge pull request #2411 from hongwei1/develop
Browse files Browse the repository at this point in the history
feature/added two new  connector methods and createVRPConsentRequest
  • Loading branch information
simonredfern authored Jul 12, 2024
2 parents 6181b2c + ec2c10e commit 83ed226
Show file tree
Hide file tree
Showing 23 changed files with 759 additions and 173 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,7 @@ object SwaggerDefinitionsJSON {
from_person = "String"
)

val branchRoutingJSON = BranchRoutingJsonV141(
val branchRoutingJsonV141 = BranchRoutingJsonV141(
scheme = "BranchNumber",
address = "678"
)
Expand All @@ -1542,7 +1542,7 @@ object SwaggerDefinitionsJSON {
lobby = lobbyJson,
drive_up = driveUpJson,
meta = metaJson,
branch_routing = branchRoutingJSON
branch_routing = branchRoutingJsonV141
)


Expand Down Expand Up @@ -3229,7 +3229,7 @@ object SwaggerDefinitionsJSON {
meta = metaJson,
lobby = lobbyJson,
drive_up = driveUpJson,
branch_routing = branchRoutingJSON
branch_routing = branchRoutingJsonV141
)


Expand Down Expand Up @@ -3820,7 +3820,7 @@ object SwaggerDefinitionsJSON {
account_id =accountIdExample.value ,
account_type ="330",
account_routings = List(accountRoutingJsonV121),
branch_routings = List(branchRoutingJSON)
branch_routings = List(branchRoutingJsonV141)
)

val checkbookOrdersJson = CheckbookOrdersJson(
Expand Down Expand Up @@ -5205,6 +5205,12 @@ object SwaggerDefinitionsJSON {
consumer_id = consumerIdExample.value
)

val vrpConsentRequestResponseJson = ConsentRequestResponseJson(
consent_request_id = consentRequestIdExample.value,
payload = json.parse(vrpConsentRequestPayloadExample.value),
consumer_id = consumerIdExample.value
)

val consentJsonV500 = ConsentJsonV500(
consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945",
jwt = "eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOltdLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIyMWUxYzhjYy1mOTE4LTRlYWMtYjhlMy01ZTVlZWM2YjNiNGIiLCJhdWQiOiJlanpuazUwNWQxMzJyeW9tbmhieDFxbXRvaHVyYnNiYjBraWphanNrIiwibmJmIjoxNTUzNTU0ODk5LCJpc3MiOiJodHRwczpcL1wvd3d3Lm9wZW5iYW5rcHJvamVjdC5jb20iLCJleHAiOjE1NTM1NTg0OTksImlhdCI6MTU1MzU1NDg5OSwianRpIjoiMDlmODhkNWYtZWNlNi00Mzk4LThlOTktNjYxMWZhMWNkYmQ1Iiwidmlld3MiOlt7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAxIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifSx7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAyIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifV19.8cc7cBEf2NyQvJoukBCmDLT7LXYcuzTcSYLqSpbxLp4",
Expand All @@ -5226,6 +5232,28 @@ object SwaggerDefinitionsJSON {
valid_from = Some(new Date()),
time_to_live = Some(3600)
)

val consentRequestFromAccountJson = ConsentRequestFromAccountJson (
bank_routing = bankRoutingJsonV121,
account_routing = accountRoutingJsonV121,
branch_routing = branchRoutingJsonV141
)

val consentRequestToAccountJson = ConsentRequestToAccountJson (
bank_routing = bankRoutingJsonV121,
account_routing = accountRoutingJsonV121,
branch_routing = branchRoutingJsonV141,
limit = postCounterpartyLimitV510
)

val postConsentRequestJsonV510 = PostConsentRequestJsonV510(
from_account = consentRequestFromAccountJson,
to_account = consentRequestToAccountJson,
email = Some(emailExample.value),
phone_number = Some(mobileNumberExample.value),
valid_from = Some(new Date()),
time_to_live = Some(3600)
)

val createPhysicalCardJsonV500 = CreatePhysicalCardJsonV500(
card_number = bankCardNumberExample.value,
Expand Down Expand Up @@ -5428,6 +5456,7 @@ object SwaggerDefinitionsJSON {
)

val postCounterpartyLimitV510 = PostCounterpartyLimitV510(
currency = currencyExample.value,
max_single_amount = maxSingleAmountExample.value.toInt,
max_monthly_amount = maxMonthlyAmountExample.value.toInt,
max_number_of_monthly_transactions = maxNumberOfMonthlyTransactionsExample.value.toInt,
Expand All @@ -5441,6 +5470,7 @@ object SwaggerDefinitionsJSON {
account_id = accountIdExample.value,
view_id = viewIdExample.value,
counterparty_id = counterpartyIdExample.value,
currency = currencyExample.value,
max_single_amount = maxSingleAmountExample.value.toInt,
max_monthly_amount = maxMonthlyAmountExample.value.toInt,
max_number_of_monthly_transactions = maxNumberOfMonthlyTransactionsExample.value.toInt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import code.views.Views
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.ExecutionContext.Implicits.global
import com.openbankproject.commons.model._
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthentication, StrongCustomerAuthenticationStatus}
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthentication, StrongCustomerAuthenticationStatus, SuppliedAnswerType}
import com.openbankproject.commons.util.ApiVersion
import net.liftweb.common.{Empty, Full}
import net.liftweb.http.js.JE.JsRaw
Expand Down Expand Up @@ -1259,12 +1259,13 @@ Maybe in a later version the access path will change.
_ <- NewStyle.function.tryons(s"$AuthorisationNotFound Current AUTHORISATION_ID($authorisationId)", 400, callContext) {
challenges.filter(_.challengeId == authorisationId).size == 1
}
(challenge, callContext) <- NewStyle.function.validateChallengeAnswerC2(
(challenge, callContext) <- NewStyle.function.validateChallengeAnswerC4(
ChallengeType.BERLIN_GROUP_CONSENT_CHALLENGE,
None,
Some(consentId),
challenges.filter(_.challengeId == authorisationId).head.challengeId,
updateJson.scaAuthenticationData,
SuppliedAnswerType.PLAIN_TEXT_VALUE,
callContext
)
consent <- challenge.scaStatus match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package code.api.builder.PaymentInitiationServicePISApi

import code.api.Constant
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.sepaCreditTransfersBerlinGroupV13
import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{CancelPaymentResponseJson,
CancelPaymentResponseLinks, LinkHrefJson, UpdatePaymentPsuDataJson, checkUpdatePsuAuthentication,checkAuthorisationConfirmation,
checkTransactionAuthorisation, checkSelectPsuAuthenticationMethod, createCancellationTransactionRequestJson}
import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{CancelPaymentResponseJson, CancelPaymentResponseLinks, LinkHrefJson, UpdatePaymentPsuDataJson, checkAuthorisationConfirmation, checkSelectPsuAuthenticationMethod, checkTransactionAuthorisation, checkUpdatePsuAuthentication, createCancellationTransactionRequestJson}
import code.api.berlin.group.v1_3.{JSONFactory_BERLIN_GROUP_1_3, JvalueCaseClass, OBP_BERLIN_GROUP_1_3}
import code.api.util.APIUtil._
import code.api.util.ApiTag._
Expand All @@ -24,7 +22,7 @@ import com.openbankproject.commons.ExecutionContext.Implicits.global
import com.openbankproject.commons.model._
import com.openbankproject.commons.model.enums.ChallengeType.BERLIN_GROUP_PAYMENT_CHALLENGE
import com.openbankproject.commons.model.enums.TransactionRequestStatus._
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthenticationStatus, TransactionRequestStatus}
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthenticationStatus, SuppliedAnswerType, TransactionRequestStatus}
import com.openbankproject.commons.util.ApiVersion
import net.liftweb
import net.liftweb.common.Box.tryo
Expand Down Expand Up @@ -1227,12 +1225,13 @@ There are the following request types on this access path:
existingTransactionRequest.status == TransactionRequestStatus.COMPLETED.toString
}
(_, callContext) <- NewStyle.function.getTransactionRequestImpl(TransactionRequestId(paymentId), callContext)
(challenge, callContext) <- NewStyle.function.validateChallengeAnswerC2(
(challenge, callContext) <- NewStyle.function.validateChallengeAnswerC4(
ChallengeType.BERLIN_GROUP_PAYMENT_CHALLENGE,
Some(paymentId),
None,
authorisationId,
transactionAuthorisation.scaAuthenticationData,
SuppliedAnswerType.PLAIN_TEXT_VALUE,
callContext
)

Expand Down Expand Up @@ -1470,12 +1469,13 @@ There are the following request types on this access path:
_ <- Helper.booleanToFuture(failMsg= CannotUpdatePSUData, cc=callContext) {
existingTransactionRequest.status == TransactionRequestStatus.INITIATED.toString
}
(challenge, callContext) <- NewStyle.function.validateChallengeAnswerC2(
(challenge, callContext) <- NewStyle.function.validateChallengeAnswerC4(
ChallengeType.BERLIN_GROUP_PAYMENT_CHALLENGE,
Some(paymentId),
None,
authorisationid,
transactionAuthorisationJson.scaAuthenticationData,
SuppliedAnswerType.PLAIN_TEXT_VALUE,
callContext
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import code.util.Helper.booleanToFuture
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.ExecutionContext.Implicits.global
import com.openbankproject.commons.model.enums.TransactionRequestStatus.{COMPLETED, REJECTED}
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthenticationStatus}
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthenticationStatus,SuppliedAnswerType}
import com.openbankproject.commons.model.{ChallengeTrait, TransactionRequestId}
import com.openbankproject.commons.util.ApiVersion
import net.liftweb.common.{Box, Empty, Full}
Expand Down Expand Up @@ -476,13 +476,14 @@ There are the following request types on this access path:
}
_ <- SigningBasketNewStyle.checkSigningBasketPayments(basketId, callContext)
// Validate a challenge answer and get an error if any
(boxedChallenge: Box[ChallengeTrait], callContext) <- NewStyle.function.validateChallengeAnswerC3(
(boxedChallenge: Box[ChallengeTrait], callContext) <- NewStyle.function.validateChallengeAnswerC5(
ChallengeType.BERLIN_GROUP_SIGNING_BASKETS_CHALLENGE,
None,
None,
Some(basketId),
authorisationId,
updateBasketPsuDataJson.scaAuthenticationData,
SuppliedAnswerType.PLAIN_TEXT_VALUE,
callContext
)
// Get the challenge after validation
Expand Down
9 changes: 6 additions & 3 deletions obp-api/src/main/scala/code/api/constant/constant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ object Constant extends MdcLoggable {
final val SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID = "ReadBalancesBerlinGroup"
final val SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID = "ReadTransactionsBerlinGroup"

//TODO, this need to be double check
final val ALL_SYSTEM_VIEWS_CREATED_FROM_BOOT =
//This is used for the canRevokeAccessToViews_ and canGrantAccessToViews_ fields of SYSTEM_OWNER_VIEW_ID or SYSTEM_STANDARD_VIEW_ID.
final val DEFAULT_CAN_GRANT_AND_REVOKE_ACCESS_TO_VIEWS =
SYSTEM_OWNER_VIEW_ID::
SYSTEM_AUDITOR_VIEW_ID::
SYSTEM_ACCOUNTANT_VIEW_ID::
Expand All @@ -80,7 +80,10 @@ object Constant extends MdcLoggable {
SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID::
SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID :: Nil

final val ALL_SYSTEM_VIEWS_CREATED_FROM_CBS =
//We allow CBS side to generate views by getBankAccountsForUser.viewsToGenerate filed.
// viewsToGenerate can be any views, and OBP will check the following list, to make sure only allowed views are generated
// If some views are not allowed, obp just log it, do not throw exceptions.
final val VIEWS_GENERATED_FROM_CBS_WHITE_LIST =
SYSTEM_OWNER_VIEW_ID::
SYSTEM_ACCOUNTANT_VIEW_ID::
SYSTEM_AUDITOR_VIEW_ID::
Expand Down
15 changes: 12 additions & 3 deletions obp-api/src/main/scala/code/api/util/ConsentUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -508,9 +508,18 @@ object Consent extends MdcLoggable {
Future(Failure(ErrorMessages.ConsentCheckExpiredIssue), Some(updatedCallContext))
}
} catch { // Possible exceptions
case e: ParseException => Future(Failure("ParseException: " + e.getMessage), Some(updatedCallContext))
case e: MappingException => Future(Failure("MappingException: " + e.getMessage), Some(updatedCallContext))
case e: Exception => Future(Failure("parsing failed: " + e.getMessage), Some(updatedCallContext))
case e: ParseException => {
logger.debug(s"code.api.util.JwtUtil.getSignedPayloadAsJson.ParseException: $e")
Future(Failure("ParseException: " + e.getMessage), Some(updatedCallContext))
}
case e: MappingException => {
logger.debug(s"code.api.util.JwtUtil.getSignedPayloadAsJson.MappingException: $e")
Future(Failure("MappingException: " + e.getMessage), Some(updatedCallContext))
}
case e: Throwable => {
logger.debug(s"code.api.util.JwtUtil.getSignedPayloadAsJson.Throwable: $e")
Future(Failure("parsing failed: " + e.getMessage), Some(updatedCallContext))
}
}
case failure@Failure(_, _, _) =>
Future(failure, Some(updatedCallContext))
Expand Down
49 changes: 49 additions & 0 deletions obp-api/src/main/scala/code/api/util/ExampleValue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,9 @@ object ExampleValue {

lazy val hashOfSuppliedAnswerExample = ConnectorField(HashUtil.Sha256Hash("123"), s"Sha256 hash value of the ChallengeAnswer.challengeId")
glossaryItems += makeGlossaryItem("ChallengeAnswer.hashOfSuppliedAnswer", hashOfSuppliedAnswerExample)

lazy val suppliedAnswerExample = ConnectorField("123456", s"The value of the ChallengeAnswer.challengeId")
glossaryItems += makeGlossaryItem("ChallengeAnswer.suppliedAnswerExample", suppliedAnswerExample)


lazy val gitCommitExample = ConnectorField("59623811dd8a41f6ffe67be46954eee11913dc28", "Identifies the code running on the OBP-API (Connector) or Adapter.")
Expand Down Expand Up @@ -1516,7 +1519,53 @@ object ExampleValue {
"The whole create consent request json body."
)

lazy val vrpConsentRequestPayloadExample = ConnectorField(
s"""{
| "from_account": {
| "bank_routing": {
| "scheme": "BIC",
| "address": "ABCDED"
| },
| "account_routing": {
| "scheme": "AccountNumber",
| "address": "4930396"
| },
| "branch_routing": {
| "scheme": "",
| "address": ""
| }
| },
| "to_account": {
| "bank_routing": {
| "scheme": "BIC",
| "address": "DDFFFF"
| },
| "account_routing": {
| "scheme": "AccountNumber",
| "address": "123567"
| },
| "branch_routing": {
| "scheme": "",
| "address": ""
| },
| "limit": {
| "currency": "EUR",
| "max_single_amount": 1000,
| "max_monthly_amount": 10000,
| "max_number_of_monthly_transactions": 10,
| "max_yearly_amount": 12000,
| "max_number_of_yearly_transactions": 100
| }
| },
| "valid_from": "2024-07-10T09:22:06Z",
| "time_to_live": 3600
|}
|""".stripMargin,
"The whole create consent request json body."
)

glossaryItems += makeGlossaryItem("payload", consentRequestPayloadExample)
glossaryItems += makeGlossaryItem("vrp_consent_request.payload", vrpConsentRequestPayloadExample)

lazy val consentRequestIdExample = ConnectorField (
"8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0",
Expand Down
26 changes: 16 additions & 10 deletions obp-api/src/main/scala/code/api/util/NewStyle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1330,25 +1330,27 @@ object NewStyle extends MdcLoggable{
(unboxFullOrFail(i._1, callContext, s"$InvalidConnectorResponse() "), i._2)
}

//At moment this method is used for Berlin Group Payments
def validateChallengeAnswerC2(
//At moment this method is used for Berlin Group Payments and Consents
def validateChallengeAnswerC4(
challengeType: ChallengeType.Value,
transactionRequestId: Option[String],
consentId: Option[String],
challengeId: String,
hashOfSuppliedAnswer: String,
challengeId: String,
suppliedAnswer: String,
suppliedAnswerType: SuppliedAnswerType.Value,
callContext: Option[CallContext]
): OBPReturnType[ChallengeTrait] = {
if(challengeType == ChallengeType.BERLIN_GROUP_PAYMENT_CHALLENGE && transactionRequestId.isEmpty ){
Future{ throw new Exception(s"$UnknownError The following parameters can not be empty for BERLINGROUP_PAYMENT_CHALLENGE challengeType: paymentId($transactionRequestId) ")}
}else if(challengeType == ChallengeType.BERLIN_GROUP_CONSENT_CHALLENGE && consentId.isEmpty ){
Future{ throw new Exception(s"$UnknownError The following parameters can not be empty for BERLINGROUP_CONSENT_CHALLENGE challengeType: consentId($consentId) ")}
}else{
Connector.connector.vend.validateChallengeAnswerC2(
Connector.connector.vend.validateChallengeAnswerC4(
transactionRequestId: Option[String],
consentId: Option[String],
challengeId: String,
hashOfSuppliedAnswer: String,
suppliedAnswer: String,
suppliedAnswerType: SuppliedAnswerType.Value,
callContext: Option[CallContext]
) map { i =>
(unboxFullOrFail(i._1, callContext, s"${
Expand All @@ -1361,13 +1363,14 @@ object NewStyle extends MdcLoggable{
}

//At moment this method is used for Berlin Group SigningBasketsApi.scala
def validateChallengeAnswerC3(
def validateChallengeAnswerC5(
challengeType: ChallengeType.Value,
transactionRequestId: Option[String],
consentId: Option[String],
basketId: Option[String],
challengeId: String,
hashOfSuppliedAnswer: String,
suppliedAnswer: String,
suppliedAnswerType: SuppliedAnswerType.Value,
callContext: Option[CallContext]
): OBPReturnType[Box[ChallengeTrait]] = {
if(challengeType == ChallengeType.BERLIN_GROUP_PAYMENT_CHALLENGE && transactionRequestId.isEmpty ){
Expand All @@ -1377,12 +1380,13 @@ object NewStyle extends MdcLoggable{
} else if(challengeType == ChallengeType.BERLIN_GROUP_SIGNING_BASKETS_CHALLENGE && basketId.isEmpty ){
Future{ throw new Exception(s"$UnknownError The following parameters can not be empty for BERLINGROUP_CONSENT_CHALLENGE challengeType: basketId($basketId) ")}
} else {
Connector.connector.vend.validateChallengeAnswerC3(
Connector.connector.vend.validateChallengeAnswerC5(
transactionRequestId: Option[String],
consentId: Option[String],
basketId: Option[String],
challengeId: String,
hashOfSuppliedAnswer: String,
suppliedAnswer: String,
suppliedAnswerType: SuppliedAnswerType.Value,
callContext: Option[CallContext]
)
}
Expand Down Expand Up @@ -4064,6 +4068,7 @@ object NewStyle extends MdcLoggable{
accountId: String,
viewId: String,
counterpartyId: String,
currency: String,
maxSingleAmount: Int,
maxMonthlyAmount: Int,
maxNumberOfMonthlyTransactions: Int,
Expand All @@ -4076,6 +4081,7 @@ object NewStyle extends MdcLoggable{
accountId: String,
viewId: String,
counterpartyId: String,
currency: String,
maxSingleAmount: Int,
maxMonthlyAmount: Int,
maxNumberOfMonthlyTransactions: Int,
Expand Down
Loading

0 comments on commit 83ed226

Please sign in to comment.