From 0d470a0fc6fc8b61a6a8a65ae41b53950d352580 Mon Sep 17 00:00:00 2001 From: hongwei Date: Thu, 2 Jun 2022 14:54:18 +0200 Subject: [PATCH] bugfix/use the MappedExpectedChallengeAnswer to save all challenges for V400 --- .../SwaggerDefinitionsJSON.scala | 5 ++- .../AccountInformationServiceAISApi.scala | 4 +-- .../v1_3/PaymentInitiationServicePISApi.scala | 8 ++--- .../main/scala/code/api/util/NewStyle.scala | 17 +++++----- .../scala/code/api/v2_1_0/APIMethods210.scala | 6 ++-- .../scala/code/api/v4_0_0/APIMethods400.scala | 31 +++++++++---------- .../code/api/v4_0_0/JSONFactory4.0.0.scala | 7 +++-- .../scala/code/bankconnectors/Connector.scala | 9 +++--- .../bankconnectors/LocalMappedConnector.scala | 29 +++++++++++------ .../akka/AkkaConnector_vDec2018.scala | 2 +- .../remotedata/RemotedataChallenges.scala | 5 +-- .../RemotedataChallengesActor.scala | 5 +-- .../ChallengeProvider.scala | 6 ++-- .../MappedChallengeProvider.scala | 4 ++- .../MappedExpectedChallengeAnswer.scala | 2 +- .../MappedTransactionRequestProvider.scala | 2 +- .../TransactionRequests.scala | 5 --- .../api/v1_4_0/TransactionRequestsTest.scala | 5 ++- .../commons/model/enums/Enumerations.scala | 8 ++--- 19 files changed, 82 insertions(+), 78 deletions(-) diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala index d2cfad322..968165127 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala @@ -25,12 +25,11 @@ import code.connectormethod.{JsonConnectorMethod, JsonConnectorMethodMethodBody} import code.dynamicMessageDoc.JsonDynamicMessageDoc import code.dynamicResourceDoc.JsonDynamicResourceDoc import code.sandbox.SandboxData -import code.transactionrequests.TransactionRequests.TransactionChallengeTypes import code.transactionrequests.TransactionRequests.TransactionRequestTypes._ import com.github.dwickern.macros.NameOf.nameOf import com.openbankproject.commons.model import com.openbankproject.commons.model.PinResetReason.{FORGOT, GOOD_SECURITY_PRACTICE} -import com.openbankproject.commons.model.enums.{AttributeCategory, CardAttributeType} +import com.openbankproject.commons.model.enums.{AttributeCategory, CardAttributeType, ChallengeType} import com.openbankproject.commons.model.{UserAuthContextUpdateStatus, ViewBasic, _} import com.openbankproject.commons.util.{ApiVersion, FieldNameApiVersions, ReflectUtils, RequiredArgs, RequiredInfo} import net.liftweb.json @@ -4309,7 +4308,7 @@ object SwaggerDefinitionsJSON { id = transactionIdExample.value, user_id = userIdExample.value, allowed_attempts =3, - challenge_type = TransactionChallengeTypes.OTP_VIA_API.toString, + challenge_type = ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString, link = "/obp/v4.0.0/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types/TRANSACTION_REQUEST_TYPE/transaction-requests/TRANSACTION_REQUEST_ID/challenge" ) val transactionRequestWithChargeJSON400 = TransactionRequestWithChargeJSON400( diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala index 9a15ceff0..92c4759d7 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/AccountInformationServiceAISApi.scala @@ -1078,7 +1078,7 @@ The ASPSP might make the usage of this access method unnecessary, since the rela } (challenges, callContext) <- NewStyle.function.createChallengesC2( List(u.userId), - ChallengeType.BERLINGROUP_CONSENT, + ChallengeType.BERLINGROUP_CONSENT_CHALLENGE, None, getSuggestedDefaultScaMethod(), Some(StrongCustomerAuthenticationStatus.received), @@ -1154,7 +1154,7 @@ Maybe in a later version the access path will change. challenges.filter(_.challengeId == authorisationId).size == 1 } (challenge, callContext) <- NewStyle.function.validateChallengeAnswerC2( - ChallengeType.BERLINGROUP_CONSENT, + ChallengeType.BERLINGROUP_CONSENT_CHALLENGE, None, Some(consentId), challenges.filter(_.challengeId == authorisationId).head.challengeId, diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala index 7ada316c6..7f06d7c52 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/PaymentInitiationServicePISApi.scala @@ -675,7 +675,7 @@ This applies in the following scenarios: (challenges, callContext) <- NewStyle.function.createChallengesC2( List(u.userId), - ChallengeType.BERLINGROUP_PAYMENT, + ChallengeType.BERLINGROUP_PAYMENT_CHALLENGE, Some(paymentId), getScaMethodAtInstance(SEPA_CREDIT_TRANSFERS.toString).toOption, Some(StrongCustomerAuthenticationStatus.received), @@ -765,7 +765,7 @@ This applies in the following scenarios: } (challenges, callContext) <- NewStyle.function.createChallengesC2( List(u.userId), - ChallengeType.BERLINGROUP_PAYMENT, + ChallengeType.BERLINGROUP_PAYMENT_CHALLENGE, Some(paymentId), getScaMethodAtInstance(SEPA_CREDIT_TRANSFERS.toString).toOption, Some(StrongCustomerAuthenticationStatus.received), @@ -877,7 +877,7 @@ There are the following request types on this access path: } (_, callContext) <- NewStyle.function.getTransactionRequestImpl(TransactionRequestId(paymentId), callContext) (challenge, callContext) <- NewStyle.function.validateChallengeAnswerC2( - ChallengeType.BERLINGROUP_PAYMENT, + ChallengeType.BERLINGROUP_PAYMENT_CHALLENGE, Some(paymentId), None, cancellationId, @@ -997,7 +997,7 @@ There are the following request types on this access path: existingTransactionRequest.status == TransactionRequestStatus.INITIATED.toString } (challenge, callContext) <- NewStyle.function.validateChallengeAnswerC2( - ChallengeType.BERLINGROUP_PAYMENT, + ChallengeType.BERLINGROUP_PAYMENT_CHALLENGE, Some(paymentId), None, authorisationid, diff --git a/obp-api/src/main/scala/code/api/util/NewStyle.scala b/obp-api/src/main/scala/code/api/util/NewStyle.scala index 63e1dc225..2361d46df 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -72,7 +72,6 @@ import code.dynamicMessageDoc.{DynamicMessageDocProvider, JsonDynamicMessageDoc} import code.dynamicResourceDoc.{DynamicResourceDocProvider, JsonDynamicResourceDoc} import code.endpointMapping.{EndpointMappingProvider, EndpointMappingT} import code.endpointTag.EndpointTagT -import code.transactionrequests.TransactionRequests.TransactionChallengeTypes import code.util.Helper.MdcLoggable import code.views.system.AccountAccess import net.liftweb.mapper.By @@ -1155,7 +1154,7 @@ object NewStyle extends MdcLoggable{ transactionRequestCommonBody: TransactionRequestCommonBodyJSON, detailsPlain: String, chargePolicy: String, - challengeType: Option[TransactionChallengeTypes.Value], + challengeType: Option[ChallengeType.Value], scaMethod: Option[SCA], reasons: Option[List[TransactionRequestReason]], berlinGroupPayments: Option[SepaCreditTransfersBerlinGroupV13], @@ -1340,14 +1339,12 @@ object NewStyle extends MdcLoggable{ bankId: BankId, accountId: AccountId, transReqId: TransactionRequestId, - challenges: List[ChallengeTrait], callContext: Option[CallContext] ): OBPReturnType[Boolean] = Connector.connector.vend.allChallengesSuccessfullyAnswered( bankId: BankId, accountId: AccountId, transReqId: TransactionRequestId, - challenges: List[ChallengeTrait], callContext: Option[CallContext] ) map { i => (unboxFullOrFail(i._1, callContext, s"$InvalidConnectorResponse"), i._2) @@ -1366,10 +1363,10 @@ object NewStyle extends MdcLoggable{ hashOfSuppliedAnswer: String, callContext: Option[CallContext] ): OBPReturnType[ChallengeTrait] = { - if(challengeType == ChallengeType.BERLINGROUP_PAYMENT && transactionRequestId.isEmpty ){ - Future{ throw new Exception(s"$UnknownError The following parameters can not be empty for BERLINGROUP_PAYMENT challengeType: paymentId($transactionRequestId) ")} - }else if(challengeType == ChallengeType.BERLINGROUP_CONSENT && consentId.isEmpty ){ - Future{ throw new Exception(s"$UnknownError The following parameters can not be empty for BERLINGROUP_CONSENT challengeType: consentId($consentId) ")} + if(challengeType == ChallengeType.BERLINGROUP_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.BERLINGROUP_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( transactionRequestId: Option[String], @@ -1405,9 +1402,9 @@ object NewStyle extends MdcLoggable{ authenticationMethodId: Option[String], callContext: Option[CallContext] ) : OBPReturnType[List[ChallengeTrait]] = { - if(challengeType == ChallengeType.BERLINGROUP_PAYMENT && (transactionRequestId.isEmpty || scaStatus.isEmpty || scaMethod.isEmpty)){ + if(challengeType == ChallengeType.BERLINGROUP_PAYMENT_CHALLENGE && (transactionRequestId.isEmpty || scaStatus.isEmpty || scaMethod.isEmpty)){ Future{ throw new Exception(s"$UnknownError The following parameters can not be empty for BERLINGROUP_PAYMENT challengeType: paymentId($transactionRequestId), scaStatus($scaStatus), scaMethod($scaMethod) ")} - }else if(challengeType == ChallengeType.BERLINGROUP_CONSENT && (consentId.isEmpty || scaStatus.isEmpty || scaMethod.isEmpty)){ + }else if(challengeType == ChallengeType.BERLINGROUP_CONSENT_CHALLENGE && (consentId.isEmpty || scaStatus.isEmpty || scaMethod.isEmpty)){ Future{ throw new Exception(s"$UnknownError The following parameters can not be empty for BERLINGROUP_CONSENT challengeType: consentId($consentId), scaStatus($scaStatus), scaMethod($scaMethod) ")} }else{ Connector.connector.vend.createChallengesC2( diff --git a/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala b/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala index 6a783baaa..1640c05cb 100644 --- a/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala +++ b/obp-api/src/main/scala/code/api/v2_1_0/APIMethods210.scala @@ -1,7 +1,6 @@ package code.api.v2_1_0 import java.util.Date - import code.TransactionTypes.TransactionType import code.api.util import code.api.util.ApiTag._ @@ -23,12 +22,13 @@ import code.fx.fx import code.metrics.APIMetrics import code.model.{BankAccountX, BankX, Consumer, UserX, toUserExtended} import code.sandbox.SandboxData -import code.transactionrequests.TransactionRequests.{TransactionChallengeTypes, TransactionRequestTypes} +import code.transactionrequests.TransactionRequests.TransactionRequestTypes import code.usercustomerlinks.UserCustomerLink import code.users.Users import code.util.Helper.booleanToBox import code.views.Views import com.openbankproject.commons.model._ +import com.openbankproject.commons.model.enums.ChallengeType import com.openbankproject.commons.util.ApiVersion import net.liftweb.json.Extraction import net.liftweb.util.Helpers.tryo @@ -639,7 +639,7 @@ trait APIMethods210 { //Check the challenge type, Note: not support yet, the default value is SANDBOX_TAN _ <- Helper.booleanToFuture(s"${InvalidChallengeType} ", cc=callContext) { - existingTransactionRequest.challenge.challenge_type == TransactionChallengeTypes.OTP_VIA_API.toString + existingTransactionRequest.challenge.challenge_type == ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString } (isChallengeAnswerValidated, callContext) <- NewStyle.function.validateChallengeAnswer(challengeAnswerJson.id, challengeAnswerJson.answer, callContext) diff --git a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala index a3bf265dd..c7a8fb75d 100644 --- a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala +++ b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala @@ -58,7 +58,6 @@ import code.scope.Scope import code.snippet.{WebUIPlaceholder, WebUITemplate} import code.transactionChallenge.MappedExpectedChallengeAnswer import code.transactionrequests.MappedTransactionRequestProvider -import code.transactionrequests.TransactionRequests.TransactionChallengeTypes._ import code.transactionrequests.TransactionRequests.TransactionRequestTypes import code.transactionrequests.TransactionRequests.TransactionRequestTypes.{apply => _, _} import code.usercustomerlinks.UserCustomerLink @@ -73,6 +72,7 @@ import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue import com.github.dwickern.macros.NameOf.nameOf import com.openbankproject.commons.ExecutionContext.Implicits.global import com.openbankproject.commons.dto.GetProductsParam +import com.openbankproject.commons.model.enums.ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE import com.openbankproject.commons.model.enums.DynamicEntityOperation._ import com.openbankproject.commons.model.enums.{TransactionRequestStatus, _} import com.openbankproject.commons.model.{ListResult, _} @@ -1035,7 +1035,7 @@ trait APIMethods400 { transactionRequestBodyRefundJson.copy(description = newDescription), transDetailsSerialized, sharedChargePolicy.toString, - Some(OTP_VIA_API), + Some(OBP_TRANSACTION_REQUEST_CHALLENGE), getScaMethodAtInstance(transactionRequestType.value).toOption, None, None, @@ -1091,7 +1091,7 @@ trait APIMethods400 { transactionRequestBodySandboxTan, transDetailsSerialized, sharedChargePolicy.toString, - Some(OTP_VIA_API), + Some(OBP_TRANSACTION_REQUEST_CHALLENGE), getScaMethodAtInstance(transactionRequestType.value).toOption, None, None, @@ -1120,7 +1120,7 @@ trait APIMethods400 { transactionRequestBodySandboxTan, transDetailsSerialized, sharedChargePolicy.toString, - Some(OTP_VIA_WEB_FORM), + Some(OBP_TRANSACTION_REQUEST_CHALLENGE), getScaMethodAtInstance(transactionRequestType.value).toOption, None, None, @@ -1155,7 +1155,7 @@ trait APIMethods400 { transactionRequestBodyCounterparty, transDetailsSerialized, chargePolicy, - Some(OTP_VIA_API), + Some(OBP_TRANSACTION_REQUEST_CHALLENGE), getScaMethodAtInstance(transactionRequestType.value).toOption, None, None, @@ -1207,7 +1207,7 @@ trait APIMethods400 { transactionRequestBodySimple, transDetailsSerialized, chargePolicy, - Some(OTP_VIA_API), + Some(OBP_TRANSACTION_REQUEST_CHALLENGE), getScaMethodAtInstance(transactionRequestType.value).toOption, None, None, @@ -1242,7 +1242,7 @@ trait APIMethods400 { transDetailsSEPAJson, transDetailsSerialized, chargePolicy, - Some(OTP_VIA_API), + Some(OBP_TRANSACTION_REQUEST_CHALLENGE), getScaMethodAtInstance(transactionRequestType.value).toOption, transDetailsSEPAJson.reasons.map(_.map(_.transform)), None, @@ -1267,7 +1267,7 @@ trait APIMethods400 { transactionRequestBodyFreeForm, transDetailsSerialized, sharedChargePolicy.toString, - Some(OTP_VIA_API), + Some(OBP_TRANSACTION_REQUEST_CHALLENGE), getScaMethodAtInstance(transactionRequestType.value).toOption, None, None, @@ -1384,17 +1384,16 @@ trait APIMethods400 { _ <- Helper.booleanToFuture(s"${TransactionRequestTypeHasChanged} It should be :'$existingTransactionRequestType', but current value (${transactionRequestType.value}) ", cc=callContext) { existingTransactionRequestType.equals(transactionRequestType.value) } + + (challenges, callContext) <- NewStyle.function.getChallengesByTransactionRequestId(transReqId.value, callContext) //Check the challenge type, Note: not supported yet, the default value is SANDBOX_TAN - _ <- Helper.booleanToFuture(s"${InvalidChallengeType} ", cc=callContext) { - List( - OTP_VIA_API.toString, - OTP_VIA_WEB_FORM.toString - ).exists(_ == existingTransactionRequest.challenge.challenge_type) + _ <- Helper.booleanToFuture(s"$InvalidChallengeType Current Type is ${challenges.map(_.challengeType)}" , cc=callContext) { + challenges.map(_.challengeType) + .filterNot(challengeType => challengeType.equals(ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString)) + .isEmpty } - (challenges, callContext) <- NewStyle.function.getChallengesByTransactionRequestId(transReqId.value, callContext) - (transactionRequest, callContext) <- challengeAnswerJson.answer match { // If the challenge answer is `REJECT` - Currently only to Reject a SEPA transaction request REFUND case "REJECT" => @@ -1453,7 +1452,7 @@ trait APIMethods400 { challengeAnswerIsValidated } - (challengeAnswerIsValidated, callContext) <- NewStyle.function.allChallengesSuccessfullyAnswered(bankId, accountId, transReqId, challenges, callContext) + (challengeAnswerIsValidated, callContext) <- NewStyle.function.allChallengesSuccessfullyAnswered(bankId, accountId, transReqId, callContext) _ <- Helper.booleanToFuture(s"$NextChallengePending", cc=callContext) { challengeAnswerIsValidated } diff --git a/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala b/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala index 682aca2b3..c502ef11d 100644 --- a/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala +++ b/obp-api/src/main/scala/code/api/v4_0_0/JSONFactory4.0.0.scala @@ -54,11 +54,12 @@ import code.model.dataAccess.ResourceUser import code.model.{Consumer, ModeratedBankAccount, ModeratedBankAccountCore} import code.ratelimiting.RateLimiting import code.standingorders.StandingOrderTrait -import code.transactionrequests.TransactionRequests.TransactionChallengeTypes + import code.userlocks.UserLocks import code.users.{UserAgreement, UserAttribute, UserInvitation} import code.views.system.AccountAccess import code.webhook.{AccountWebhook, BankAccountNotificationWebhookTrait, SystemAccountNotificationWebhookTrait} +import com.openbankproject.commons.model.enums.ChallengeType import com.openbankproject.commons.model.{DirectDebitTrait, ProductFeeTrait, _} import net.liftweb.common.{Box, Full} import net.liftweb.json.JValue @@ -1229,8 +1230,8 @@ object JSONFactory400 { stringOrNull(tr.id.value), "/challenge").mkString("") val link = challenge.challengeType match { - case challengeType if challengeType == TransactionChallengeTypes.OTP_VIA_WEB_FORM.toString => otpViaWebFormPath - case challengeType if challengeType == TransactionChallengeTypes.OTP_VIA_API.toString => otpViaApiPath + case challengeType if challengeType == ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString => otpViaWebFormPath + case challengeType if challengeType == ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString => otpViaApiPath case _ => "" } ChallengeJsonV400( diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index 2fbaf59f0..4c5b59837 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -404,7 +404,6 @@ trait Connector extends MdcLoggable { bankId: BankId, accountId: AccountId, transReqId: TransactionRequestId, - challenges: List[ChallengeTrait], callContext: Option[CallContext] ): OBPReturnType[Box[Boolean]]= Future{(Full(true), callContext)} @@ -845,7 +844,7 @@ trait Connector extends MdcLoggable { } } else { //if challenge necessary, create a new one - val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = TransactionChallengeTypes.OTP_VIA_API.toString) + val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) saveTransactionRequestChallenge(result.id, challenge) result = result.copy(challenge = challenge) } @@ -913,7 +912,7 @@ trait Connector extends MdcLoggable { } } else { //if challenge necessary, create a new one - val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = TransactionChallengeTypes.OTP_VIA_API.toString) + val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) saveTransactionRequestChallenge(result.id, challenge) result = result.copy(challenge = challenge) } @@ -1043,7 +1042,7 @@ trait Connector extends MdcLoggable { (unboxFullOrFail(i._1, callContext, s"$InvalidConnectorResponseForCreateChallenge ", 400), i._2) } - newChallenge = TransactionRequestChallenge(challengeId, allowed_attempts = 3, challenge_type = challengeType.getOrElse(TransactionChallengeTypes.OTP_VIA_API.toString)) + newChallenge = TransactionRequestChallenge(challengeId, allowed_attempts = 3, challenge_type = challengeType.getOrElse(ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString)) _ <- Future (saveTransactionRequestChallenge(transactionRequest.id, newChallenge)) transactionRequest <- Future(transactionRequest.copy(challenge = newChallenge)) } yield { @@ -1223,7 +1222,7 @@ trait Connector extends MdcLoggable { tr.map(_._1) match { case Full(tr: TransactionRequest) => if (tr.challenge.allowed_attempts > 0) { - if (tr.challenge.challenge_type == TransactionChallengeTypes.OTP_VIA_API.toString) { + if (tr.challenge.challenge_type == ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) { //check if answer supplied is correct (i.e. for now, TAN -> some number and not empty) for { nonEmpty <- booleanToBox(answer.nonEmpty) ?~ "Need a non-empty answer" diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index df56ba90e..1cf5e7b35 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -65,7 +65,7 @@ import code.transactionChallenge.{Challenges, MappedExpectedChallengeAnswer} import code.transactionRequestAttribute.TransactionRequestAttributeX import code.transactionattribute.TransactionAttributeX import code.transactionrequests.TransactionRequests.TransactionRequestTypes._ -import code.transactionrequests.TransactionRequests.{TransactionChallengeTypes, TransactionRequestTypes} +import code.transactionrequests.TransactionRequests.TransactionRequestTypes import code.transactionrequests._ import code.users.{UserAttribute, UserAttributeProvider, Users} import code.util.Helper @@ -76,6 +76,7 @@ import com.nexmo.client.NexmoClient import com.nexmo.client.sms.messages.TextMessage import com.openbankproject.commons.ExecutionContext.Implicits.global import com.openbankproject.commons.dto.{CustomerAndAttribute, GetProductsParam, ProductCollectionItemsTree} +import com.openbankproject.commons.model.enums.ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE import com.openbankproject.commons.model.enums.DynamicEntityOperation._ import com.openbankproject.commons.model.enums.StrongCustomerAuthentication.SCA import com.openbankproject.commons.model.enums.StrongCustomerAuthenticationStatus.SCAStatus @@ -211,6 +212,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { None, //there are only for new version, set the empty here. None,//there are only for new version, set the empty here. None,//there are only for new version, set the empty here. + challengeType = OBP_TRANSACTION_REQUEST_CHALLENGE.toString, callContext: Option[CallContext]) (challenge._1.map(_.challengeId),challenge._2) } @@ -240,6 +242,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { None, //there are only for new version, set the empty here. None,//there are only for new version, set the empty here. None,//there are only for new version, set the empty here. + challengeType = OBP_TRANSACTION_REQUEST_CHALLENGE.toString, callContext ) challenge.map(_.challengeId).toList @@ -267,6 +270,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { scaStatus, consentId, authenticationMethodId, + challengeType = OBP_TRANSACTION_REQUEST_CHALLENGE.toString, callContext ) challengeId.toList @@ -290,7 +294,8 @@ object LocalMappedConnector extends Connector with MdcLoggable { scaMethod: Option[SCA], scaStatus: Option[SCAStatus], //Only use for BerlinGroup Now consentId: Option[String], // Note: consentId and transactionRequestId are exclusive here. - authenticationMethodId: Option[String], + authenticationMethodId: Option[String], + challengeType: String, callContext: Option[CallContext] ) = { def createHashedPassword(challengeAnswer: String) = { @@ -306,7 +311,8 @@ object LocalMappedConnector extends Connector with MdcLoggable { scaMethod, scaStatus, consentId, - authenticationMethodId), callContext) + authenticationMethodId, + challengeType), callContext) } scaMethod match { @@ -389,11 +395,11 @@ object LocalMappedConnector extends Connector with MdcLoggable { bankId: BankId, accountId: AccountId, transReqId: TransactionRequestId, - challenges: List[ChallengeTrait], callContext: Option[CallContext] ): OBPReturnType[Box[Boolean]] = { for { (accountAttributes, callContext) <- Connector.connector.vend.getAccountAttributesByAccount(bankId, accountId, callContext) + (challenges, callContext) <- NewStyle.function.getChallengesByTransactionRequestId(transReqId.value, callContext) quorum = accountAttributes.toList.flatten.find(_.name == "REQUIRED_CHALLENGE_ANSWERS").map(_.value).getOrElse("1").toInt challengeSuccess = challenges.count(_.successful == true) match { case number if number >= quorum => true @@ -4559,7 +4565,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { } } else { //if challenge necessary, create a new one - val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = TransactionChallengeTypes.OTP_VIA_API.toString) + val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) saveTransactionRequestChallenge(result.id, challenge) result = result.copy(challenge = challenge) } @@ -4630,7 +4636,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { } } else { //if challenge necessary, create a new one - val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = TransactionChallengeTypes.OTP_VIA_API.toString) + val challenge = TransactionRequestChallenge(id = generateUUID(), allowed_attempts = 3, challenge_type = ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) saveTransactionRequestChallenge(result.id, challenge) result = result.copy(challenge = challenge) } @@ -4767,7 +4773,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { (unboxFullOrFail(i._1, callContext, s"$InvalidConnectorResponseForCreateChallenge ", 400), i._2) } - newChallenge = TransactionRequestChallenge(challengeId, allowed_attempts = 3, challenge_type = challengeType.getOrElse(TransactionChallengeTypes.OTP_VIA_API.toString)) + newChallenge = TransactionRequestChallenge(challengeId, allowed_attempts = 3, challenge_type = challengeType.getOrElse(ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString)) _ <- Future(saveTransactionRequestChallenge(transactionRequest.id, newChallenge)) transactionRequest <- Future(transactionRequest.copy(challenge = newChallenge)) } yield { @@ -4841,6 +4847,9 @@ object LocalMappedConnector extends Connector with MdcLoggable { chargeLevelAmount <- NewStyle.function.tryons(s"$InvalidNumber chargeLevel.amount: ${chargeLevel.amount} can not be transferred to decimal !", 400, callContext) { BigDecimal(chargeLevel.amount) } + challengeTypeValue <- NewStyle.function.tryons(s"$InvalidChallengeType Current Type is $challengeType", 400, callContext) { + challengeType.map(ChallengeType.withName(_)).head + } chargeValue <- getChargeValue(chargeLevelAmount, transactionRequestCommonBodyAmount) charge = TransactionRequestCharge("Total charges for completed transaction", AmountOfMoney(transactionRequestCommonBody.value.currency, chargeValue)) // Always create a new Transaction Request @@ -4921,7 +4930,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { //So here we return the challengeIds. (challenges, callContext) <- Connector.connector.vend.createChallengesC2( userIds = users.toList.flatten.map(_.userId), - challengeType = ChallengeType.OBP_PAYMENT,//TODO, here just hard code, it is TransactionChallengeTypes.Value in createTransactionRequestv400 method + challengeType = challengeTypeValue, transactionRequestId = Some(transactionRequest.id.value), scaMethod = scaMethod, scaStatus = None, //Only use for BerlinGroup Now @@ -4934,7 +4943,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { //NOTE:this is only for Backward compatibility, now we use the MappedExpectedChallengeAnswer tables instead of the single field in TransactionRequest. //Here only put the dummy date. - newChallenge = TransactionRequestChallenge(s"challenges number:${challenges.length}", allowed_attempts = 3, challenge_type = TransactionChallengeTypes.OTP_VIA_API.toString) + newChallenge = TransactionRequestChallenge(s"challenges number:${challenges.length}", allowed_attempts = 3, challenge_type = ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) _ <- Future(saveTransactionRequestChallenge(transactionRequest.id, newChallenge)) transactionRequest <- Future(transactionRequest.copy(challenge = newChallenge)) } yield { @@ -5052,7 +5061,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { tr.map(_._1) match { case Full(tr: TransactionRequest) => if (tr.challenge.allowed_attempts > 0) { - if (tr.challenge.challenge_type == TransactionChallengeTypes.OTP_VIA_API.toString) { + if (tr.challenge.challenge_type == ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) { //check if answer supplied is correct (i.e. for now, TAN -> some number and not empty) for { nonEmpty <- booleanToBox(answer.nonEmpty) ?~ "Need a non-empty answer" diff --git a/obp-api/src/main/scala/code/bankconnectors/akka/AkkaConnector_vDec2018.scala b/obp-api/src/main/scala/code/bankconnectors/akka/AkkaConnector_vDec2018.scala index 6078c644a..8df38a14c 100644 --- a/obp-api/src/main/scala/code/bankconnectors/akka/AkkaConnector_vDec2018.scala +++ b/obp-api/src/main/scala/code/bankconnectors/akka/AkkaConnector_vDec2018.scala @@ -11,7 +11,7 @@ import code.api.util.ExampleValue._ import code.api.util._ import code.bankconnectors._ import code.bankconnectors.akka.actor.{AkkaConnectorActorInit, AkkaConnectorHelperActor} -import code.transactionrequests.TransactionRequests.TransactionChallengeTypes + import com.openbankproject.commons.ExecutionContext.Implicits.global import com.openbankproject.commons.dto._ import com.openbankproject.commons.model._ diff --git a/obp-api/src/main/scala/code/remotedata/RemotedataChallenges.scala b/obp-api/src/main/scala/code/remotedata/RemotedataChallenges.scala index c76f33e0b..868f4f111 100644 --- a/obp-api/src/main/scala/code/remotedata/RemotedataChallenges.scala +++ b/obp-api/src/main/scala/code/remotedata/RemotedataChallenges.scala @@ -21,10 +21,11 @@ object RemotedataChallenges extends ObpActorInit with ChallengeProvider { scaMethod: Option[SCA], scaStatus: Option[SCAStatus], consentId: Option[String], // Note: consentId and transactionRequestId are exclusive here. - authenticationMethodId: Option[String] + authenticationMethodId: Option[String], + challengeType: String, ): Box[ChallengeTrait] = getValueFromFuture( - (actor ? cc.saveChallenge(challengeId, transactionRequestId, salt, expectedAnswer, expectedUserId, scaMethod, scaStatus, consentId, authenticationMethodId)) + (actor ? cc.saveChallenge(challengeId, transactionRequestId, salt, expectedAnswer, expectedUserId, scaMethod, scaStatus, consentId, authenticationMethodId, challengeType)) .mapTo[Box[ChallengeTrait]] ) diff --git a/obp-api/src/main/scala/code/remotedata/RemotedataChallengesActor.scala b/obp-api/src/main/scala/code/remotedata/RemotedataChallengesActor.scala index 332cbf137..f26c530c7 100644 --- a/obp-api/src/main/scala/code/remotedata/RemotedataChallengesActor.scala +++ b/obp-api/src/main/scala/code/remotedata/RemotedataChallengesActor.scala @@ -18,10 +18,11 @@ class RemotedataChallengesActor extends Actor with ObpActorHelper with MdcLoggab scaMethod: Option[SCA], scaStatus: Option[SCAStatus], consentId: Option[String], // Note: consentId and transactionRequestId are exclusive here. - authenticationMethodId: Option[String] + authenticationMethodId: Option[String], + challengeType: String, ) => logger.debug(s"saveChallenge($challengeId, $transactionRequestId, $salt, $expectedAnswer, $expectedUserId)") - sender ! (mapper.saveChallenge(challengeId, transactionRequestId, salt, expectedAnswer, expectedUserId, scaMethod, scaStatus, consentId, authenticationMethodId)) + sender ! (mapper.saveChallenge(challengeId, transactionRequestId, salt, expectedAnswer, expectedUserId, scaMethod, scaStatus, consentId, authenticationMethodId, challengeType: String)) case cc.getChallenge(challengeId: String) => logger.debug(s"getChallenge($challengeId)") diff --git a/obp-api/src/main/scala/code/transactionChallenge/ChallengeProvider.scala b/obp-api/src/main/scala/code/transactionChallenge/ChallengeProvider.scala index 84106a131..84437e5e5 100644 --- a/obp-api/src/main/scala/code/transactionChallenge/ChallengeProvider.scala +++ b/obp-api/src/main/scala/code/transactionChallenge/ChallengeProvider.scala @@ -17,7 +17,8 @@ trait ChallengeProvider { scaMethod: Option[SCA], scaStatus: Option[SCAStatus], consentId: Option[String], // Note: consentId and transactionRequestId are exclusive here. - authenticationMethodId: Option[String], + authenticationMethodId: Option[String], + challengeType: String, ): Box[ChallengeTrait] def getChallenge(challengeId: String): Box[ChallengeTrait] @@ -45,7 +46,8 @@ class RemotedataChallengeProviderCaseClasses { scaMethod: Option[SCA], scaStatus: Option[SCAStatus], consentId: Option[String], // Note: consentId and transactionRequestId are exclusive here. - authenticationMethodId: Option[String] + authenticationMethodId: Option[String], + challengeType: String, ) case class getChallenge(challengeId: String) case class getChallengesByTransactionRequestId(transactionRequestId: String) diff --git a/obp-api/src/main/scala/code/transactionChallenge/MappedChallengeProvider.scala b/obp-api/src/main/scala/code/transactionChallenge/MappedChallengeProvider.scala index 06868ff9f..df5536bd9 100644 --- a/obp-api/src/main/scala/code/transactionChallenge/MappedChallengeProvider.scala +++ b/obp-api/src/main/scala/code/transactionChallenge/MappedChallengeProvider.scala @@ -25,12 +25,14 @@ object MappedChallengeProvider extends ChallengeProvider { scaMethod: Option[SCA], scaStatus: Option[SCAStatus], consentId: Option[String], // Note: consentId and transactionRequestId are exclusive here. - authenticationMethodId: Option[String], + authenticationMethodId: Option[String], + challengeType: String, ): Box[ChallengeTrait] = tryo ( MappedExpectedChallengeAnswer .create .mChallengeId(challengeId) + .mChallengeType(challengeType) .mTransactionRequestId(transactionRequestId) .mSalt(salt) .mExpectedAnswer(expectedAnswer) diff --git a/obp-api/src/main/scala/code/transactionChallenge/MappedExpectedChallengeAnswer.scala b/obp-api/src/main/scala/code/transactionChallenge/MappedExpectedChallengeAnswer.scala index 7a5d810fd..3fd568343 100644 --- a/obp-api/src/main/scala/code/transactionChallenge/MappedExpectedChallengeAnswer.scala +++ b/obp-api/src/main/scala/code/transactionChallenge/MappedExpectedChallengeAnswer.scala @@ -13,7 +13,7 @@ class MappedExpectedChallengeAnswer extends ChallengeTrait with LongKeyedMapper[ // Unique object mChallengeId extends MappedUUID(this) - object mChallengeType extends MappedUUID(this) + object mChallengeType extends MappedString(this, 100) object mTransactionRequestId extends MappedUUID(this) object mExpectedAnswer extends MappedString(this,50) object mExpectedUserId extends MappedUUID(this) diff --git a/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala b/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala index a089de47a..9a9d19d47 100644 --- a/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala +++ b/obp-api/src/main/scala/code/transactionrequests/MappedTransactionRequestProvider.scala @@ -200,7 +200,7 @@ class MappedTransactionRequest extends LongKeyedMapper[MappedTransactionRequest] object mEndDate extends MappedDate(this) object mChallenge_Id extends MappedString(this, 64) object mChallenge_AllowedAttempts extends MappedInt(this) - object mChallenge_ChallengeType extends MappedString(this, 32) + object mChallenge_ChallengeType extends MappedString(this, 100) object mCharge_Summary extends MappedString(this, 64) object mCharge_Amount extends MappedString(this, 32) object mCharge_Currency extends MappedString(this, 3) diff --git a/obp-api/src/main/scala/code/transactionrequests/TransactionRequests.scala b/obp-api/src/main/scala/code/transactionrequests/TransactionRequests.scala index 2a1438d93..5ff700756 100644 --- a/obp-api/src/main/scala/code/transactionrequests/TransactionRequests.scala +++ b/obp-api/src/main/scala/code/transactionrequests/TransactionRequests.scala @@ -15,11 +15,6 @@ object TransactionRequests extends SimpleInjector { val payments, bulk_payments, periodic_payments = Value } - object TransactionChallengeTypes extends Enumeration { - type TransactionChallengeTypes = Value - val OTP_VIA_API, OTP_VIA_WEB_FORM = Value - } - object TransactionRequestTypes extends Enumeration { type TransactionRequestTypes = Value val SANDBOX_TAN, ACCOUNT, ACCOUNT_OTP, COUNTERPARTY, SEPA, FREE_FORM, SIMPLE, diff --git a/obp-api/src/test/scala/code/api/v1_4_0/TransactionRequestsTest.scala b/obp-api/src/test/scala/code/api/v1_4_0/TransactionRequestsTest.scala index c7d4163f4..1a39810f4 100644 --- a/obp-api/src/test/scala/code/api/v1_4_0/TransactionRequestsTest.scala +++ b/obp-api/src/test/scala/code/api/v1_4_0/TransactionRequestsTest.scala @@ -8,8 +8,7 @@ import code.api.v1_4_0.JSONFactory1_4_0._ import code.bankconnectors.Connector import code.setup.DefaultUsers import code.transactionrequests.TransactionRequests.TransactionRequestTypes._ -import code.transactionrequests.TransactionRequests.TransactionChallengeTypes -import com.openbankproject.commons.model.enums.TransactionRequestStatus +import com.openbankproject.commons.model.enums.{ChallengeType, TransactionRequestStatus} import net.liftweb.json.JsonAST.JString import net.liftweb.json.Serialization.write import org.scalatest.Tag @@ -202,7 +201,7 @@ class TransactionRequestsTest extends V140ServerSetup with DefaultUsers { //amount over 100 €, so should trigger challenge request val amt = BigDecimal("1250.00") val bodyValue = AmountOfMoneyJsonV121("EUR", amt.toString()) - val transactionRequestBody = TransactionRequestBodyJsonV140(toAccountJson, bodyValue, "Test Transaction Request description", TransactionChallengeTypes.OTP_VIA_API.toString) + val transactionRequestBody = TransactionRequestBodyJsonV140(toAccountJson, bodyValue, "Test Transaction Request description", ChallengeType.OBP_TRANSACTION_REQUEST_CHALLENGE.toString) //call createTransactionRequest API method var request = (v1_4Request / "banks" / testBank.bankId.value / "accounts" / fromAccount.accountId.value / diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala index 6846d014d..2284960eb 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/enums/Enumerations.scala @@ -116,10 +116,10 @@ object StrongCustomerAuthenticationStatus extends OBPEnumeration[StrongCustomerA sealed trait ChallengeType extends EnumValue object ChallengeType extends OBPEnumeration[ChallengeType] { - object OBP_PAYMENT extends Value - object OBP_CONSENT extends Value - object BERLINGROUP_PAYMENT extends Value - object BERLINGROUP_CONSENT extends Value + object OBP_TRANSACTION_REQUEST_CHALLENGE extends Value + object OBP_CONSENT_CHALLENGE extends Value + object BERLINGROUP_PAYMENT_CHALLENGE extends Value + object BERLINGROUP_CONSENT_CHALLENGE extends Value } sealed trait PemCertificateRole extends EnumValue