From a55824fbc33fc2e7d7f73ac24ec2bacb54dddbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Wed, 13 Aug 2025 09:54:19 +0200 Subject: [PATCH 1/3] feature/Add query param withBalance at BG endpoint Read Account Details --- .../AccountInformationServiceAISApi.scala | 27 ++++++++++++++++++- .../v1_3/JSONFactory_BERLIN_GROUP_1_3.scala | 18 +++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) 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 bba14b21c..d3684b268 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 @@ -1036,17 +1036,27 @@ Give detailed information about the addressed account together with balance info cc => for { (Full(u), callContext) <- authenticatedAccess(cc) + withBalanceParam <- NewStyle.function.tryons(s"$InvalidUrlParameters withBalance parameter can only take two values: TRUE or FALSE!", 400, callContext) { + val withBalance = APIUtil.getHttpRequestUrlParam(cc.url, "withBalance") + if (withBalance.isEmpty) Some(false) else Some(withBalance.toBoolean) + } _ <- passesPsd2Aisp(callContext) (account: BankAccount, callContext) <- NewStyle.function.getBankAccountByAccountId(AccountId(accountId), callContext) (canReadBalancesAccounts, callContext) <- NewStyle.function.getAccountCanReadBalancesOfBerlinGroup(u, callContext) (canReadTransactionsAccounts, callContext) <- NewStyle.function.getAccountCanReadTransactionsOfBerlinGroup(u, callContext) _ <- checkAccountAccess(ViewId(SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID), u, account, callContext) + (accountBalances, callContext) <- code.api.util.newstyle.BankAccountBalanceNewStyle.getBankAccountBalances( + AccountId(accountId), + callContext + ) } yield { ( JSONFactory_BERLIN_GROUP_1_3.createAccountDetailsJson( account, canReadBalancesAccounts, canReadTransactionsAccounts, + withBalanceParam, + accountBalances, u ), callContext @@ -1105,8 +1115,23 @@ respectively the OAuth2 access token. (canReadBalancesAccounts, callContext) <- NewStyle.function.getAccountCanReadBalancesOfBerlinGroup(u, callContext) (canReadTransactionsAccounts, callContext) <- NewStyle.function.getAccountCanReadTransactionsOfBerlinGroup(u, callContext) _ <- checkAccountAccess(ViewId(SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID), u, account, callContext) + withBalanceParam <- NewStyle.function.tryons(s"$InvalidUrlParameters withBalance parameter can only take two values: TRUE or FALSE!", 400, callContext) { + val withBalance = APIUtil.getHttpRequestUrlParam(cc.url, "withBalance") + if (withBalance.isEmpty) Some(false) else Some(withBalance.toBoolean) + } + (accountBalances, callContext) <- code.api.util.newstyle.BankAccountBalanceNewStyle.getBankAccountBalances( + AccountId(accountId), + callContext + ) } yield { - (JSONFactory_BERLIN_GROUP_1_3.createCardAccountDetailsJson(account, canReadBalancesAccounts, canReadTransactionsAccounts, u), callContext) + (JSONFactory_BERLIN_GROUP_1_3.createCardAccountDetailsJson( + account, + canReadBalancesAccounts, + canReadTransactionsAccounts, + withBalanceParam, + accountBalances, + u + ), callContext) } } } diff --git a/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala b/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala index f7857a00d..52d78bfb3 100644 --- a/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala +++ b/obp-api/src/main/scala/code/api/berlin/group/v1_3/JSONFactory_BERLIN_GROUP_1_3.scala @@ -93,6 +93,7 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats with MdcLoggable{ product: String, cashAccountType: String, name: Option[String], + balances: Option[List[CoreAccountBalanceJson]] = None, _links: AccountDetailsLinksJsonV13, ) @@ -407,14 +408,18 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats with MdcLoggable{ def createCardAccountDetailsJson(bankAccount: BankAccount, canReadBalancesAccounts: List[BankIdAccountId], canReadTransactionsAccounts: List[BankIdAccountId], + withBalanceParam: Option[Boolean], + balances: List[BankAccountBalanceTrait], user: User): CardAccountDetailsJsonV13 = { - val accountDetailsJsonV13 = createAccountDetailsJson(bankAccount, canReadBalancesAccounts, canReadTransactionsAccounts, user) + val accountDetailsJsonV13 = createAccountDetailsJson(bankAccount, canReadBalancesAccounts, canReadTransactionsAccounts, withBalanceParam, balances, user) CardAccountDetailsJsonV13(accountDetailsJsonV13.account) } def createAccountDetailsJson(bankAccount: BankAccount, canReadBalancesAccounts: List[BankIdAccountId], canReadTransactionsAccounts: List[BankIdAccountId], + withBalanceParam: Option[Boolean], + balances: List[BankAccountBalanceTrait], user: User): AccountDetailsJsonV13 = { val (iBan: String, bBan: String) = getIbanAndBban(bankAccount) val commonPath = s"${OBP_BERLIN_GROUP_1_3.apiVersion.urlPrefix}/${OBP_BERLIN_GROUP_1_3.version}/accounts/${bankAccount.accountId.value}" @@ -423,7 +428,15 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats with MdcLoggable{ val transactionRef = LinkHrefJson(s"/$commonPath/transactions") val canReadTransactions = canReadTransactionsAccounts.map(_.accountId.value).contains(bankAccount.accountId.value) val cashAccountType = bankAccount.attributes.getOrElse(Nil).filter(_.name== "cashAccountType").map(_.value).headOption.getOrElse("") - + val accountBalances = if (withBalanceParam.contains(true)) { + Some(balances.filter(_.accountId.equals(bankAccount.accountId)).flatMap(balance => (List(CoreAccountBalanceJson( + balanceAmount = AmountOfMoneyV13(bankAccount.currency, balance.balanceAmount.toString()), + balanceType = balance.balanceType, + lastChangeDateTime = balance.lastChangeDateTime.map(APIUtil.DateWithMsAndTimeZoneOffset.format(_)) + ))))) + } else { + None + } val account = AccountJsonV13( resourceId = bankAccount.accountId.value, @@ -432,6 +445,7 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats with MdcLoggable{ name = if(APIUtil.getPropsAsBoolValue("BG_v1312_show_account_name", defaultValue = true)) Some(bankAccount.name) else None, cashAccountType = cashAccountType, product = bankAccount.accountType, + balances = if(canReadBalances) accountBalances else None, _links = AccountDetailsLinksJsonV13( balances = if (canReadBalances) Some(balanceRef) else None, transactions = if (canReadTransactions) Some(transactionRef) else None, From 01393cec64ee5e231954fc9a1100444d5d310c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Thu, 14 Aug 2025 14:32:34 +0200 Subject: [PATCH 2/3] feature/Add query param cbs_user_id at Get Consents endpoint --- .../src/main/scala/code/api/util/APIUtil.scala | 7 +++++-- .../src/main/scala/code/api/util/OBPParam.scala | 1 + .../code/api/v5_1_0/JSONFactory5.1.0.scala | 16 +++++++++++++--- .../main/scala/code/consent/MappedConsent.scala | 17 +++++++++++++++-- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/obp-api/src/main/scala/code/api/util/APIUtil.scala b/obp-api/src/main/scala/code/api/util/APIUtil.scala index 7e6e9561e..2fade7e73 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -1147,6 +1147,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ case "iss" => Full(OBPIss(values.head)) case "consent_id" => Full(OBPConsentId(values.head)) case "user_id" => Full(OBPUserId(values.head)) + case "cbs_user_id" => Full(CBSUserId(values.head)) case "bank_id" => Full(OBPBankId(values.head)) case "account_id" => Full(OBPAccountId(values.head)) case "url" => Full(OBPUrl(values.head)) @@ -1198,6 +1199,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ iss <- getHttpParamValuesByName(httpParams,"iss") consentId <- getHttpParamValuesByName(httpParams,"consent_id") userId <- getHttpParamValuesByName(httpParams, "user_id") + cbsUserId <- getHttpParamValuesByName(httpParams, "cbs_user_id") bankId <- getHttpParamValuesByName(httpParams, "bank_id") accountId <- getHttpParamValuesByName(httpParams, "account_id") url <- getHttpParamValuesByName(httpParams, "url") @@ -1233,7 +1235,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ val ordering = OBPOrdering(None, sortDirection) //This guarantee the order List(limit, offset, ordering, sortBy, fromDate, toDate, - anon, status, consumerId, azp, iss, consentId, userId, url, appName, implementedByPartialFunction, implementedInVersion, + anon, status, consumerId, azp, iss, consentId, userId, cbsUserId, url, appName, implementedByPartialFunction, implementedInVersion, verb, correlationId, duration, excludeAppNames, excludeUrlPattern, excludeImplementedByPartialfunctions, includeAppNames, includeUrlPattern, includeImplementedByPartialfunctions, connectorName,functionName, bankId, accountId, customerId, lockedStatus, deletedStatus @@ -1276,6 +1278,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ val azp = getHttpRequestUrlParam(httpRequestUrl,"azp") val consentId = getHttpRequestUrlParam(httpRequestUrl,"consent_id") val userId = getHttpRequestUrlParam(httpRequestUrl, "user_id") + val cbsUserId = getHttpRequestUrlParam(httpRequestUrl, "cbs_user_id") val bankId = getHttpRequestUrlParam(httpRequestUrl, "bank_id") val accountId = getHttpRequestUrlParam(httpRequestUrl, "account_id") val url = getHttpRequestUrlParam(httpRequestUrl, "url") @@ -1305,7 +1308,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ Full(List( HTTPParam("sort_by",sortBy), HTTPParam("sort_direction",sortDirection), HTTPParam("from_date",fromDate), HTTPParam("to_date", toDate), HTTPParam("limit",limit), HTTPParam("offset",offset), - HTTPParam("anon", anon), HTTPParam("status", status), HTTPParam("consumer_id", consumerId), HTTPParam("azp", azp), HTTPParam("iss", iss), HTTPParam("consent_id", consentId), HTTPParam("user_id", userId), HTTPParam("url", url), HTTPParam("app_name", appName), + HTTPParam("anon", anon), HTTPParam("status", status), HTTPParam("consumer_id", consumerId), HTTPParam("azp", azp), HTTPParam("iss", iss), HTTPParam("consent_id", consentId), HTTPParam("user_id", userId), HTTPParam("cbs_user_id", cbsUserId), HTTPParam("url", url), HTTPParam("app_name", appName), HTTPParam("implemented_by_partial_function",implementedByPartialFunction), HTTPParam("implemented_in_version",implementedInVersion), HTTPParam("verb", verb), HTTPParam("correlation_id", correlationId), HTTPParam("duration", duration), HTTPParam("exclude_app_names", excludeAppNames), HTTPParam("exclude_url_patterns", excludeUrlPattern),HTTPParam("exclude_implemented_by_partial_functions", excludeImplementedByPartialfunctions), diff --git a/obp-api/src/main/scala/code/api/util/OBPParam.scala b/obp-api/src/main/scala/code/api/util/OBPParam.scala index 49bd62193..a4587e88e 100644 --- a/obp-api/src/main/scala/code/api/util/OBPParam.scala +++ b/obp-api/src/main/scala/code/api/util/OBPParam.scala @@ -31,6 +31,7 @@ case class OBPAzp(value: String) extends OBPQueryParam case class OBPIss(value: String) extends OBPQueryParam case class OBPConsentId(value: String) extends OBPQueryParam case class OBPUserId(value: String) extends OBPQueryParam +case class CBSUserId(value: String) extends OBPQueryParam case class OBPStatus(value: String) extends OBPQueryParam case class OBPBankId(value: String) extends OBPQueryParam case class OBPAccountId(value: String) extends OBPQueryParam diff --git a/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala b/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala index db1354069..b05898569 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala @@ -46,12 +46,13 @@ import code.consent.MappedConsent import code.metrics.APIMetric import code.model.Consumer import code.users.{UserAttribute, Users} +import code.util.Helper.MdcLoggable import code.views.system.{AccountAccess, ViewDefinition, ViewPermission} import com.openbankproject.commons.model._ import com.openbankproject.commons.util.ApiVersion import net.liftweb.common.{Box, Full} import net.liftweb.json -import net.liftweb.json.{JString, JValue, parse, parseOpt} +import net.liftweb.json.{JString, JValue, MappingException, parse, parseOpt} import java.text.SimpleDateFormat import java.util.Date @@ -676,7 +677,7 @@ case class ViewPermissionJson( extra_data: Option[List[String]] ) -object JSONFactory510 extends CustomJsonFormats { +object JSONFactory510 extends CustomJsonFormats with MdcLoggable { def createTransactionRequestJson(tr : TransactionRequest, transactionRequestAttributes: List[TransactionRequestAttributeTrait] ) : TransactionRequestJsonV510 = { TransactionRequestJsonV510( @@ -980,7 +981,16 @@ object JSONFactory510 extends CustomJsonFormats { def createConsentsJsonV510(consents: List[MappedConsent]): ConsentsJsonV510 = { ConsentsJsonV510( consents.map { c => - val jwtPayload = JwtUtil.getSignedPayloadAsJson(c.jsonWebToken).map(parse(_).extract[ConsentJWT]).toOption + val jwtPayload = JwtUtil + .getSignedPayloadAsJson(c.jsonWebToken) + .flatMap { payload => + Try(parse(payload).extract[ConsentJWT]).recover { + case e: MappingException => + logger.warn(s"Invalid JWT payload: ${e.getMessage}") + null + }.toOption + }.toOption + AllConsentJsonV510( consent_reference_id = c.consentReferenceId, consumer_id = c.consumerId, diff --git a/obp-api/src/main/scala/code/consent/MappedConsent.scala b/obp-api/src/main/scala/code/consent/MappedConsent.scala index 21f5bca8a..e1e4c00c9 100644 --- a/obp-api/src/main/scala/code/consent/MappedConsent.scala +++ b/obp-api/src/main/scala/code/consent/MappedConsent.scala @@ -1,9 +1,10 @@ package code.consent import java.util.Date -import code.api.util.{APIUtil, Consent, ErrorMessages, OBPBankId, OBPConsentId, OBPConsumerId, OBPLimit, OBPOffset, OBPQueryParam, OBPSortBy, OBPStatus, OBPUserId, SecureRandomUtil} +import code.api.util.{APIUtil, CBSUserId, Consent, ErrorMessages, OBPBankId, OBPConsentId, OBPConsumerId, OBPLimit, OBPOffset, OBPQueryParam, OBPSortBy, OBPStatus, OBPUserId, SecureRandomUtil} import code.consent.ConsentStatus.ConsentStatus import code.model.Consumer +import code.model.dataAccess.ResourceUser import code.util.MappedUUID import com.openbankproject.commons.model.User import com.openbankproject.commons.util.ApiStandards @@ -71,6 +72,18 @@ object MappedConsentProvider extends ConsentProvider { // The optional variables: val consumerId = queryParams.collectFirst { case OBPConsumerId(value) => By(MappedConsent.mConsumerId, value) } val consentId = queryParams.collectFirst { case OBPConsentId(value) => By(MappedConsent.mConsentId, value) } + val cbsUserId: Option[Cmp[MappedConsent, String]] = queryParams.collectFirst { + case CBSUserId(value) => + ResourceUser.findAll(By(ResourceUser.providerId, value)) match { + case Nil => + Some(By(MappedConsent.mUserId, "-1")) // no result + case x :: Nil => // exactly one + Some(By(MappedConsent.mUserId, x.userId)) + case moreThanOneRow => // more than one + None + } + }.flatten + val userId = queryParams.collectFirst { case OBPUserId(value) => By(MappedConsent.mUserId, value) } val status = queryParams.collectFirst { case OBPStatus(value) => @@ -96,7 +109,7 @@ object MappedConsentProvider extends ConsentProvider { offset.toSeq, limit.toSeq, status.toSeq, - userId.toSeq, + userId.orElse(cbsUserId).toSeq, consentId.toSeq, consumerId.toSeq ).flatten From 253327c937f36a32ab39c5572154d55348d5b17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Fri, 15 Aug 2025 12:17:46 +0200 Subject: [PATCH 3/3] feature/Add query param provider_provider_id at Get Consents endpoint --- .../main/scala/code/api/util/APIUtil.scala | 12 +++++----- .../main/scala/code/api/util/OBPParam.scala | 2 +- .../scala/code/api/v5_1_0/APIMethods510.scala | 4 ++++ .../scala/code/consent/MappedConsent.scala | 22 +++++++++++-------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/obp-api/src/main/scala/code/api/util/APIUtil.scala b/obp-api/src/main/scala/code/api/util/APIUtil.scala index 2fade7e73..176726d85 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -1147,7 +1147,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ case "iss" => Full(OBPIss(values.head)) case "consent_id" => Full(OBPConsentId(values.head)) case "user_id" => Full(OBPUserId(values.head)) - case "cbs_user_id" => Full(CBSUserId(values.head)) + case "provider_provider_id" => Full(ProviderProviderId(values.head)) case "bank_id" => Full(OBPBankId(values.head)) case "account_id" => Full(OBPAccountId(values.head)) case "url" => Full(OBPUrl(values.head)) @@ -1199,7 +1199,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ iss <- getHttpParamValuesByName(httpParams,"iss") consentId <- getHttpParamValuesByName(httpParams,"consent_id") userId <- getHttpParamValuesByName(httpParams, "user_id") - cbsUserId <- getHttpParamValuesByName(httpParams, "cbs_user_id") + providerProviderId <- getHttpParamValuesByName(httpParams, "provider_provider_id") bankId <- getHttpParamValuesByName(httpParams, "bank_id") accountId <- getHttpParamValuesByName(httpParams, "account_id") url <- getHttpParamValuesByName(httpParams, "url") @@ -1233,9 +1233,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ */ //val sortBy = json.header("obp_sort_by") val ordering = OBPOrdering(None, sortDirection) - //This guarantee the order + //This guarantee the order List(limit, offset, ordering, sortBy, fromDate, toDate, - anon, status, consumerId, azp, iss, consentId, userId, cbsUserId, url, appName, implementedByPartialFunction, implementedInVersion, + anon, status, consumerId, azp, iss, consentId, userId, providerProviderId, url, appName, implementedByPartialFunction, implementedInVersion, verb, correlationId, duration, excludeAppNames, excludeUrlPattern, excludeImplementedByPartialfunctions, includeAppNames, includeUrlPattern, includeImplementedByPartialfunctions, connectorName,functionName, bankId, accountId, customerId, lockedStatus, deletedStatus @@ -1278,7 +1278,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ val azp = getHttpRequestUrlParam(httpRequestUrl,"azp") val consentId = getHttpRequestUrlParam(httpRequestUrl,"consent_id") val userId = getHttpRequestUrlParam(httpRequestUrl, "user_id") - val cbsUserId = getHttpRequestUrlParam(httpRequestUrl, "cbs_user_id") + val providerProviderId = getHttpRequestUrlParam(httpRequestUrl, "provider_provider_id") val bankId = getHttpRequestUrlParam(httpRequestUrl, "bank_id") val accountId = getHttpRequestUrlParam(httpRequestUrl, "account_id") val url = getHttpRequestUrlParam(httpRequestUrl, "url") @@ -1308,7 +1308,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ Full(List( HTTPParam("sort_by",sortBy), HTTPParam("sort_direction",sortDirection), HTTPParam("from_date",fromDate), HTTPParam("to_date", toDate), HTTPParam("limit",limit), HTTPParam("offset",offset), - HTTPParam("anon", anon), HTTPParam("status", status), HTTPParam("consumer_id", consumerId), HTTPParam("azp", azp), HTTPParam("iss", iss), HTTPParam("consent_id", consentId), HTTPParam("user_id", userId), HTTPParam("cbs_user_id", cbsUserId), HTTPParam("url", url), HTTPParam("app_name", appName), + HTTPParam("anon", anon), HTTPParam("status", status), HTTPParam("consumer_id", consumerId), HTTPParam("azp", azp), HTTPParam("iss", iss), HTTPParam("consent_id", consentId), HTTPParam("user_id", userId), HTTPParam("provider_provider_id", providerProviderId), HTTPParam("url", url), HTTPParam("app_name", appName), HTTPParam("implemented_by_partial_function",implementedByPartialFunction), HTTPParam("implemented_in_version",implementedInVersion), HTTPParam("verb", verb), HTTPParam("correlation_id", correlationId), HTTPParam("duration", duration), HTTPParam("exclude_app_names", excludeAppNames), HTTPParam("exclude_url_patterns", excludeUrlPattern),HTTPParam("exclude_implemented_by_partial_functions", excludeImplementedByPartialfunctions), diff --git a/obp-api/src/main/scala/code/api/util/OBPParam.scala b/obp-api/src/main/scala/code/api/util/OBPParam.scala index a4587e88e..bc42c0465 100644 --- a/obp-api/src/main/scala/code/api/util/OBPParam.scala +++ b/obp-api/src/main/scala/code/api/util/OBPParam.scala @@ -31,7 +31,7 @@ case class OBPAzp(value: String) extends OBPQueryParam case class OBPIss(value: String) extends OBPQueryParam case class OBPConsentId(value: String) extends OBPQueryParam case class OBPUserId(value: String) extends OBPQueryParam -case class CBSUserId(value: String) extends OBPQueryParam +case class ProviderProviderId(value: String) extends OBPQueryParam case class OBPStatus(value: String) extends OBPQueryParam case class OBPBankId(value: String) extends OBPQueryParam case class OBPAccountId(value: String) extends OBPQueryParam diff --git a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala index 32f8ce6c2..01851b749 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala @@ -1707,6 +1707,10 @@ trait APIMethods510 { | |7 bank_id (ignore if omitted) | + |8 provider_provider_id (ignore if omitted) + |provider and provider_id values are separated by pipe char + |eg: provider_provider_id=http%3A%2F%2Flocalhost%3A7070%2Frealms%2Fmaster|7837ee9c-3446-4d8c-9b90-301a52b4851d + | |eg:/management/consents?consumer_id=78&limit=10&offset=10 | """.stripMargin, diff --git a/obp-api/src/main/scala/code/consent/MappedConsent.scala b/obp-api/src/main/scala/code/consent/MappedConsent.scala index e1e4c00c9..6fa453465 100644 --- a/obp-api/src/main/scala/code/consent/MappedConsent.scala +++ b/obp-api/src/main/scala/code/consent/MappedConsent.scala @@ -1,7 +1,7 @@ package code.consent import java.util.Date -import code.api.util.{APIUtil, CBSUserId, Consent, ErrorMessages, OBPBankId, OBPConsentId, OBPConsumerId, OBPLimit, OBPOffset, OBPQueryParam, OBPSortBy, OBPStatus, OBPUserId, SecureRandomUtil} +import code.api.util.{APIUtil, Consent, ErrorMessages, OBPBankId, OBPConsentId, OBPConsumerId, OBPLimit, OBPOffset, OBPQueryParam, OBPSortBy, OBPStatus, OBPUserId, ProviderProviderId, SecureRandomUtil} import code.consent.ConsentStatus.ConsentStatus import code.model.Consumer import code.model.dataAccess.ResourceUser @@ -9,10 +9,12 @@ import code.util.MappedUUID import com.openbankproject.commons.model.User import com.openbankproject.commons.util.ApiStandards import net.liftweb.common.{Box, Empty, Failure, Full} -import net.liftweb.mapper.{MappedString, _} +import net.liftweb.mapper._ import net.liftweb.util.Helpers.{now, tryo} import org.mindrot.jbcrypt.BCrypt +import java.net.URLDecoder +import java.nio.charset.StandardCharsets import scala.collection.immutable.List object MappedConsentProvider extends ConsentProvider { @@ -72,14 +74,16 @@ object MappedConsentProvider extends ConsentProvider { // The optional variables: val consumerId = queryParams.collectFirst { case OBPConsumerId(value) => By(MappedConsent.mConsumerId, value) } val consentId = queryParams.collectFirst { case OBPConsentId(value) => By(MappedConsent.mConsentId, value) } - val cbsUserId: Option[Cmp[MappedConsent, String]] = queryParams.collectFirst { - case CBSUserId(value) => - ResourceUser.findAll(By(ResourceUser.providerId, value)) match { - case Nil => - Some(By(MappedConsent.mUserId, "-1")) // no result + val providerProviderId: Option[Cmp[MappedConsent, String]] = queryParams.collectFirst { + case ProviderProviderId(value) => + val (provider, providerId) = value.split("\\|") match { // split by literal '|' + case Array(a, b) => (a, b) + case _ => ("", "") // fallback if format is unexpected + } + ResourceUser.findAll(By(ResourceUser.provider_, provider), By(ResourceUser.providerId, providerId)) match { case x :: Nil => // exactly one Some(By(MappedConsent.mUserId, x.userId)) - case moreThanOneRow => // more than one + case _ => None } }.flatten @@ -109,7 +113,7 @@ object MappedConsentProvider extends ConsentProvider { offset.toSeq, limit.toSeq, status.toSeq, - userId.orElse(cbsUserId).toSeq, + userId.orElse(providerProviderId).toSeq, consentId.toSeq, consumerId.toSeq ).flatten