mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:07:02 +00:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
60a9f76a57
@ -1359,5 +1359,13 @@ validate_iban=false
|
||||
# sample props regulated_entities = [{"certificate_authority_ca_owner_id":"CY_CBC","entity_certificate_public_key":"-----BEGIN CERTIFICATE-----MIICsjCCAZqgAwIBAgIGAYwQ62R0MA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNVBAMMD2FwcC5leGFtcGxlLmNvbTAeFw0yMzExMjcxMzE1MTFaFw0yNTExMjYxMzE1MTFaMBoxGDAWBgNVBAMMD2FwcC5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK9WIodZHWzKyCcf9YfWEhPURbfO6zKuMqzHN27GdqHsVVEGxP4F/J4mso+0ENcRr6ur4u81iREaVdCc40rHDHVJNEtniD8Icbz7tcsqAewIVhc/q6WXGqImJpCq7hA0m247dDsaZT0lb/MVBiMoJxDEmAE/GYYnWTEn84R35WhJsMvuQ7QmLvNg6RkChY6POCT/YKe9NKwa1NqI1U+oA5RFzAaFtytvZCE3jtp+aR0brL7qaGfgxm6B7dEpGyhg0NcVCV7xMQNq2JxZTVdAr6lcsRGaAFulakmW3aNnmK+L35Wu8uW+OxNxwUuC6f3b4FVBa276FMuUTRfu7gc+k6kCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAAU5CjEyAoyTn7PgFpQD48ZNPuUsEQ19gzYgJvHMzFIoZ7jKBodjO5mCzWBcR7A4mpeAsdyiNBl2sTiZscSnNqxk61jVzP5Ba1D7XtOjjr7+3iqowrThj6BY40QqhYh/6BSY9fDzVZQiHnvlo6ZUM5kUK6OavZOovKlp5DIl5sGqoP0qAJnpQ4nhB2WVVsKfPlOXc+2KSsbJ23g9l8zaTMr+X0umlvfEKqyEl1Fa2L1dO0y/KFQ+ILmxcZLpRdq1hRAjd0quq9qGC8ucXhRWDgM4hslVpau0da68g0aItWNez3mc5lB82b3dcZpFMzO41bgw7gvw10AvvTfQDqEYIuQ==-----END CERTIFICATE-----","entity_code":"PSD_PICY_CBC!12345","entity_type":"PSD_PI","entity_address":"EXAMPLE COMPANY LTD, 5 SOME STREET","entity_town_city":"SOME CITY","entity_post_code":"1060","entity_country":"CY","entity_web_site":"www.example.com","services":[{"CY":["PS_010","PS_020","PS_03C","PS_04C"]}]}]
|
||||
regulated_entities = []
|
||||
|
||||
#In OBP Create Consent if the app that is creating the consent (grantor_consumer_id) wants to create a consent for the grantee_consumer_id App, then we should skip SCA.
|
||||
#The use case is API Explorer II giving a consent to Opey . In such a case API Explorer II and Opey are effectively the same App as far as the user is concerned.
|
||||
|
||||
#skip_consent_sca_for_consumer_id_pairs=[{ \
|
||||
# "grantor_consumer_id": "ef0a8fa4-3814-4a21-8ca9-8c553a43aa631", \
|
||||
# "grantee_consumer_id": "fb327484-94d7-44d2-83e5-8d27301e8279" \
|
||||
#}]
|
||||
|
||||
|
||||
# Note: For secure and http only settings for cookies see resources/web.xml which is mentioned in the README.md
|
||||
@ -593,7 +593,9 @@ class Boot extends MdcLoggable {
|
||||
OAuthWorkedThanks.menu, //OAuth thanks page that will do the redirect
|
||||
Menu.i("Introduction") / "introduction",
|
||||
Menu.i("add-user-auth-context-update-request") / "add-user-auth-context-update-request",
|
||||
Menu.i("confirm-user-auth-context-update-request") / "confirm-user-auth-context-update-request"
|
||||
Menu.i("confirm-user-auth-context-update-request") / "confirm-user-auth-context-update-request",
|
||||
Menu.i("confirm-vrp-consent-request") / "confirm-vrp-consent-request" >> AuthUser.loginFirst,//OAuth consent page,
|
||||
Menu.i("confirm-vrp-consent") / "confirm-vrp-consent" >> AuthUser.loginFirst //OAuth consent page
|
||||
) ++ accountCreation ++ Admin.menus
|
||||
|
||||
// Build SiteMap
|
||||
|
||||
@ -5240,6 +5240,14 @@ object SwaggerDefinitionsJSON {
|
||||
consent_request_id = Some(consentRequestIdExample.value),
|
||||
account_access= Some(consentAccountAccessJson)
|
||||
)
|
||||
val consentJsonV510 = ConsentJsonV510(
|
||||
consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945",
|
||||
jwt = "eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOltdLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIyMWUxYzhjYy1mOTE4LTRlYWMtYjhlMy01ZTVlZWM2YjNiNGIiLCJhdWQiOiJlanpuazUwNWQxMzJyeW9tbmhieDFxbXRvaHVyYnNiYjBraWphanNrIiwibmJmIjoxNTUzNTU0ODk5LCJpc3MiOiJodHRwczpcL1wvd3d3Lm9wZW5iYW5rcHJvamVjdC5jb20iLCJleHAiOjE1NTM1NTg0OTksImlhdCI6MTU1MzU1NDg5OSwianRpIjoiMDlmODhkNWYtZWNlNi00Mzk4LThlOTktNjYxMWZhMWNkYmQ1Iiwidmlld3MiOlt7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAxIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifSx7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAyIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifV19.8cc7cBEf2NyQvJoukBCmDLT7LXYcuzTcSYLqSpbxLp4",
|
||||
status = ConsentStatus.INITIATED.toString,
|
||||
consent_request_id = Some(consentRequestIdExample.value),
|
||||
scopes = None,
|
||||
consumer_id= consumerIdExample.value
|
||||
)
|
||||
|
||||
val postConsentRequestJsonV500 = PostConsentRequestJsonV500(
|
||||
everything = false,
|
||||
|
||||
@ -504,7 +504,7 @@ There are the following request types on this access path:
|
||||
})
|
||||
}
|
||||
SigningBasketX.signingBasketProvider.vend.saveSigningBasketStatus(basketId, ConstantsBG.SigningBasketsStatus.ACTC.toString)
|
||||
unboxFullOrFail(boxedChallenge, callContext, s"$InvalidConnectorResponse ")
|
||||
unboxFullOrFail(boxedChallenge, callContext, s"$InvalidConnectorResponse validateChallengeAnswerC5")
|
||||
} else { // Fail due to unexisting payment
|
||||
val paymentIds = basket.flatMap(_.payments).getOrElse(Nil).mkString(",")
|
||||
unboxFullOrFail(Empty, callContext, s"$InvalidConnectorResponse Some of paymentIds [${paymentIds}] are invalid")
|
||||
@ -520,10 +520,10 @@ There are the following request types on this access path:
|
||||
})
|
||||
}
|
||||
// Fail in case of an error message
|
||||
unboxFullOrFail(boxedChallenge, callContext, s"$InvalidConnectorResponse ")
|
||||
unboxFullOrFail(boxedChallenge, callContext, s"$InvalidConnectorResponse validateChallengeAnswerC5")
|
||||
}
|
||||
case _ => // Fail in case of an error message
|
||||
Future(unboxFullOrFail(Empty, callContext, s"$InvalidConnectorResponse "))
|
||||
Future(unboxFullOrFail(Empty, callContext, s"$InvalidConnectorResponse getChallenge"))
|
||||
}
|
||||
} yield {
|
||||
(JSONFactory_BERLIN_GROUP_1_3.createStartPaymentAuthorisationJson(challenge), callContext)
|
||||
|
||||
@ -601,6 +601,11 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
domain: String,
|
||||
bank_ids: List[String]
|
||||
)
|
||||
//This is used for get the value from props `skip_consent_sca_for_consumer_id_pairs`
|
||||
case class ConsumerIdPair(
|
||||
grantor_consumer_id: String,
|
||||
grantee_consumer_id: String
|
||||
)
|
||||
|
||||
case class EmailDomainToEntitlementMapping(
|
||||
domain: String,
|
||||
@ -3167,7 +3172,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
}
|
||||
|
||||
def connectorEmptyResponse[T](box: Box[T], cc: Option[CallContext])(implicit m: Manifest[T]): T = {
|
||||
unboxFullOrFail(box, cc, InvalidConnectorResponse, 400)
|
||||
unboxFullOrFail(box, cc, s"$InvalidConnectorResponse ${nameOf(connectorEmptyResponse _)}" , 400)
|
||||
}
|
||||
|
||||
def unboxFuture[T](box: Box[Future[T]]): Future[Box[T]] = box match {
|
||||
@ -4729,6 +4734,23 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
APIUtil.getPropsValue("email_domain_to_space_mappings").map(extractor).getOrElse(Nil)
|
||||
}
|
||||
|
||||
val skipConsentScaForConsumerIdPairs: List[ConsumerIdPair] = {
|
||||
def extractor(str: String) = try {
|
||||
val consumerIdPair = json.parse(str).extract[List[ConsumerIdPair]]
|
||||
//The props value can be parsed to JNothing.
|
||||
if(str.nonEmpty && consumerIdPair == Nil)
|
||||
throw new RuntimeException("props [skip_consent_sca_for_consumer_id_pairs] parse -> extract to Nil!")
|
||||
else
|
||||
consumerIdPair
|
||||
} catch {
|
||||
case e: Throwable => // error handling, found wrong props value as early as possible.
|
||||
this.logger.error(s"props [skip_consent_sca_for_consumer_id_pairs] value is invalid, it should be the class($ConsumerIdPair) json format, current value is $str ." );
|
||||
throw e;
|
||||
}
|
||||
|
||||
APIUtil.getPropsValue("skip_consent_sca_for_consumer_id_pairs").map(extractor).getOrElse(Nil)
|
||||
}
|
||||
|
||||
val emailDomainToEntitlementMappings: List[EmailDomainToEntitlementMapping] = {
|
||||
def extractor(str: String) = try {
|
||||
val emailDomainToEntitlementMappings = json.parse(str).extract[List[EmailDomainToEntitlementMapping]]
|
||||
|
||||
@ -824,7 +824,7 @@ object ExampleValue {
|
||||
lazy val line1Example = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
glossaryItems += makeGlossaryItem("line1", line1Example)
|
||||
|
||||
lazy val fromDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
lazy val fromDateExample = ConnectorField(DateWithMsExampleString,s"The TimeStamp in the format: $DateWithMs")
|
||||
glossaryItems += makeGlossaryItem("from_date", fromDateExample)
|
||||
|
||||
lazy val creditLimitExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
@ -908,7 +908,7 @@ object ExampleValue {
|
||||
lazy val cashWithdrawalNationalFeeExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
|
||||
glossaryItems += makeGlossaryItem("ATM.cash_withdrawal_national_fee", cashWithdrawalNationalFeeExample)
|
||||
|
||||
lazy val cashWithdrawalInternationalFeeExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
|
||||
lazy val cashWithdrawalInternationalFeeExample: ConnectorField = ConnectorField(NoExampleProvided, NoDescriptionProvided)
|
||||
glossaryItems += makeGlossaryItem("ATM.cash_withdrawal_international_fee", cashWithdrawalInternationalFeeExample)
|
||||
|
||||
lazy val balanceInquiryFeeExample = ConnectorField(NoExampleProvided, NoDescriptionProvided)
|
||||
@ -1052,7 +1052,7 @@ object ExampleValue {
|
||||
lazy val itemsExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
glossaryItems += makeGlossaryItem("items", itemsExample)
|
||||
|
||||
lazy val toDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
lazy val toDateExample = ConnectorField(DateWithMsExampleString,s"The TimeStamp in the format: $DateWithMs")
|
||||
glossaryItems += makeGlossaryItem("to_date", toDateExample)
|
||||
|
||||
lazy val bankRoutingsExample = ConnectorField("bank routing in form of (scheme, address)",NoDescriptionProvided)
|
||||
@ -1622,7 +1622,7 @@ object ExampleValue {
|
||||
lazy val endDateExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
glossaryItems += makeGlossaryItem("end_date", endDateExample)
|
||||
|
||||
lazy val canAddTransactionRequestToOwnAccountExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
lazy val canAddTransactionRequestToOwnAccountExample = ConnectorField(booleanFalse,NoDescriptionProvided)
|
||||
glossaryItems += makeGlossaryItem("can_add_transaction_request_to_own_account", canAddTransactionRequestToOwnAccountExample)
|
||||
|
||||
lazy val otherAccountRoutingAddressExample = ConnectorField(NoExampleProvided,NoDescriptionProvided)
|
||||
@ -2340,7 +2340,7 @@ object ExampleValue {
|
||||
lazy val inboundAdapterInfoInternalErrorCodeExample = ConnectorField("error code", "fix me")
|
||||
lazy val inboundAdapterInfoInternalNameExample = ConnectorField("NAME", "fix me")
|
||||
lazy val inboundAdapterInfoInternalGit_commitExample = ConnectorField("git_commit", "fix me")
|
||||
lazy val inboundAdapterInfoInternalDateExample = ConnectorField("date String", "fix me")
|
||||
lazy val inboundAdapterInfoInternalDateExample = ConnectorField(DateWithMsExampleString, "")
|
||||
lazy val inboundAdapterInfoInternalVersionExample = ConnectorField("version string", "fix me")
|
||||
|
||||
lazy val inboundStatusMessageStatusExample = ConnectorField("Status string", "fix me")
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
package code.api.util.newstyle
|
||||
|
||||
import code.api.util.APIUtil.{OBPReturnType, unboxFullOrFail}
|
||||
import code.api.util.ErrorMessages.InvalidConnectorResponseForGetBankAccounts
|
||||
import code.api.util.ErrorMessages.{InvalidConnectorResponse}
|
||||
import code.api.util.{APIUtil, CallContext}
|
||||
import code.bankconnectors.Connector
|
||||
import code.views.Views
|
||||
import com.openbankproject.commons.model.{AccountBalances, AccountsBalances, BankId, BankIdAccountId, User, ViewId}
|
||||
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import scala.concurrent.Future
|
||||
|
||||
object BalanceNewStyle {
|
||||
@ -46,13 +46,13 @@ object BalanceNewStyle {
|
||||
|
||||
def getBankAccountBalances(bankIdAccountId: BankIdAccountId, callContext: Option[CallContext]): OBPReturnType[AccountBalances] = {
|
||||
Connector.connector.vend.getBankAccountBalances(bankIdAccountId: BankIdAccountId, callContext: Option[CallContext]) map { i =>
|
||||
(unboxFullOrFail(i._1, callContext,s"$InvalidConnectorResponseForGetBankAccounts", 400 ), i._2)
|
||||
(unboxFullOrFail(i._1, callContext,s"$InvalidConnectorResponse ${nameOf(getBankAccountBalances _)} ", 400 ), i._2)
|
||||
}
|
||||
}
|
||||
|
||||
def getBankAccountsBalances(bankIdAccountIds: List[BankIdAccountId], callContext: Option[CallContext]): OBPReturnType[AccountsBalances] = {
|
||||
Connector.connector.vend.getBankAccountsBalances(bankIdAccountIds: List[BankIdAccountId], callContext: Option[CallContext]) map { i =>
|
||||
(unboxFullOrFail(i._1, callContext,s"$InvalidConnectorResponseForGetBankAccounts", 400 ), i._2)
|
||||
(unboxFullOrFail(i._1, callContext,s"$InvalidConnectorResponse ${nameOf(getBankAccountsBalances _)}", 400 ), i._2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ import code.api.v3_0_0.JSONFactory300.createAdapterInfoJson
|
||||
import code.api.v3_1_0.JSONFactory310._
|
||||
import code.bankconnectors.rest.RestConnector_vMar2019
|
||||
import code.bankconnectors.{Connector, LocalMappedConnector}
|
||||
import code.consent.{ConsentRequests, ConsentStatus, Consents}
|
||||
import code.consent.{ConsentRequests, ConsentStatus, Consents, MappedConsent}
|
||||
import code.consumer.Consumers
|
||||
import code.context.UserAuthContextUpdateProvider
|
||||
import code.entitlement.Entitlement
|
||||
@ -57,6 +57,7 @@ import net.liftweb.http.provider.HTTPParam
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import net.liftweb.json._
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
import net.liftweb.mapper.By
|
||||
import net.liftweb.util.Mailer.{From, PlainMailBodyType, Subject, To}
|
||||
import net.liftweb.util.{Helpers, Mailer, Props, StringHelpers}
|
||||
import org.apache.commons.lang3.{StringUtils, Validate}
|
||||
@ -3586,66 +3587,82 @@ trait APIMethods310 {
|
||||
_ <- Future(Consents.consentProvider.vend.setJsonWebToken(createdConsent.consentId, consentJWT)) map {
|
||||
i => connectorEmptyResponse(i, callContext)
|
||||
}
|
||||
challengeText = s"Your consent challenge : ${challengeAnswer}, Application: $applicationText"
|
||||
_ <- scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL.toString => // Send the email
|
||||
for{
|
||||
failMsg <- Future {s"$InvalidJsonFormat The Json body should be the $PostConsentEmailJsonV310"}
|
||||
postConsentEmailJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentEmailJsonV310]
|
||||
}
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
postConsentEmailJson.email,
|
||||
Some("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield Future{status}
|
||||
case v if v == StrongCustomerAuthentication.SMS.toString =>
|
||||
for {
|
||||
failMsg <- Future {
|
||||
s"$InvalidJsonFormat The Json body should be the $PostConsentPhoneJsonV310"
|
||||
}
|
||||
postConsentPhoneJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentPhoneJsonV310]
|
||||
}
|
||||
phoneNumber = postConsentPhoneJson.phone_number
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
phoneNumber,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield Future{status}
|
||||
case v if v == StrongCustomerAuthentication.IMPLICIT.toString =>
|
||||
for {
|
||||
(consentImplicitSCA, callContext) <- NewStyle.function.getConsentImplicitSCA(user, callContext)
|
||||
status <- consentImplicitSCA.scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL => // Send the email
|
||||
NewStyle.function.sendCustomerNotification (
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
consentImplicitSCA.recipient,
|
||||
Some ("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case v if v == StrongCustomerAuthentication.SMS =>
|
||||
NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
consentImplicitSCA.recipient,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case _ => Future {
|
||||
"Success"
|
||||
}
|
||||
}} yield {
|
||||
status
|
||||
//we need to check `skip_consent_sca_for_consumer_id_pairs` props, to see if we really need the SCA flow.
|
||||
//this is from callContext
|
||||
grantorConsumerId = callContext.map(_.consumer.toOption.map(_.consumerId.get)).flatten.getOrElse("Unknown")
|
||||
//this is from json body
|
||||
granteeConsumerId = consentJson.consumer_id.getOrElse("Unknown")
|
||||
|
||||
shouldSkipConsentScaForConsumerIdPair = APIUtil.skipConsentScaForConsumerIdPairs.contains(
|
||||
APIUtil.ConsumerIdPair(
|
||||
grantorConsumerId,
|
||||
granteeConsumerId
|
||||
))
|
||||
mappedConsent <- if (shouldSkipConsentScaForConsumerIdPair) {
|
||||
Future{
|
||||
MappedConsent.find(By(MappedConsent.mConsentId, createdConsent.consentId)).map(_.mStatus(ConsentStatus.ACCEPTED.toString).saveMe()).head
|
||||
}
|
||||
case _ =>Future{"Success"}
|
||||
} else {
|
||||
val challengeText = s"Your consent challenge : ${challengeAnswer}, Application: $applicationText"
|
||||
scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL.toString => // Send the email
|
||||
for{
|
||||
failMsg <- Future {s"$InvalidJsonFormat The Json body should be the $PostConsentEmailJsonV310"}
|
||||
postConsentEmailJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentEmailJsonV310]
|
||||
}
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
postConsentEmailJson.email,
|
||||
Some("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield createdConsent
|
||||
case v if v == StrongCustomerAuthentication.SMS.toString =>
|
||||
for {
|
||||
failMsg <- Future {
|
||||
s"$InvalidJsonFormat The Json body should be the $PostConsentPhoneJsonV310"
|
||||
}
|
||||
postConsentPhoneJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentPhoneJsonV310]
|
||||
}
|
||||
phoneNumber = postConsentPhoneJson.phone_number
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
phoneNumber,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield createdConsent
|
||||
case v if v == StrongCustomerAuthentication.IMPLICIT.toString =>
|
||||
for {
|
||||
(consentImplicitSCA, callContext) <- NewStyle.function.getConsentImplicitSCA(user, callContext)
|
||||
status <- consentImplicitSCA.scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL => // Send the email
|
||||
NewStyle.function.sendCustomerNotification (
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
consentImplicitSCA.recipient,
|
||||
Some ("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case v if v == StrongCustomerAuthentication.SMS =>
|
||||
NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
consentImplicitSCA.recipient,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case _ => Future {
|
||||
"Success"
|
||||
}
|
||||
}} yield {
|
||||
createdConsent
|
||||
}
|
||||
case _ =>Future{createdConsent}}
|
||||
}
|
||||
} yield {
|
||||
(ConsentJsonV310(createdConsent.consentId, consentJWT, createdConsent.status), HttpCode.`201`(callContext))
|
||||
|
||||
@ -18,7 +18,7 @@ import code.api.v4_0_0.{JSONFactory400, PostCounterpartyJson400}
|
||||
import code.api.v5_0_0.JSONFactory500.{createPhysicalCardJson, createViewJsonV500, createViewsIdsJsonV500, createViewsJsonV500}
|
||||
import code.api.v5_1_0.{CreateCustomViewJson, PostCounterpartyLimitV510, PostVRPConsentRequestJsonV510}
|
||||
import code.bankconnectors.Connector
|
||||
import code.consent.{ConsentRequests, Consents}
|
||||
import code.consent.{ConsentRequests, ConsentStatus, Consents, MappedConsent}
|
||||
import code.consumer.Consumers
|
||||
import code.entitlement.Entitlement
|
||||
import code.metadata.counterparties.MappedCounterparty
|
||||
@ -40,6 +40,7 @@ import net.liftweb.json
|
||||
import net.liftweb.json.{Extraction, compactRender, prettyRender}
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
import net.liftweb.util.{Helpers, Props, StringHelpers}
|
||||
import net.liftweb.mapper.By
|
||||
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
@ -929,7 +930,7 @@ trait APIMethods500 {
|
||||
)) map {
|
||||
i => unboxFullOrFail(i,callContext, ConsentRequestNotFound)
|
||||
}
|
||||
_ <- Helper.booleanToFuture(ConsentRequestIsInvalid, cc=callContext){
|
||||
_ <- Helper.booleanToFuture(s"$ConsentRequestIsInvalid, the current CONSENT_REQUEST_ID($consentRequestId) is already used to create a consent, please provide another one!", cc=callContext){
|
||||
Consents.consentProvider.vend.getConsentByConsentRequestId(consentRequestId).isEmpty
|
||||
}
|
||||
_ <- Helper.booleanToFuture(ConsentAllowedScaMethods, cc=callContext){
|
||||
@ -1202,34 +1203,54 @@ trait APIMethods500 {
|
||||
_ <- Future(Consents.consentProvider.vend.setJsonWebToken(createdConsent.consentId, consentJWT)) map {
|
||||
i => connectorEmptyResponse(i, callContext)
|
||||
}
|
||||
challengeText = s"Your consent challenge : ${challengeAnswer}, Application: $applicationText"
|
||||
_ <- scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL.toString => // Send the email
|
||||
sendEmailNotification(callContext, consentRequestJson, challengeText)
|
||||
case v if v == StrongCustomerAuthentication.SMS.toString =>
|
||||
sendSmsNotification(callContext, consentRequestJson, challengeText)
|
||||
case v if v == StrongCustomerAuthentication.IMPLICIT.toString =>
|
||||
for {
|
||||
(consentImplicitSCA, callContext) <- NewStyle.function.getConsentImplicitSCA(user, callContext)
|
||||
status <- consentImplicitSCA.scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL => // Send the email
|
||||
sendEmailNotification(callContext, consentRequestJson.copy(email=Some(consentImplicitSCA.recipient)), challengeText)
|
||||
case v if v == StrongCustomerAuthentication.SMS =>
|
||||
sendSmsNotification(callContext, consentRequestJson.copy(phone_number=Some(consentImplicitSCA.recipient)), challengeText)
|
||||
case _ => Future {
|
||||
"Success"
|
||||
}
|
||||
}} yield {
|
||||
status
|
||||
//we need to check `skip_consent_sca_for_consumer_id_pairs` props, to see if we really need the SCA flow.
|
||||
//this is from callContext
|
||||
grantorConsumerId = callContext.map(_.consumer.toOption.map(_.consumerId.get)).flatten.getOrElse("Unknown")
|
||||
//this is from json body
|
||||
granteeConsumerId = postConsentBodyCommonJson.consumer_id.getOrElse("Unknown")
|
||||
|
||||
shouldSkipConsentScaForConsumerIdPair = APIUtil.skipConsentScaForConsumerIdPairs.contains(
|
||||
APIUtil.ConsumerIdPair(
|
||||
grantorConsumerId,
|
||||
granteeConsumerId
|
||||
))
|
||||
mappedConsent <- if (shouldSkipConsentScaForConsumerIdPair) {
|
||||
Future{
|
||||
MappedConsent.find(By(MappedConsent.mConsentId, createdConsent.consentId)).map(_.mStatus(ConsentStatus.ACCEPTED.toString).saveMe()).head
|
||||
}
|
||||
} else {
|
||||
val challengeText = s"Your consent challenge : ${challengeAnswer}, Application: $applicationText"
|
||||
scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL.toString => // Send the email
|
||||
sendEmailNotification(callContext, consentRequestJson, challengeText)
|
||||
case v if v == StrongCustomerAuthentication.SMS.toString =>
|
||||
sendSmsNotification(callContext, consentRequestJson, challengeText)
|
||||
case v if v == StrongCustomerAuthentication.IMPLICIT.toString =>
|
||||
for {
|
||||
(consentImplicitSCA, callContext) <- NewStyle.function.getConsentImplicitSCA(user, callContext)
|
||||
status <- consentImplicitSCA.scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL => // Send the email
|
||||
sendEmailNotification(callContext, consentRequestJson.copy(email = Some(consentImplicitSCA.recipient)), challengeText)
|
||||
case v if v == StrongCustomerAuthentication.SMS =>
|
||||
sendSmsNotification(callContext, consentRequestJson.copy(phone_number = Some(consentImplicitSCA.recipient)), challengeText)
|
||||
case _ => Future {
|
||||
"Success"
|
||||
}
|
||||
}} yield {
|
||||
status
|
||||
}
|
||||
case _ => Future {
|
||||
"Success"
|
||||
}
|
||||
case _ =>Future{"Success"}
|
||||
}
|
||||
Future{createdConsent}
|
||||
}
|
||||
} yield {
|
||||
(ConsentJsonV500(
|
||||
createdConsent.consentId,
|
||||
mappedConsent.consentId,
|
||||
consentJWT,
|
||||
createdConsent.status,
|
||||
Some(createdConsent.consentRequestId),
|
||||
mappedConsent.status,
|
||||
Some(mappedConsent.consentRequestId),
|
||||
if (isVRPConsentRequest) Some(ConsentAccountAccessJson(bankId.value, accountId.value, viewId.value, HelperInfoJson(List(counterpartyId.value)))) else None
|
||||
), HttpCode.`201`(callContext))
|
||||
}
|
||||
|
||||
@ -1684,7 +1684,7 @@ trait APIMethods510 {
|
||||
|
|
||||
""".stripMargin,
|
||||
EmptyBody,
|
||||
consentJsonV500,
|
||||
consentJsonV510,
|
||||
List(
|
||||
$UserNotLoggedIn,
|
||||
UnknownError
|
||||
@ -2050,77 +2050,95 @@ trait APIMethods510 {
|
||||
_ <- Future(Consents.consentProvider.vend.setJsonWebToken(createdConsent.consentId, consentJWT)) map {
|
||||
i => connectorEmptyResponse(i, callContext)
|
||||
}
|
||||
challengeText = s"Your consent challenge : ${challengeAnswer}, Application: $applicationText"
|
||||
_ <- scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL.toString => // Send the email
|
||||
for {
|
||||
failMsg <- Future {
|
||||
s"$InvalidJsonFormat The Json body should be the $PostConsentEmailJsonV310"
|
||||
}
|
||||
postConsentEmailJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentEmailJsonV310]
|
||||
}
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
postConsentEmailJson.email,
|
||||
Some("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield Future {
|
||||
status
|
||||
}
|
||||
case v if v == StrongCustomerAuthentication.SMS.toString =>
|
||||
for {
|
||||
failMsg <- Future {
|
||||
s"$InvalidJsonFormat The Json body should be the $PostConsentPhoneJsonV310"
|
||||
}
|
||||
postConsentPhoneJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentPhoneJsonV310]
|
||||
}
|
||||
phoneNumber = postConsentPhoneJson.phone_number
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
phoneNumber,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield Future {
|
||||
status
|
||||
}
|
||||
case v if v == StrongCustomerAuthentication.IMPLICIT.toString =>
|
||||
for {
|
||||
(consentImplicitSCA, callContext) <- NewStyle.function.getConsentImplicitSCA(user, callContext)
|
||||
status <- consentImplicitSCA.scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL => // Send the email
|
||||
NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
consentImplicitSCA.recipient,
|
||||
Some("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case v if v == StrongCustomerAuthentication.SMS =>
|
||||
NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
consentImplicitSCA.recipient,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case _ => Future {
|
||||
"Success"
|
||||
|
||||
//we need to check `skip_consent_sca_for_consumer_id_pairs` props, to see if we really need the SCA flow.
|
||||
//this is from callContext
|
||||
grantorConsumerId = callContext.map(_.consumer.toOption.map(_.consumerId.get)).flatten.getOrElse("Unknown")
|
||||
//this is from json body
|
||||
granteeConsumerId = consentJson.consumer_id.getOrElse("Unknown")
|
||||
|
||||
shouldSkipConsentScaForConsumerIdPair = APIUtil.skipConsentScaForConsumerIdPairs.contains(
|
||||
APIUtil.ConsumerIdPair(
|
||||
grantorConsumerId,
|
||||
granteeConsumerId
|
||||
))
|
||||
mappedConsent <- if (shouldSkipConsentScaForConsumerIdPair) {
|
||||
Future{
|
||||
MappedConsent.find(By(MappedConsent.mConsentId, createdConsent.consentId)).map(_.mStatus(ConsentStatus.ACCEPTED.toString).saveMe()).head
|
||||
}
|
||||
} else {
|
||||
val challengeText = s"Your consent challenge : ${challengeAnswer}, Application: $applicationText"
|
||||
scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL.toString => // Send the email
|
||||
for {
|
||||
failMsg <- Future {
|
||||
s"$InvalidJsonFormat The Json body should be the $PostConsentEmailJsonV310"
|
||||
}
|
||||
}} yield {
|
||||
status
|
||||
postConsentEmailJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentEmailJsonV310]
|
||||
}
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
postConsentEmailJson.email,
|
||||
Some("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield {
|
||||
createdConsent
|
||||
}
|
||||
case v if v == StrongCustomerAuthentication.SMS.toString =>
|
||||
for {
|
||||
failMsg <- Future {
|
||||
s"$InvalidJsonFormat The Json body should be the $PostConsentPhoneJsonV310"
|
||||
}
|
||||
postConsentPhoneJson <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[PostConsentPhoneJsonV310]
|
||||
}
|
||||
phoneNumber = postConsentPhoneJson.phone_number
|
||||
(status, callContext) <- NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
phoneNumber,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
} yield {
|
||||
createdConsent
|
||||
}
|
||||
case v if v == StrongCustomerAuthentication.IMPLICIT.toString =>
|
||||
for {
|
||||
(consentImplicitSCA, callContext) <- NewStyle.function.getConsentImplicitSCA(user, callContext)
|
||||
status <- consentImplicitSCA.scaMethod match {
|
||||
case v if v == StrongCustomerAuthentication.EMAIL => // Send the email
|
||||
NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.EMAIL,
|
||||
consentImplicitSCA.recipient,
|
||||
Some("OBP Consent Challenge"),
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case v if v == StrongCustomerAuthentication.SMS =>
|
||||
NewStyle.function.sendCustomerNotification(
|
||||
StrongCustomerAuthentication.SMS,
|
||||
consentImplicitSCA.recipient,
|
||||
None,
|
||||
challengeText,
|
||||
callContext
|
||||
)
|
||||
case _ => Future {
|
||||
"Success"
|
||||
}
|
||||
}} yield {
|
||||
createdConsent
|
||||
}
|
||||
case _ => Future {
|
||||
createdConsent
|
||||
}
|
||||
case _ => Future {
|
||||
"Success"
|
||||
}
|
||||
}
|
||||
} yield {
|
||||
(ConsentJsonV310(createdConsent.consentId, consentJWT, createdConsent.status), HttpCode.`201`(callContext))
|
||||
(ConsentJsonV310(mappedConsent.consentId, consentJWT, mappedConsent.status), HttpCode.`201`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,8 +31,7 @@ import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.ConsentAccessJson
|
||||
import code.api.util.APIUtil.{DateWithDay, DateWithSeconds, gitCommit, stringOrNull}
|
||||
import code.api.util._
|
||||
import code.api.v1_2_1.BankRoutingJsonV121
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.{LocationJsonV140, MetaJsonV140, transformToLocationFromV140, transformToMetaFromV140,
|
||||
TransactionRequestAccountJsonV140,ChallengeJsonV140}
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.{ChallengeJsonV140, LocationJsonV140, MetaJsonV140, TransactionRequestAccountJsonV140, transformToLocationFromV140, transformToMetaFromV140}
|
||||
import code.api.v2_0_0.TransactionRequestChargeJsonV200
|
||||
import code.api.v2_1_0.ResourceUserJSON
|
||||
import code.api.v3_0_0.JSONFactory300.{createLocationJson, createMetaJson, transformToAddressFromV300}
|
||||
@ -121,7 +120,8 @@ case class ConsentJsonV510(consent_id: String,
|
||||
jwt: String,
|
||||
status: String,
|
||||
consent_request_id: Option[String],
|
||||
scopes: Option[List[Role]])
|
||||
scopes: Option[List[Role]],
|
||||
consumer_id:String)
|
||||
|
||||
|
||||
case class ConsentInfoJsonV510(consent_id: String,
|
||||
@ -859,7 +859,8 @@ object JSONFactory510 extends CustomJsonFormats {
|
||||
consent.jsonWebToken,
|
||||
consent.status,
|
||||
Some(consent.consentRequestId),
|
||||
jsonWebTokenAsJValue.map(_.entitlements).toOption
|
||||
jsonWebTokenAsJValue.map(_.entitlements).toOption,
|
||||
consent.consumerId
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -303,6 +303,19 @@ trait Connector extends MdcLoggable {
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[Box[AmountOfMoney]] =Future{(Failure(setUnimplementedError(nameOf(getChallengeThreshold _))), callContext)}
|
||||
|
||||
//TODO. WIP
|
||||
def shouldRaiseConsentChallenge(
|
||||
bankId: String,
|
||||
accountId: String,
|
||||
viewId: String,
|
||||
consentRequestType: String,
|
||||
userId: String,
|
||||
username: String,
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[Box[(Boolean, String)]] = Future {
|
||||
(Failure(setUnimplementedError(nameOf(shouldRaiseConsentChallenge _))), callContext)
|
||||
}
|
||||
|
||||
def getPaymentLimit(
|
||||
bankId: String,
|
||||
accountId: String,
|
||||
|
||||
@ -9,7 +9,6 @@ object CommonsCaseClassGenerator extends App {
|
||||
//We need to check if the classCommons is existing or not.
|
||||
val allExistingClasses = getClassesFromPackage("com.openbankproject.commons.model")
|
||||
.filter(it =>it.getName.endsWith("Commons"))
|
||||
.toList
|
||||
|
||||
|
||||
val missingReturnModels: Set[ru.Type] = connectorDeclsMethodsReturnOBPRequiredType
|
||||
@ -17,7 +16,8 @@ object CommonsCaseClassGenerator extends App {
|
||||
.filter(it => {
|
||||
val symbol = it.typeSymbol
|
||||
val isAbstract = symbol.isAbstract
|
||||
isAbstract //We only need the commons classes for abstract class, eg: ProductAttributeCommons instead of ProductAttribute
|
||||
isAbstract && //We only need the commons classes for abstract class, eg: ProductAttributeCommons instead of ProductAttribute
|
||||
!it.toString.equals("Boolean") //Boolean is also abstract class, so we need to remove it.
|
||||
})
|
||||
.filterNot(it =>
|
||||
allExistingClasses.find(thisClass=> thisClass.toString.contains(s"${it.typeSymbol.name}Commons")).isDefined
|
||||
@ -37,9 +37,13 @@ object CommonsCaseClassGenerator extends App {
|
||||
}
|
||||
// private val str: String = ru.typeOf[Bank].decls.map(it => s"${it.name} :${it.typeSignature.typeSymbol.name}").mkString(", \n")
|
||||
private val caseClassStrings: Set[String] = missingReturnModels.map(mkClass)
|
||||
println("#################################Started########################################################################")
|
||||
caseClassStrings.foreach {
|
||||
println
|
||||
}
|
||||
println()
|
||||
|
||||
println("#################################Finished########################################################################")
|
||||
println("Please copy and compair the result to obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModel.scala")
|
||||
|
||||
System.exit(0)
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package code.bankconnectors.generator
|
||||
|
||||
import code.api.util.CodeGenerateUtils.createDocExample
|
||||
import code.api.util.{APIUtil, CallContext}
|
||||
import code.bankconnectors.Connector
|
||||
import code.bankconnectors.{Connector, LocalMappedConnector}
|
||||
import code.bankconnectors.vSept2018.KafkaMappedConnector_vSept2018
|
||||
import com.openbankproject.commons.util.ReflectUtils
|
||||
import org.apache.commons.io.FileUtils
|
||||
@ -21,7 +21,7 @@ import scala.reflect.runtime.{universe => ru}
|
||||
*/
|
||||
object ConnectorBuilderUtil {
|
||||
|
||||
def getClassesFromPackage(packageName: String): Seq[Class[_]] = {
|
||||
def getClassesFromPackage(packageName: String): List[Class[_]] = {
|
||||
val classLoader = Thread.currentThread().getContextClassLoader
|
||||
val path = packageName.replace('.', '/')
|
||||
val resources: Seq[URL] = classLoader.getResources(path).asScala.toSeq
|
||||
@ -36,7 +36,7 @@ object ConnectorBuilderUtil {
|
||||
} else {
|
||||
Seq.empty
|
||||
}
|
||||
}
|
||||
}.toList
|
||||
}
|
||||
|
||||
|
||||
@ -273,165 +273,170 @@ object ConnectorBuilderUtil {
|
||||
}
|
||||
}
|
||||
|
||||
val commonMethodNames = List(
|
||||
"getAdapterInfo",
|
||||
"getChallengeThreshold",
|
||||
"getChargeLevel",
|
||||
"getChargeLevelC2",
|
||||
"createChallenge",
|
||||
"getBank",
|
||||
"getBanks",
|
||||
"getBankAccountsForUser",
|
||||
"getBankAccountsBalances",
|
||||
"getBankAccountBalances",
|
||||
"getCoreBankAccounts",
|
||||
"getBankAccountsHeld",
|
||||
"getCounterpartyTrait",
|
||||
"getCounterpartyByCounterpartyId",
|
||||
"getCounterpartyByIban",
|
||||
"getCounterparties",
|
||||
"getTransactions",
|
||||
"getTransactionsCore",
|
||||
"getTransaction",
|
||||
"getPhysicalCardForBank",
|
||||
"deletePhysicalCardForBank",
|
||||
"getPhysicalCardsForBank",
|
||||
"createPhysicalCard",
|
||||
"updatePhysicalCard",
|
||||
"makePaymentv210",
|
||||
"makePaymentV400",
|
||||
"cancelPaymentV400",
|
||||
"createTransactionRequestv210",
|
||||
"getTransactionRequests210",
|
||||
"getTransactionRequestImpl",
|
||||
"createTransactionAfterChallengeV210",
|
||||
"updateBankAccount",
|
||||
"createBankAccount",
|
||||
"getBranch",
|
||||
"getBranches",
|
||||
"getAtm",
|
||||
"getAtms",
|
||||
"createTransactionAfterChallengev300",
|
||||
"makePaymentv300",
|
||||
"createTransactionRequestv300",
|
||||
"createCounterparty",
|
||||
"checkCustomerNumberAvailable",
|
||||
"createCustomer",
|
||||
"updateCustomerScaData",
|
||||
"updateCustomerCreditData",
|
||||
"updateCustomerGeneralData",
|
||||
"getCustomersByUserId",
|
||||
"getCustomerByCustomerId",
|
||||
"getCustomerByCustomerNumber",
|
||||
"getCustomerAddress",
|
||||
"createCustomerAddress",
|
||||
"updateCustomerAddress",
|
||||
"deleteCustomerAddress",
|
||||
"createTaxResidence",
|
||||
"getTaxResidence",
|
||||
"deleteTaxResidence",
|
||||
"getCustomers",
|
||||
"getCheckbookOrders",
|
||||
"getStatusOfCreditCardOrder",
|
||||
"createUserAuthContext",
|
||||
"createUserAuthContextUpdate",
|
||||
"deleteUserAuthContexts",
|
||||
"deleteUserAuthContextById",
|
||||
"getUserAuthContexts",
|
||||
"createOrUpdateProductAttribute",
|
||||
"getProduct",
|
||||
"getProducts",
|
||||
"getProductAttributeById",
|
||||
"getProductAttributesByBankAndCode",
|
||||
"deleteProductAttribute",
|
||||
"getAccountAttributeById",
|
||||
"createOrUpdateAccountAttribute",
|
||||
"createAccountAttributes",
|
||||
"getAccountAttributesByAccount",
|
||||
"createOrUpdateCardAttribute",
|
||||
"getCardAttributeById",
|
||||
"getCardAttributesFromProvider",
|
||||
"createAccountApplication",
|
||||
"getAllAccountApplication",
|
||||
"getAccountApplicationById",
|
||||
"updateAccountApplicationStatus",
|
||||
"getOrCreateProductCollection",
|
||||
"getProductCollection",
|
||||
"getOrCreateProductCollectionItem",
|
||||
"getProductCollectionItem",
|
||||
"getProductCollectionItemsTree",
|
||||
"createMeeting",
|
||||
"getMeetings",
|
||||
"getMeeting",
|
||||
"createOrUpdateKycCheck",
|
||||
"createOrUpdateKycDocument",
|
||||
"createOrUpdateKycMedia",
|
||||
"createOrUpdateKycStatus",
|
||||
"getKycChecks",
|
||||
"getKycDocuments",
|
||||
"getKycMedias",
|
||||
"getKycStatuses",
|
||||
"createMessage",
|
||||
"makeHistoricalPayment",
|
||||
"validateChallengeAnswer",
|
||||
//"getBankLegacy", // should not generate for Legacy methods
|
||||
//"getBanksLegacy", // should not generate for Legacy methods
|
||||
//"getBankAccountsForUserLegacy", // should not generate for Legacy methods
|
||||
//"getBankAccountLegacy", // should not generate for Legacy methods
|
||||
"getBankAccountByIban",
|
||||
"getBankAccountByRouting",
|
||||
"getBankAccounts",
|
||||
"checkBankAccountExists",
|
||||
//"getCoreBankAccountsLegacy", // should not generate for Legacy methods
|
||||
//"getBankAccountsHeldLegacy", // should not generate for Legacy methods
|
||||
//"checkBankAccountExistsLegacy", // should not generate for Legacy methods
|
||||
//"getCounterpartyByCounterpartyIdLegacy", // should not generate for Legacy methods
|
||||
//"getCounterpartiesLegacy", // should not generate for Legacy methods
|
||||
//"getTransactionsLegacy", // should not generate for Legacy methods
|
||||
//"getTransactionLegacy", // should not generate for Legacy methods
|
||||
//"createPhysicalCardLegacy", // should not generate for Legacy methods
|
||||
//"getCustomerByCustomerIdLegacy", // should not generate for Legacy methods
|
||||
//TODO WIP, need to fix the code to support the following methods
|
||||
// val commonMethodNames = LocalMappedConnector.callableMethods.keySet.toList
|
||||
|
||||
"createChallenges",
|
||||
"createTransactionRequestv400",
|
||||
"createTransactionRequestSepaCreditTransfersBGV1",
|
||||
"createTransactionRequestPeriodicSepaCreditTransfersBGV1",
|
||||
"getCustomersByCustomerPhoneNumber",
|
||||
"getTransactionAttributeById",
|
||||
"createOrUpdateCustomerAttribute",
|
||||
"createOrUpdateTransactionAttribute",
|
||||
"getCustomerAttributes",
|
||||
"getCustomerIdsByAttributeNameValues",
|
||||
"getCustomerAttributesForCustomers",
|
||||
"getTransactionIdsByAttributeNameValues",
|
||||
"getTransactionAttributes",
|
||||
"getBankAttributesByBank",
|
||||
"getCustomerAttributeById",
|
||||
"createDirectDebit",
|
||||
"deleteCustomerAttribute",
|
||||
"getPhysicalCardsForUser",
|
||||
"getChallengesByBasketId",
|
||||
"createChallengesC2",
|
||||
"createChallengesC3",
|
||||
"getChallenge",
|
||||
"getChallengesByTransactionRequestId",
|
||||
"getChallengesByConsentId",
|
||||
"validateAndCheckIbanNumber",
|
||||
"validateChallengeAnswerC2",
|
||||
"validateChallengeAnswerC3",
|
||||
"validateChallengeAnswerC4",
|
||||
"validateChallengeAnswerC5",
|
||||
"validateChallengeAnswerV2",
|
||||
"getCounterpartyByIbanAndBankAccountId",
|
||||
"getChargeValue",
|
||||
"saveTransactionRequestTransaction",
|
||||
"saveTransactionRequestChallenge",
|
||||
"getTransactionRequestTypes",
|
||||
"updateAccountLabel",
|
||||
"getProduct",
|
||||
"saveTransactionRequestStatusImpl",
|
||||
"getTransactionRequestTypeCharges"
|
||||
).distinct
|
||||
val commonMethodNames = List(
|
||||
"getAdapterInfo",
|
||||
"getChallengeThreshold",
|
||||
"getChargeLevel",
|
||||
"getChargeLevelC2",
|
||||
"createChallenge",
|
||||
"getBank",
|
||||
"getBanks",
|
||||
"getBankAccountsForUser",
|
||||
"getBankAccountsBalances",
|
||||
"getBankAccountBalances",
|
||||
"getCoreBankAccounts",
|
||||
"getBankAccountsHeld",
|
||||
"getCounterpartyTrait",
|
||||
"getCounterpartyByCounterpartyId",
|
||||
"getCounterpartyByIban",
|
||||
"getCounterparties",
|
||||
"getTransactions",
|
||||
"getTransactionsCore",
|
||||
"getTransaction",
|
||||
"getPhysicalCardForBank",
|
||||
"deletePhysicalCardForBank",
|
||||
"getPhysicalCardsForBank",
|
||||
"createPhysicalCard",
|
||||
"updatePhysicalCard",
|
||||
"makePaymentv210",
|
||||
"makePaymentV400",
|
||||
"cancelPaymentV400",
|
||||
"createTransactionRequestv210",
|
||||
"getTransactionRequests210",
|
||||
"getTransactionRequestImpl",
|
||||
"createTransactionAfterChallengeV210",
|
||||
"updateBankAccount",
|
||||
"createBankAccount",
|
||||
"getBranch",
|
||||
"getBranches",
|
||||
"getAtm",
|
||||
"getAtms",
|
||||
"createTransactionAfterChallengev300",
|
||||
"makePaymentv300",
|
||||
"createTransactionRequestv300",
|
||||
"createCounterparty",
|
||||
"checkCustomerNumberAvailable",
|
||||
"createCustomer",
|
||||
"updateCustomerScaData",
|
||||
"updateCustomerCreditData",
|
||||
"updateCustomerGeneralData",
|
||||
"getCustomersByUserId",
|
||||
"getCustomerByCustomerId",
|
||||
"getCustomerByCustomerNumber",
|
||||
"getCustomerAddress",
|
||||
"createCustomerAddress",
|
||||
"updateCustomerAddress",
|
||||
"deleteCustomerAddress",
|
||||
"createTaxResidence",
|
||||
"getTaxResidence",
|
||||
"deleteTaxResidence",
|
||||
"getCustomers",
|
||||
"getCheckbookOrders",
|
||||
"getStatusOfCreditCardOrder",
|
||||
"createUserAuthContext",
|
||||
"createUserAuthContextUpdate",
|
||||
"deleteUserAuthContexts",
|
||||
"deleteUserAuthContextById",
|
||||
"getUserAuthContexts",
|
||||
"createOrUpdateProductAttribute",
|
||||
"getProduct",
|
||||
"getProducts",
|
||||
"getProductAttributeById",
|
||||
"getProductAttributesByBankAndCode",
|
||||
"deleteProductAttribute",
|
||||
"getAccountAttributeById",
|
||||
"createOrUpdateAccountAttribute",
|
||||
"createAccountAttributes",
|
||||
"getAccountAttributesByAccount",
|
||||
"createOrUpdateCardAttribute",
|
||||
"getCardAttributeById",
|
||||
"getCardAttributesFromProvider",
|
||||
"createAccountApplication",
|
||||
"getAllAccountApplication",
|
||||
"getAccountApplicationById",
|
||||
"updateAccountApplicationStatus",
|
||||
"getOrCreateProductCollection",
|
||||
"getProductCollection",
|
||||
"getOrCreateProductCollectionItem",
|
||||
"getProductCollectionItem",
|
||||
"getProductCollectionItemsTree",
|
||||
"createMeeting",
|
||||
"getMeetings",
|
||||
"getMeeting",
|
||||
"createOrUpdateKycCheck",
|
||||
"createOrUpdateKycDocument",
|
||||
"createOrUpdateKycMedia",
|
||||
"createOrUpdateKycStatus",
|
||||
"getKycChecks",
|
||||
"getKycDocuments",
|
||||
"getKycMedias",
|
||||
"getKycStatuses",
|
||||
"createMessage",
|
||||
"makeHistoricalPayment",
|
||||
"validateChallengeAnswer",
|
||||
//"getBankLegacy", // should not generate for Legacy methods
|
||||
//"getBanksLegacy", // should not generate for Legacy methods
|
||||
//"getBankAccountsForUserLegacy", // should not generate for Legacy methods
|
||||
//"getBankAccountLegacy", // should not generate for Legacy methods
|
||||
"getBankAccountByIban",
|
||||
"getBankAccountByRouting",
|
||||
"getBankAccounts",
|
||||
"checkBankAccountExists",
|
||||
//"getCoreBankAccountsLegacy", // should not generate for Legacy methods
|
||||
//"getBankAccountsHeldLegacy", // should not generate for Legacy methods
|
||||
//"checkBankAccountExistsLegacy", // should not generate for Legacy methods
|
||||
//"getCounterpartyByCounterpartyIdLegacy", // should not generate for Legacy methods
|
||||
//"getCounterpartiesLegacy", // should not generate for Legacy methods
|
||||
//"getTransactionsLegacy", // should not generate for Legacy methods
|
||||
//"getTransactionLegacy", // should not generate for Legacy methods
|
||||
//"createPhysicalCardLegacy", // should not generate for Legacy methods
|
||||
//"getCustomerByCustomerIdLegacy", // should not generate for Legacy methods
|
||||
|
||||
"createChallenges",
|
||||
"createTransactionRequestv400",
|
||||
"createTransactionRequestSepaCreditTransfersBGV1",
|
||||
"createTransactionRequestPeriodicSepaCreditTransfersBGV1",
|
||||
"getCustomersByCustomerPhoneNumber",
|
||||
"getTransactionAttributeById",
|
||||
"createOrUpdateCustomerAttribute",
|
||||
"createOrUpdateTransactionAttribute",
|
||||
"getCustomerAttributes",
|
||||
"getCustomerIdsByAttributeNameValues",
|
||||
"getCustomerAttributesForCustomers",
|
||||
"getTransactionIdsByAttributeNameValues",
|
||||
"getTransactionAttributes",
|
||||
"getBankAttributesByBank",
|
||||
"getCustomerAttributeById",
|
||||
"createDirectDebit",
|
||||
"deleteCustomerAttribute",
|
||||
"getPhysicalCardsForUser",
|
||||
"getChallengesByBasketId",
|
||||
"createChallengesC2",
|
||||
"createChallengesC3",
|
||||
"getChallenge",
|
||||
"getChallengesByTransactionRequestId",
|
||||
"getChallengesByConsentId",
|
||||
"validateAndCheckIbanNumber",
|
||||
"validateChallengeAnswerC2",
|
||||
"validateChallengeAnswerC3",
|
||||
"validateChallengeAnswerC4",
|
||||
"validateChallengeAnswerC5",
|
||||
"validateChallengeAnswerV2",
|
||||
"getCounterpartyByIbanAndBankAccountId",
|
||||
"getChargeValue",
|
||||
"saveTransactionRequestTransaction",
|
||||
"saveTransactionRequestChallenge",
|
||||
"getTransactionRequestTypes",
|
||||
"updateAccountLabel",
|
||||
"getProduct",
|
||||
"saveTransactionRequestStatusImpl",
|
||||
"getTransactionRequestTypeCharges",
|
||||
"getAccountsHeld",
|
||||
"getAccountsHeldByUser",
|
||||
).distinct
|
||||
|
||||
/**
|
||||
* these connector methods have special parameter or return type
|
||||
@ -449,20 +454,51 @@ object ConnectorBuilderUtil {
|
||||
).distinct
|
||||
|
||||
val omitMethods = List(
|
||||
// "createOrUpdateAttributeDefinition", // should not be auto generated
|
||||
// "deleteAttributeDefinition", // should not be auto generated
|
||||
// "getAttributeDefinition", // should not be auto generated
|
||||
// "createStandingOrder", // should not be auto generated
|
||||
|
||||
"createOrUpdateAttributeDefinition", // should not be auto generated
|
||||
"deleteAttributeDefinition", // should not be auto generated
|
||||
"getAttributeDefinition", // should not be auto generated
|
||||
"createStandingOrder", // should not be auto generated
|
||||
//** the follow 5 methods should not be generated, should create manually
|
||||
// "dynamicEntityProcess",
|
||||
// "dynamicEndpointProcess",
|
||||
// "createDynamicEndpoint",
|
||||
// "getDynamicEndpoint",
|
||||
// "getDynamicEndpoints",
|
||||
|
||||
// "checkExternalUserCredentials",// this is not a standard connector method.
|
||||
// "checkExternalUserExists", // this is not a standard connector method.
|
||||
"dynamicEntityProcess",
|
||||
"dynamicEndpointProcess",
|
||||
"createDynamicEndpoint",
|
||||
"getDynamicEndpoint",
|
||||
"getDynamicEndpoints",
|
||||
"checkExternalUserCredentials",// this is not a standard connector method.
|
||||
"checkExternalUserExists", // this is not a standard connector method.
|
||||
"getBankAccountByRoutingLegacy",
|
||||
"getAccountRoutingsByScheme",
|
||||
"getAccountRouting",
|
||||
"getBankAccountsWithAttributes",
|
||||
"getBankSettlementAccounts",
|
||||
"getCountOfTransactionsFromAccountToCounterparty",
|
||||
"getStatus",
|
||||
"createOrUpdateBank",
|
||||
"createOrUpdateProduct",
|
||||
"getAllAtms",
|
||||
"getCurrentCurrencies",
|
||||
"getAgents",
|
||||
"getCustomersAtAllBanks",
|
||||
"createOrUpdateBankAttribute",
|
||||
"getBankAttribute",
|
||||
"createOrUpdateAtmAttribute",
|
||||
"getAtmAttribute",
|
||||
"getBankAttributeById",
|
||||
"getAtmAttributeById",
|
||||
"getUserAttributes",
|
||||
"getPersonalUserAttributes",
|
||||
"getNonPersonalUserAttributes",
|
||||
"getUserAttributesByUsers",
|
||||
"createOrUpdateUserAttribute",
|
||||
"getUserAttribute",
|
||||
"getUserAttributeById",
|
||||
"deleteUserAttribute",
|
||||
"getTransactionRequestIdsByAttributeNameValues",
|
||||
"sendCustomerNotification",
|
||||
"equals",
|
||||
"getAtmAttributesByAtm",
|
||||
"==",
|
||||
"!=",
|
||||
).distinct
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ object InOutCaseClassGenerator extends App {
|
||||
val allExistingClasses = getClassesFromPackage("com.openbankproject.commons.dto")
|
||||
|
||||
val code = connectorDeclsMethodsReturnOBPRequiredType
|
||||
.filter(it => allExistingClasses.toString.contains(s"OutBound${it.name.toString.capitalize} ")) //filter what we have implemented
|
||||
.filterNot(it => allExistingClasses.toString.contains(s"${it.name.toString.capitalize}")) //find what we have not implemented
|
||||
.map(it => {
|
||||
val returnType = it.returnType
|
||||
val tp = extractReturnModel(returnType)
|
||||
@ -34,9 +34,10 @@ object InOutCaseClassGenerator extends App {
|
||||
|case class InBound${it.name.toString.capitalize} (inboundAdapterCallContext: InboundAdapterCallContext, status: Status, data: $payload) extends InBoundTrait[$payload]
|
||||
""".stripMargin
|
||||
})
|
||||
println("#################################Started########################################################################")
|
||||
code.foreach(println)
|
||||
|
||||
println("#################################Finished########################################################################")
|
||||
println("Please copy and compair the result to obp-commons/src/main/scala/com/openbankproject/commons/model/CommonModel.scala")
|
||||
println("Please copy and compair the result to obp-commons/src/main/scala/com/openbankproject/commons/dto/JsonsTransfer.scala")
|
||||
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ class ServerCallback(val ch: Channel) extends DeliverCallback with MdcLoggable{
|
||||
))
|
||||
}
|
||||
//---------------- dynamic start -------------------please don't modify this line
|
||||
// ---------- created on 2024-10-28T12:26:57Z
|
||||
// ---------- created on 2025-01-14T11:53:01Z
|
||||
|
||||
} else if (obpMessageId.contains("get_adapter_info")) {
|
||||
val outBound = json.parse(message).extract[OutBoundGetAdapterInfo]
|
||||
@ -687,6 +687,48 @@ class ServerCallback(val ch: Channel) extends DeliverCallback with MdcLoggable{
|
||||
)).recoverWith {
|
||||
case e: Exception => Future(InBoundGetBankAccountsHeld(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status(e.getMessage, Nil),
|
||||
data = null
|
||||
))
|
||||
}
|
||||
} else if (obpMessageId.contains("get_accounts_held")) {
|
||||
val outBound = json.parse(message).extract[OutBoundGetAccountsHeld]
|
||||
val obpMappedResponse = code.bankconnectors.LocalMappedConnector.getAccountsHeld(outBound.bankId,outBound.user,None).map(_._1.head)
|
||||
|
||||
obpMappedResponse.map(response => InBoundGetAccountsHeld(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status("", Nil),
|
||||
data = response
|
||||
)).recoverWith {
|
||||
case e: Exception => Future(InBoundGetAccountsHeld(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status(e.getMessage, Nil),
|
||||
data = null
|
||||
))
|
||||
}
|
||||
} else if (obpMessageId.contains("get_accounts_held_by_user")) {
|
||||
val outBound = json.parse(message).extract[OutBoundGetAccountsHeldByUser]
|
||||
val obpMappedResponse = code.bankconnectors.LocalMappedConnector.getAccountsHeldByUser(outBound.user,None).map(_._1.head)
|
||||
|
||||
obpMappedResponse.map(response => InBoundGetAccountsHeldByUser(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status("", Nil),
|
||||
data = response
|
||||
)).recoverWith {
|
||||
case e: Exception => Future(InBoundGetAccountsHeldByUser(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
@ -1233,6 +1275,27 @@ class ServerCallback(val ch: Channel) extends DeliverCallback with MdcLoggable{
|
||||
)).recoverWith {
|
||||
case e: Exception => Future(InBoundGetTransactionRequestImpl(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status(e.getMessage, Nil),
|
||||
data = null
|
||||
))
|
||||
}
|
||||
} else if (obpMessageId.contains("get_transaction_request_types")) {
|
||||
val outBound = json.parse(message).extract[OutBoundGetTransactionRequestTypes]
|
||||
val obpMappedResponse = Future{code.bankconnectors.LocalMappedConnector.getTransactionRequestTypes(outBound.initiator,outBound.fromAccount,None).map(_._1).head}
|
||||
|
||||
obpMappedResponse.map(response => InBoundGetTransactionRequestTypes(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status("", Nil),
|
||||
data = response
|
||||
)).recoverWith {
|
||||
case e: Exception => Future(InBoundGetTransactionRequestTypes(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
@ -1450,7 +1513,7 @@ class ServerCallback(val ch: Channel) extends DeliverCallback with MdcLoggable{
|
||||
data = null
|
||||
))
|
||||
}
|
||||
} else if (obpMessageId.contains("create_transaction_after_challengev300")) {
|
||||
} else if (obpMessageId.contains("create_transaction_after_challengev300")) {
|
||||
val outBound = json.parse(message).extract[OutBoundCreateTransactionAfterChallengev300]
|
||||
val obpMappedResponse = code.bankconnectors.LocalMappedConnector.createTransactionAfterChallengev300(outBound.initiator,outBound.fromAccount,outBound.transReqId,outBound.transactionRequestType,None).map(_._1.head)
|
||||
|
||||
@ -2115,6 +2178,27 @@ class ServerCallback(val ch: Channel) extends DeliverCallback with MdcLoggable{
|
||||
)).recoverWith {
|
||||
case e: Exception => Future(InBoundCreateOrUpdateProductAttribute(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status(e.getMessage, Nil),
|
||||
data = null
|
||||
))
|
||||
}
|
||||
} else if (obpMessageId.contains("get_bank_attributes_by_bank")) {
|
||||
val outBound = json.parse(message).extract[OutBoundGetBankAttributesByBank]
|
||||
val obpMappedResponse = code.bankconnectors.LocalMappedConnector.getBankAttributesByBank(outBound.bankId,None).map(_._1.head)
|
||||
|
||||
obpMappedResponse.map(response => InBoundGetBankAttributesByBank(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
status = Status("", Nil),
|
||||
data = response
|
||||
)).recoverWith {
|
||||
case e: Exception => Future(InBoundGetBankAttributesByBank(
|
||||
|
||||
inboundAdapterCallContext = InboundAdapterCallContext(
|
||||
correlationId = outBound.outboundAdapterCallContext.correlationId
|
||||
),
|
||||
@ -3046,8 +3130,8 @@ class ServerCallback(val ch: Channel) extends DeliverCallback with MdcLoggable{
|
||||
data = null
|
||||
))
|
||||
}
|
||||
// ---------- created on 2024-10-28T12:26:57Z
|
||||
//---------------- dynamic end ---------------------please don't modify this line
|
||||
// ---------- created on 2025-01-14T11:53:01Z
|
||||
//---------------- dynamic end ---------------------please don't modify this line
|
||||
} else {
|
||||
Future {
|
||||
1
|
||||
|
||||
@ -7,7 +7,7 @@ import scala.language.postfixOps
|
||||
|
||||
object RabbitMQConnectorBuilder extends App {
|
||||
|
||||
buildMethods(commonMethodNames,
|
||||
buildMethods(commonMethodNames.diff(omitMethods),
|
||||
"src/main/scala/code/bankconnectors/rabbitmq/RabbitMQConnector_vOct2024.scala",
|
||||
methodName => s"""sendRequest[InBound]("obp_${StringHelpers.snakify(methodName)}", req, callContext)""")
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ trait RabbitMQConnector_vOct2024 extends Connector with MdcLoggable {
|
||||
val connectorName = "rabbitmq_vOct2024"
|
||||
|
||||
//---------------- dynamic start -------------------please don't modify this line
|
||||
// ---------- created on 2024-12-10T10:42:33Z
|
||||
// ---------- created on 2025-01-14T19:52:36Z
|
||||
|
||||
messageDocs += getAdapterInfoDoc
|
||||
def getAdapterInfoDoc = MessageDoc(
|
||||
@ -1154,6 +1154,79 @@ trait RabbitMQConnector_vOct2024 extends Connector with MdcLoggable {
|
||||
response.map(convertToTuple[List[AccountHeld]](callContext))
|
||||
}
|
||||
|
||||
messageDocs += getAccountsHeldDoc
|
||||
def getAccountsHeldDoc = MessageDoc(
|
||||
process = "obp.getAccountsHeld",
|
||||
messageFormat = messageFormat,
|
||||
description = "Get Accounts Held",
|
||||
outboundTopic = None,
|
||||
inboundTopic = None,
|
||||
exampleOutboundMessage = (
|
||||
OutBoundGetAccountsHeld(outboundAdapterCallContext=MessageDocsSwaggerDefinitions.outboundAdapterCallContext,
|
||||
bankId=BankId(bankIdExample.value),
|
||||
user= UserCommons(userPrimaryKey=UserPrimaryKey(123),
|
||||
userId=userIdExample.value,
|
||||
idGivenByProvider="string",
|
||||
provider=providerExample.value,
|
||||
emailAddress=emailAddressExample.value,
|
||||
name=userNameExample.value,
|
||||
createdByConsentId=Some("string"),
|
||||
createdByUserInvitationId=Some("string"),
|
||||
isDeleted=Some(true),
|
||||
lastMarketingAgreementSignedDate=Some(toDate(dateExample))))
|
||||
),
|
||||
exampleInboundMessage = (
|
||||
InBoundGetAccountsHeld(inboundAdapterCallContext=MessageDocsSwaggerDefinitions.inboundAdapterCallContext,
|
||||
status=MessageDocsSwaggerDefinitions.inboundStatus,
|
||||
data=List( BankIdAccountId(bankId=BankId(bankIdExample.value),
|
||||
accountId=AccountId(accountIdExample.value))))
|
||||
),
|
||||
adapterImplementation = Some(AdapterImplementation("- Core", 1))
|
||||
)
|
||||
|
||||
override def getAccountsHeld(bankId: BankId, user: User, callContext: Option[CallContext]): OBPReturnType[Box[List[BankIdAccountId]]] = {
|
||||
import com.openbankproject.commons.dto.{InBoundGetAccountsHeld => InBound, OutBoundGetAccountsHeld => OutBound}
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).orNull, bankId, user)
|
||||
val response: Future[Box[InBound]] = sendRequest[InBound]("obp_get_accounts_held", req, callContext)
|
||||
response.map(convertToTuple[List[BankIdAccountId]](callContext))
|
||||
}
|
||||
|
||||
messageDocs += getAccountsHeldByUserDoc
|
||||
def getAccountsHeldByUserDoc = MessageDoc(
|
||||
process = "obp.getAccountsHeldByUser",
|
||||
messageFormat = messageFormat,
|
||||
description = "Get Accounts Held By User",
|
||||
outboundTopic = None,
|
||||
inboundTopic = None,
|
||||
exampleOutboundMessage = (
|
||||
OutBoundGetAccountsHeldByUser(outboundAdapterCallContext=MessageDocsSwaggerDefinitions.outboundAdapterCallContext,
|
||||
user= UserCommons(userPrimaryKey=UserPrimaryKey(123),
|
||||
userId=userIdExample.value,
|
||||
idGivenByProvider="string",
|
||||
provider=providerExample.value,
|
||||
emailAddress=emailAddressExample.value,
|
||||
name=userNameExample.value,
|
||||
createdByConsentId=Some("string"),
|
||||
createdByUserInvitationId=Some("string"),
|
||||
isDeleted=Some(true),
|
||||
lastMarketingAgreementSignedDate=Some(toDate(dateExample))))
|
||||
),
|
||||
exampleInboundMessage = (
|
||||
InBoundGetAccountsHeldByUser(inboundAdapterCallContext=MessageDocsSwaggerDefinitions.inboundAdapterCallContext,
|
||||
status=MessageDocsSwaggerDefinitions.inboundStatus,
|
||||
data=List( BankIdAccountId(bankId=BankId(bankIdExample.value),
|
||||
accountId=AccountId(accountIdExample.value))))
|
||||
),
|
||||
adapterImplementation = Some(AdapterImplementation("- Core", 1))
|
||||
)
|
||||
|
||||
override def getAccountsHeldByUser(user: User, callContext: Option[CallContext]): OBPReturnType[Box[List[BankIdAccountId]]] = {
|
||||
import com.openbankproject.commons.dto.{InBoundGetAccountsHeldByUser => InBound, OutBoundGetAccountsHeldByUser => OutBound}
|
||||
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).orNull, user)
|
||||
val response: Future[Box[InBound]] = sendRequest[InBound]("obp_get_accounts_held_by_user", req, callContext)
|
||||
response.map(convertToTuple[List[BankIdAccountId]](callContext))
|
||||
}
|
||||
|
||||
messageDocs += checkBankAccountExistsDoc
|
||||
def checkBankAccountExistsDoc = MessageDoc(
|
||||
process = "obp.checkBankAccountExists",
|
||||
@ -6997,8 +7070,8 @@ trait RabbitMQConnector_vOct2024 extends Connector with MdcLoggable {
|
||||
response.map(convertToTuple[Boolean](callContext))
|
||||
}
|
||||
|
||||
// ---------- created on 2024-12-10T10:42:33Z
|
||||
//---------------- dynamic end ---------------------please don't modify this line
|
||||
// ---------- created on 2025-01-14T19:52:36Z
|
||||
//---------------- dynamic end ---------------------please don't modify this line
|
||||
|
||||
private val availableOperation = DynamicEntityOperation.values.map(it => s""""$it"""").mkString("[", ", ", "]")
|
||||
|
||||
|
||||
@ -339,7 +339,7 @@ case class BankAccountExtended(val bankAccount: BankAccount) extends MdcLoggable
|
||||
if(APIUtil.hasAccountAccess(view, BankIdAccountId(bankId, accountId), user, callContext)) {
|
||||
for {
|
||||
(transactions, callContext) <- Connector.connector.vend.getTransactions(bankId, accountId, callContext, queryParams) map {
|
||||
x => (unboxFullOrFail(x._1, callContext, InvalidConnectorResponse, 400), x._2)
|
||||
x => (unboxFullOrFail(x._1, callContext, InvalidConnectorResponseForGetTransactions, 400), x._2)
|
||||
}
|
||||
} yield {
|
||||
view.moderateTransactionsWithSameAccount(bank, transactions) match {
|
||||
|
||||
241
obp-api/src/main/scala/code/snippet/VrpConsentCreation.scala
Normal file
241
obp-api/src/main/scala/code/snippet/VrpConsentCreation.scala
Normal file
@ -0,0 +1,241 @@
|
||||
/**
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2019, TESOBE GmbH.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH.
|
||||
Osloer Strasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
|
||||
*/
|
||||
package code.snippet
|
||||
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ErrorMessages.InvalidJsonFormat
|
||||
import code.api.util.{APIUtil, CustomJsonFormats}
|
||||
import code.api.v5_1_0.{APIMethods510, ConsentJsonV510}
|
||||
import code.api.v5_0_0.{APIMethods500, ConsentJsonV500, ConsentRequestResponseJson}
|
||||
import code.api.v3_1_0.{APIMethods310, ConsentChallengeJsonV310, ConsumerJsonV310}
|
||||
import code.consent.{ConsentStatus}
|
||||
import code.util.Helper.{MdcLoggable, ObpS}
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import net.liftweb.http.{GetRequest, PostRequest, RequestVar, S, SHtml}
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json.Formats
|
||||
import net.liftweb.util.Helpers._
|
||||
|
||||
class VrpConsentCreation extends MdcLoggable with RestHelper with APIMethods510 with APIMethods500 with APIMethods310 {
|
||||
protected implicit override def formats: Formats = CustomJsonFormats.formats
|
||||
|
||||
private object otpValue extends RequestVar("123456")
|
||||
|
||||
def confirmVrpConsentRequest = {
|
||||
getConsentRequest match {
|
||||
case Left(error) => {
|
||||
S.error(error._1)
|
||||
"#confirm-vrp-consent-request-form-title *" #> s"Please confirm or deny the following consent request:" &
|
||||
"#confirm-vrp-consent-request-response-json *" #> s"""""" &
|
||||
"type=submit" #> ""
|
||||
}
|
||||
case Right(response) => {
|
||||
tryo {json.parse(response).extract[ConsentRequestResponseJson]} match {
|
||||
case Full(consentRequestResponseJson) =>
|
||||
"#confirm-vrp-consent-request-form-title *" #> s"Please confirm or deny the following consent request:" &
|
||||
"#confirm-vrp-consent-request-response-json *" #> s"""${json.prettyRender(json.Extraction.decompose(consentRequestResponseJson.payload))}""" &
|
||||
"#confirm-vrp-consent-request-confirm-submit-button" #> SHtml.onSubmitUnit(confirmConsentRequestProcess)
|
||||
case _ =>
|
||||
"#confirm-vrp-consent-request-form-title *" #> s"Please confirm or deny the following consent request:" &
|
||||
"#confirm-vrp-consent-request-response-json *" #>
|
||||
s"""$InvalidJsonFormat The Json body should be the $ConsentRequestResponseJson.
|
||||
|Please check `Get Consent Request` endpoint separately! """.stripMargin &
|
||||
"type=submit" #> ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def confirmVrpConsent = {
|
||||
"#otp-value" #> SHtml.textElem(otpValue) &
|
||||
"type=submit" #> SHtml.onSubmitUnit(confirmVrpConsentProcess)
|
||||
}
|
||||
|
||||
private def confirmConsentRequestProcess() ={
|
||||
//1st: we need to call `Create Consent By CONSENT_REQUEST_ID (IMPLICIT)`, this will send OTP to account owner.
|
||||
callCreateConsentByConsentRequestIdImplicit match {
|
||||
case Left(error) => {
|
||||
S.error(error._1)
|
||||
}
|
||||
case Right(response) => {
|
||||
tryo {json.parse(response).extract[ConsentJsonV500]} match {
|
||||
case Full(consentJsonV500) =>
|
||||
//2nd: we need to redirect to confirm page to fill the OTP
|
||||
S.redirectTo(
|
||||
s"/confirm-vrp-consent?CONSENT_ID=${consentJsonV500.consent_id}"
|
||||
)
|
||||
case _ =>
|
||||
S.error(s"$InvalidJsonFormat The Json body should be the $ConsentJsonV500. " +
|
||||
s"Please check `Create Consent By CONSENT_REQUEST_ID (IMPLICIT) !")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def callAnswerConsentChallenge: Either[(String, Int), String] = {
|
||||
|
||||
val requestParam = List(
|
||||
ObpS.param("CONSENT_ID")
|
||||
)
|
||||
|
||||
if(requestParam.count(_.isDefined) < requestParam.size) {
|
||||
return Left(("There are one or many mandatory request parameter not present, please check request parameter: CONSENT_ID", 500))
|
||||
}
|
||||
|
||||
val pathOfEndpoint = List(
|
||||
"banks",
|
||||
APIUtil.defaultBankId,//we do not need to get this from URL, it will be easier for the developer.
|
||||
"consents",
|
||||
ObpS.param("CONSENT_ID")openOr(""),
|
||||
"challenge"
|
||||
)
|
||||
|
||||
val requestBody = s"""{"answer":"${otpValue.get}"}"""
|
||||
val authorisationsResult = callEndpoint(Implementations3_1_0.answerConsentChallenge, pathOfEndpoint, PostRequest, requestBody)
|
||||
|
||||
authorisationsResult
|
||||
|
||||
}
|
||||
|
||||
private def callGetConsentByConsentId(consentId: String): Either[(String, Int), String] = {
|
||||
|
||||
val pathOfEndpoint = List(
|
||||
"user",
|
||||
"current",
|
||||
"consents",
|
||||
consentId,
|
||||
)
|
||||
|
||||
val authorisationsResult = callEndpoint(Implementations5_1_0.getConsentByConsentId, pathOfEndpoint, GetRequest)
|
||||
|
||||
authorisationsResult
|
||||
}
|
||||
|
||||
private def callGetConsumer(consumerId: String): Either[(String, Int), String] = {
|
||||
|
||||
val pathOfEndpoint = List(
|
||||
"management",
|
||||
"consumers",
|
||||
consumerId,
|
||||
)
|
||||
|
||||
val authorisationsResult = callEndpoint(Implementations5_1_0.getConsumer, pathOfEndpoint, GetRequest)
|
||||
|
||||
authorisationsResult
|
||||
}
|
||||
|
||||
private def callCreateConsentByConsentRequestIdImplicit: Either[(String, Int), String] = {
|
||||
|
||||
val requestParam = List(
|
||||
ObpS.param("CONSENT_REQUEST_ID"),
|
||||
)
|
||||
if(requestParam.count(_.isDefined) < requestParam.size) {
|
||||
return Left(("Parameter CONSENT_REQUEST_ID is missing, please set it in the URL", 500))
|
||||
}
|
||||
|
||||
val pathOfEndpoint = List(
|
||||
"consumer",
|
||||
"consent-requests",
|
||||
ObpS.param("CONSENT_REQUEST_ID")openOr(""),
|
||||
"IMPLICIT",
|
||||
"consents",
|
||||
)
|
||||
|
||||
val requestBody = s"""{}"""
|
||||
val authorisationsResult = callEndpoint(Implementations5_0_0.createConsentByConsentRequestIdImplicit, pathOfEndpoint, PostRequest, requestBody)
|
||||
|
||||
authorisationsResult
|
||||
}
|
||||
|
||||
private def confirmVrpConsentProcess() ={
|
||||
//1st: we need to answer challenge and create the consent properly.
|
||||
callAnswerConsentChallenge match {
|
||||
case Left(error) => S.error(error._1)
|
||||
case Right(response) => {
|
||||
tryo {json.parse(response).extract[ConsentChallengeJsonV310]} match {
|
||||
case Full(consentChallengeJsonV310) if (consentChallengeJsonV310.status.equals(ConsentStatus.ACCEPTED.toString)) =>
|
||||
//2nd: we need to call getConsent by consentId --> get the consumerId
|
||||
callGetConsentByConsentId(consentChallengeJsonV310.consent_id) match {
|
||||
case Left(error) => S.error(error._1)
|
||||
case Right(response) => {
|
||||
tryo {json.parse(response).extract[ConsentJsonV510]} match {
|
||||
case Full(consentJsonV510) =>
|
||||
//3rd: get consumer by consumerId
|
||||
callGetConsumer(consentJsonV510.consumer_id) match {
|
||||
case Left(error) => S.error(error._1)
|
||||
case Right(response) => {
|
||||
tryo {json.parse(response).extract[ConsumerJsonV310]} match {
|
||||
case Full(consumerJsonV310) =>
|
||||
//4th: get the redirect url.
|
||||
val redirectURL = consumerJsonV310.redirect_url.trim
|
||||
S.redirectTo(s"$redirectURL?CONSENT_REQUEST_ID=${consentJsonV510.consent_request_id.getOrElse("")}")
|
||||
case _ =>
|
||||
S.error(s"$InvalidJsonFormat The Json body should be the $ConsumerJsonV310. " +
|
||||
s"Please check `Get Consumer` !")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case _ =>
|
||||
S.error(s"$InvalidJsonFormat The Json body should be the $ConsentJsonV510. " +
|
||||
s"Please check `Get Consent By Consent Id` !")
|
||||
}
|
||||
}
|
||||
}
|
||||
case Full(consentChallengeJsonV310) =>
|
||||
S.error(s"Current SCA status is ${consentChallengeJsonV310.status}. Please double check OTP value.")
|
||||
case _ => S.error(s"$InvalidJsonFormat The Json body should be the $ConsentChallengeJsonV310. " +
|
||||
s"Please check `Answer Consent Challenge` ! ")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def getConsentRequest: Either[(String, Int), String] = {
|
||||
|
||||
val requestParam = List(
|
||||
ObpS.param("CONSENT_REQUEST_ID"),
|
||||
)
|
||||
|
||||
if(requestParam.count(_.isDefined) < requestParam.size) {
|
||||
return Left(("Parameter CONSENT_REQUEST_ID is missing, please set it in the URL", 500))
|
||||
}
|
||||
|
||||
val pathOfEndpoint = List(
|
||||
"consumer",
|
||||
"consent-requests",
|
||||
ObpS.param("CONSENT_REQUEST_ID")openOr("")
|
||||
)
|
||||
|
||||
val authorisationsResult = callEndpoint(Implementations5_0_0.getConsentRequest, pathOfEndpoint, GetRequest)
|
||||
|
||||
authorisationsResult
|
||||
}
|
||||
|
||||
}
|
||||
@ -212,18 +212,22 @@ object Helper extends Loggable {
|
||||
*/
|
||||
def isValidInternalRedirectUrl(url: String) : Boolean = {
|
||||
//set the default value is "/" and "/oauth/authorize"
|
||||
val validUrls = List(
|
||||
val internalRedirectUrlsWhiteList = List(
|
||||
"/","/oauth/authorize","/consumer-registration",
|
||||
"/dummy-user-tokens","/create-sandbox-account",
|
||||
"/add-user-auth-context-update-request","/otp",
|
||||
"/terms-and-conditions", "/privacy-policy"
|
||||
"/terms-and-conditions", "/privacy-policy",
|
||||
"/confirm-vrp-consent-request",
|
||||
"/confirm-vrp-consent",
|
||||
"/consent-screen",
|
||||
"/consent",
|
||||
)
|
||||
|
||||
//case1: OBP-API login: url = "/"
|
||||
//case2: API-Explore oauth login: url = "/oauth/authorize?oauth_token=V0JTCDYXWUNTXDZ3VUDNM1HE3Q1PZR2WJ4PURXQA&logUserOut=false"
|
||||
val extractCleanURL = StringUtils.substringBefore(url, "?")
|
||||
|
||||
validUrls.contains(extractCleanURL)
|
||||
internalRedirectUrlsWhiteList.contains(extractCleanURL)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
50
obp-api/src/main/webapp/confirm-vrp-consent-request.html
Normal file
50
obp-api/src/main/webapp/confirm-vrp-consent-request.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!--
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2025, TESOBE GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH
|
||||
Osloerstrasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
by
|
||||
Hongwei Zhang : Hongwei AT tesobe DOT com
|
||||
|
||||
-->
|
||||
|
||||
<div data-lift="surround?with=default;at=content">
|
||||
<div id="confirm-vrp-consent-request-div" data-lift="VrpConsentCreation.confirmVrpConsentRequest">
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<h3 id="confirm-vrp-consent-request-form-title">Please check the VRP Consent Request: </h3>
|
||||
</div>
|
||||
|
||||
<pre id="confirm-vrp-consent-request-response-json">
|
||||
|
||||
</pre>
|
||||
<div class="row">
|
||||
<input id="confirm-vrp-consent-request-confirm-submit-button" class="btn btn-danger pull-right" type="submit" value="Confirm"
|
||||
tabindex="0"/>
|
||||
<a id="confirm-vrp-consent-request-deny-submit-button" class="btn btn-danger pull-right" href="/">Deny</span></a>
|
||||
</div>
|
||||
<br>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
49
obp-api/src/main/webapp/confirm-vrp-consent.html
Normal file
49
obp-api/src/main/webapp/confirm-vrp-consent.html
Normal file
@ -0,0 +1,49 @@
|
||||
<!--
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2017, TESOBE GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH
|
||||
Osloerstrasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
by
|
||||
Simon Redfern : simon AT tesobe DOT com
|
||||
Sebastian Henschel : sebastian AT tesobe DOT com
|
||||
-->
|
||||
|
||||
<div data-lift="surround?with=default;at=content">
|
||||
<div id="confirm-user-auth-context-update-request-div" data-lift="VrpConsentCreation.confirmVrpConsent">
|
||||
<form class="login" method="post">
|
||||
<div class="form-group">
|
||||
<h3>Please enter the One Time Password (OTP) that we just sent to you</h3>
|
||||
<p>Please check your phone or email for the value to enter.</p>
|
||||
<input class="form-control" id="otp-value" type="text" value="123" tabindex="0" autofocus
|
||||
autocomplete="off" aria-label="One Time Password"/>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<input id="authorise-submit-button" class="btn btn-danger pull-right" type="submit" value="Submit"
|
||||
tabindex="0"/>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -437,4 +437,8 @@ input{
|
||||
color: #333333;
|
||||
line-height: 24px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#confirm-vrp-consent-request-deny-submit-button {
|
||||
background: red;
|
||||
}
|
||||
@ -199,7 +199,7 @@ class VRPConsentRequestTest extends V510ServerSetup with PropsReset{
|
||||
val getConsentByRequestResponse = makeGetRequest(getConsentByRequestIdUrl(consentRequestId))
|
||||
Then("We should get a 200")
|
||||
getConsentByRequestResponse.code should equal(200)
|
||||
val getConsentByRequestResponseJson = getConsentByRequestResponse.body.extract[ConsentJsonV510]
|
||||
val getConsentByRequestResponseJson = getConsentByRequestResponse.body.extract[ConsentJsonV500]
|
||||
getConsentByRequestResponseJson.consent_request_id.head should be(consentRequestId)
|
||||
getConsentByRequestResponseJson.status should be(ConsentStatus.ACCEPTED.toString)
|
||||
|
||||
@ -280,7 +280,7 @@ class VRPConsentRequestTest extends V510ServerSetup with PropsReset{
|
||||
val getConsentByRequestResponse = makeGetRequest(getConsentByRequestIdUrl(consentRequestId))
|
||||
Then("We should get a 200")
|
||||
getConsentByRequestResponse.code should equal(200)
|
||||
val getConsentByRequestResponseJson = getConsentByRequestResponse.body.extract[ConsentJsonV510]
|
||||
val getConsentByRequestResponseJson = getConsentByRequestResponse.body.extract[ConsentJsonV500]
|
||||
getConsentByRequestResponseJson.consent_request_id.head should be(consentRequestId)
|
||||
getConsentByRequestResponseJson.status should be(ConsentStatus.ACCEPTED.toString)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
||||
### Most recent changes at top of file
|
||||
```
|
||||
Date Commit Action
|
||||
24/01/2025 ad68f054 Added props skip_consent_sca_for_consumer_id_pairs .
|
||||
03/02/2024 7bcb6bc5 Added props oauth2.keycloak.source_of_truth, default is false.
|
||||
oauth2.keycloak.source_of_truth = true turns sync ON.
|
||||
It is used to sync IAM of OBP-API and IAM of Keycloak.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user