mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:37:00 +00:00
feature/Add endpoint updateConsentPayloadByConsentId v5.1.0
This commit is contained in:
parent
751c16890e
commit
d79f076556
@ -992,6 +992,10 @@ object ApiRole extends MdcLoggable{
|
||||
lazy val canUpdateConsentStatusAtOneBank = CanUpdateConsentStatusAtOneBank()
|
||||
case class CanUpdateConsentStatusAtAnyBank(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canUpdateConsentStatusAtAnyBank = CanUpdateConsentStatusAtAnyBank()
|
||||
case class CanUpdateConsentPayloadAtOneBank(requiresBankId: Boolean = true) extends ApiRole
|
||||
lazy val canUpdateConsentPayloadAtOneBank = CanUpdateConsentPayloadAtOneBank()
|
||||
case class CanUpdateConsentPayloadAtAnyBank(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canUpdateConsentPayloadAtAnyBank = CanUpdateConsentPayloadAtAnyBank()
|
||||
case class CanRevokeConsentAtBank(requiresBankId: Boolean = true) extends ApiRole
|
||||
lazy val canRevokeConsentAtBank = CanRevokeConsentAtBank()
|
||||
case class CanGetConsentsAtOneBank(requiresBankId: Boolean = true) extends ApiRole
|
||||
|
||||
@ -2,7 +2,6 @@ package code.api.util
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.{Date, UUID}
|
||||
|
||||
import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{ConsentAccessJson, PostConsentJson}
|
||||
import code.api.util.ApiRole.{canCreateEntitlementAtAnyBank, canCreateEntitlementAtOneBank}
|
||||
import code.api.v3_1_0.{PostConsentBodyCommonJson, PostConsentEntitlementJsonV310, PostConsentViewJsonV310}
|
||||
@ -741,6 +740,57 @@ object Consent extends MdcLoggable {
|
||||
}
|
||||
}
|
||||
}
|
||||
def updateBerlinGroupConsentJWT(access: ConsentAccessJson,
|
||||
consent: MappedConsent,
|
||||
callContext: Option[CallContext]): Future[Box[String]] = {
|
||||
implicit val dateFormats = CustomJsonFormats.formats
|
||||
val payloadToUpdate: Box[ConsentJWT] = JwtUtil.getSignedPayloadAsJson(consent.jsonWebToken) // Payload as JSON string
|
||||
.map(net.liftweb.json.parse(_).extract[ConsentJWT]) // Extract case class
|
||||
|
||||
|
||||
// 1. Add access
|
||||
val accounts: List[Future[ConsentView]] = access.accounts.getOrElse(Nil) map { account =>
|
||||
Connector.connector.vend.getBankAccountByIban(account.iban.getOrElse(""), callContext) map { bankAccount =>
|
||||
logger.debug(s"createBerlinGroupConsentJWT.accounts.bankAccount: $bankAccount")
|
||||
ConsentView(
|
||||
bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""),
|
||||
account_id = bankAccount._1.map(_.accountId.value).getOrElse(""),
|
||||
view_id = Constant.SYSTEM_READ_ACCOUNTS_BERLIN_GROUP_VIEW_ID
|
||||
)
|
||||
}
|
||||
}
|
||||
val balances: List[Future[ConsentView]] = access.balances.getOrElse(Nil) map { account =>
|
||||
Connector.connector.vend.getBankAccountByIban(account.iban.getOrElse(""), callContext) map { bankAccount =>
|
||||
logger.debug(s"createBerlinGroupConsentJWT.balances.bankAccount: $bankAccount")
|
||||
ConsentView(
|
||||
bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""),
|
||||
account_id = bankAccount._1.map(_.accountId.value).getOrElse(""),
|
||||
view_id = Constant.SYSTEM_READ_BALANCES_BERLIN_GROUP_VIEW_ID
|
||||
)
|
||||
}
|
||||
}
|
||||
val transactions: List[Future[ConsentView]] = access.transactions.getOrElse(Nil) map { account =>
|
||||
Connector.connector.vend.getBankAccountByIban(account.iban.getOrElse(""), callContext) map { bankAccount =>
|
||||
logger.debug(s"createBerlinGroupConsentJWT.transactions.bankAccount: $bankAccount")
|
||||
ConsentView(
|
||||
bank_id = bankAccount._1.map(_.bankId.value).getOrElse(""),
|
||||
account_id = bankAccount._1.map(_.accountId.value).getOrElse(""),
|
||||
view_id = Constant.SYSTEM_READ_TRANSACTIONS_BERLIN_GROUP_VIEW_ID
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Future.sequence(accounts ::: balances ::: transactions) map { views =>
|
||||
if(views.isEmpty) {
|
||||
Empty
|
||||
} else {
|
||||
val updatedPayload = payloadToUpdate.map(i => i.copy(views = views))
|
||||
val jwtPayloadAsJson = compactRender(Extraction.decompose(updatedPayload))
|
||||
val jwtClaims: JWTClaimsSet = JWTClaimsSet.parse(jwtPayloadAsJson)
|
||||
Full(CertificateUtil.jwtWithHmacProtection(jwtClaims, consent.secret))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def createUKConsentJWT(
|
||||
user: Option[User],
|
||||
|
||||
@ -3,6 +3,7 @@ package code.api.v5_1_0
|
||||
|
||||
import code.api.Constant
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
|
||||
import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{ConsentAccessAccountsJson, ConsentAccessJson}
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiRole._
|
||||
import code.api.util.ApiTag._
|
||||
@ -28,7 +29,7 @@ import code.api.v5_0_0.JSONFactory500
|
||||
import code.api.v5_1_0.JSONFactory510.{createConsentsInfoJsonV510, createConsentsJsonV510, createRegulatedEntitiesJson, createRegulatedEntityJson}
|
||||
import code.atmattribute.AtmAttribute
|
||||
import code.bankconnectors.Connector
|
||||
import code.consent.{ConsentRequests, ConsentStatus, Consents}
|
||||
import code.consent.{ConsentRequests, ConsentStatus, Consents, MappedConsent}
|
||||
import code.consumer.Consumers
|
||||
import code.loginattempts.LoginAttempt
|
||||
import code.metrics.APIMetrics
|
||||
@ -55,6 +56,7 @@ import net.liftweb.mapper.By
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
import net.liftweb.util.{Helpers, StringHelpers}
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.time.{LocalDate, ZoneId}
|
||||
import java.util.Date
|
||||
import scala.collection.immutable.{List, Nil}
|
||||
@ -1347,6 +1349,83 @@ trait APIMethods510 {
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
updateConsentPayloadByConsentId,
|
||||
implementedInApiVersion,
|
||||
nameOf(updateConsentPayloadByConsentId),
|
||||
"PUT",
|
||||
"/management/banks/BANK_ID/consents/CONSENT_ID/payload",
|
||||
"Update Consent Payload by CONSENT_ID",
|
||||
s"""
|
||||
|
|
||||
|This endpoint is used to update the Payload of Consent.
|
||||
|
|
||||
|${authenticationRequiredMessage(true)}
|
||||
|
|
||||
|""",
|
||||
PutConsentPayloadJsonV510(
|
||||
access = ConsentAccessJson(
|
||||
accounts = Option(List(ConsentAccessAccountsJson(
|
||||
iban = Some(ExampleValue.ibanExample.value),
|
||||
bban = None,
|
||||
pan = None,
|
||||
maskedPan = None,
|
||||
msisdn = None,
|
||||
currency = None,
|
||||
)))
|
||||
)
|
||||
),
|
||||
ConsentChallengeJsonV310(
|
||||
consent_id = "9d429899-24f5-42c8-8565-943ffa6a7945",
|
||||
jwt = "eyJhbGciOiJIUzI1NiJ9.eyJlbnRpdGxlbWVudHMiOltdLCJjcmVhdGVkQnlVc2VySWQiOiJhYjY1MzlhOS1iMTA1LTQ0ODktYTg4My0wYWQ4ZDZjNjE2NTciLCJzdWIiOiIyMWUxYzhjYy1mOTE4LTRlYWMtYjhlMy01ZTVlZWM2YjNiNGIiLCJhdWQiOiJlanpuazUwNWQxMzJyeW9tbmhieDFxbXRvaHVyYnNiYjBraWphanNrIiwibmJmIjoxNTUzNTU0ODk5LCJpc3MiOiJodHRwczpcL1wvd3d3Lm9wZW5iYW5rcHJvamVjdC5jb20iLCJleHAiOjE1NTM1NTg0OTksImlhdCI6MTU1MzU1NDg5OSwianRpIjoiMDlmODhkNWYtZWNlNi00Mzk4LThlOTktNjYxMWZhMWNkYmQ1Iiwidmlld3MiOlt7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAxIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifSx7ImFjY291bnRfaWQiOiJtYXJrb19wcml2aXRlXzAyIiwiYmFua19pZCI6ImdoLjI5LnVrLngiLCJ2aWV3X2lkIjoib3duZXIifV19.8cc7cBEf2NyQvJoukBCmDLT7LXYcuzTcSYLqSpbxLp4",
|
||||
status = "AUTHORISED"
|
||||
),
|
||||
List(
|
||||
$UserNotLoggedIn,
|
||||
$BankNotFound,
|
||||
InvalidJsonFormat,
|
||||
ConsentNotFound,
|
||||
InvalidConnectorResponse,
|
||||
UnknownError
|
||||
),
|
||||
apiTagConsent :: apiTagPSD2AIS :: Nil,
|
||||
Some(List(canUpdateConsentPayloadAtOneBank, canUpdateConsentPayloadAtAnyBank))
|
||||
)
|
||||
|
||||
lazy val updateConsentPayloadByConsentId: OBPEndpoint = {
|
||||
case "management" :: "banks" :: BankId(bankId) :: "consents" :: consentId :: "payload" :: Nil JsonPut json -> _ => {
|
||||
cc =>
|
||||
implicit val ec = EndpointContext(Some(cc))
|
||||
for {
|
||||
consentJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PutConsentPayloadJsonV510 ", 400, cc.callContext) {
|
||||
json.extract[PutConsentPayloadJsonV510]
|
||||
}
|
||||
consent: MappedConsent <- Future(Consents.consentProvider.vend.getConsentByConsentId(consentId)) map {
|
||||
unboxFullOrFail(_, cc.callContext, s"$ConsentNotFound ($consentId)", 404)
|
||||
}
|
||||
consentJWT <- Consent.updateBerlinGroupConsentJWT(
|
||||
consentJson.access,
|
||||
consent,
|
||||
cc.callContext
|
||||
) map {
|
||||
i => connectorEmptyResponse(i, cc.callContext)
|
||||
}
|
||||
updatedConsent <- Future(Consents.consentProvider.vend.setJsonWebToken(consent.consentId, consentJWT)) map {
|
||||
i => connectorEmptyResponse(i, cc.callContext)
|
||||
}
|
||||
} yield {
|
||||
(
|
||||
ConsentJsonV310(
|
||||
updatedConsent.consentId,
|
||||
updatedConsent.jsonWebToken,
|
||||
updatedConsent.status
|
||||
),
|
||||
HttpCode.`200`(cc.callContext)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
getMyConsents,
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
package code.api.v5_1_0
|
||||
|
||||
import code.api.Constant
|
||||
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
|
||||
@ -134,6 +135,8 @@ case class ConsentInfoJsonV510(consent_id: String,
|
||||
)
|
||||
case class ConsentsInfoJsonV510(consents: List[ConsentInfoJsonV510])
|
||||
|
||||
case class PutConsentPayloadJsonV510(access: ConsentAccessJson)
|
||||
|
||||
case class AllConsentJsonV510(consent_reference_id: String,
|
||||
consumer_id: String,
|
||||
created_by_user_id: String,
|
||||
|
||||
@ -28,7 +28,7 @@ package code.api.v5_1_0
|
||||
import code.api.Constant
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import code.api.util.ApiRole.{canUpdateConsentStatusAtOneBank, _}
|
||||
import code.api.util.ApiRole._
|
||||
import code.api.util.Consent
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.v3_1_0.{PostConsentChallengeJsonV310, PostConsentEntitlementJsonV310}
|
||||
@ -68,6 +68,7 @@ class ConsentsTest extends V510ServerSetup with PropsReset{
|
||||
object ApiEndpoint8 extends Tag(nameOf(Implementations5_1_0.getMyConsents))
|
||||
object ApiEndpoint9 extends Tag(nameOf(Implementations5_1_0.getConsentsAtBank))
|
||||
object UpdateConsentStatusByUser extends Tag(nameOf(Implementations5_1_0.updateConsentStatusByUser))
|
||||
object UpdateConsentPayloadByConsentId extends Tag(nameOf(Implementations5_1_0.updateConsentPayloadByConsentId))
|
||||
|
||||
lazy val entitlements = List(PostConsentEntitlementJsonV310("", CanGetAnyUser.toString()))
|
||||
lazy val bankId = testBankId1.value
|
||||
@ -93,6 +94,7 @@ class ConsentsTest extends V510ServerSetup with PropsReset{
|
||||
def getMyConsents(consentId: String) = (v5_1_0_Request / "banks" / bankId / "my" / "consents").GET
|
||||
def getConsentsAtBAnk(consentId: String) = (v5_1_0_Request / "management"/ "consents" / "banks" / bankId).GET
|
||||
def updateConsentStatusByUser(consentId: String) = (v5_1_0_Request / "management" / "banks" / bankId / "consents" / consentId).PUT
|
||||
def updateConsentPayloadByConsent(consentId: String) = (v5_1_0_Request / "management" / "banks" / bankId / "consents" / consentId / "payload").PUT
|
||||
|
||||
feature(s"test $ApiEndpoint6 version $VersionOfApi - Unauthorized access") {
|
||||
scenario("We will call the endpoint without user credentials", ApiEndpoint6, VersionOfApi) {
|
||||
@ -155,7 +157,7 @@ class ConsentsTest extends V510ServerSetup with PropsReset{
|
||||
feature(s"test $UpdateConsentStatusByUser version $VersionOfApi - Unauthenticated access") {
|
||||
scenario("We will call the endpoint without user credentials", UpdateConsentStatusByUser, VersionOfApi) {
|
||||
When(s"We make a request $UpdateConsentStatusByUser")
|
||||
val response510 = makeGetRequest(getConsentsAtBAnk("whatever"))
|
||||
val response510 = makePutRequest(updateConsentStatusByUser("whatever"), write(consentStatus))
|
||||
Then("We should get a 401")
|
||||
response510.code should equal(401)
|
||||
response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
@ -180,6 +182,36 @@ class ConsentsTest extends V510ServerSetup with PropsReset{
|
||||
response510.body.extract[ErrorMessage].message should startWith(ConsentNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
feature(s"test $UpdateConsentPayloadByConsentId version $VersionOfApi - Unauthenticated access") {
|
||||
scenario("We will call the endpoint without user credentials", UpdateConsentPayloadByConsentId, VersionOfApi) {
|
||||
When(s"We make a request $UpdateConsentPayloadByConsentId")
|
||||
val response510 = makePutRequest(updateConsentPayloadByConsent("whatever"), write(consentStatus))
|
||||
Then("We should get a 401")
|
||||
response510.code should equal(401)
|
||||
response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
}
|
||||
}
|
||||
feature(s"test $UpdateConsentPayloadByConsentId version $VersionOfApi - Authenticated access") {
|
||||
scenario("We will call the endpoint with user credentials", UpdateConsentPayloadByConsentId, VersionOfApi) {
|
||||
When(s"We make a request $UpdateConsentPayloadByConsentId")
|
||||
val response510 = makePutRequest(updateConsentPayloadByConsent("whatever") <@ user1, write(consentStatus))
|
||||
Then("We should get a 403")
|
||||
response510.code should equal(403)
|
||||
response510.body.extract[ErrorMessage].message contains (UserHasMissingRoles + s"$CanUpdateConsentPayloadAtOneBank or $CanUpdateConsentPayloadAtAnyBank") should be(true)
|
||||
}
|
||||
}
|
||||
feature(s"test $UpdateConsentPayloadByConsentId version $VersionOfApi - Authenticated access with Role $CanUpdateConsentStatusAtAnyBank") {
|
||||
scenario("We will call the endpoint with user credentials", UpdateConsentPayloadByConsentId, VersionOfApi) {
|
||||
When(s"We make a request $UpdateConsentPayloadByConsentId")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanUpdateConsentPayloadAtAnyBank.toString)
|
||||
val response510 = makePutRequest(updateConsentPayloadByConsent("whatever") <@ user1, write(consentStatus))
|
||||
Then("We should get a 404")
|
||||
response510.code should equal(404)
|
||||
response510.body.extract[ErrorMessage].message should startWith(ConsentNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"Create/Use/Revoke Consent $VersionOfApi") {
|
||||
scenario("We will call the Create, Get and Delete endpoints with user credentials ", ApiEndpoint1, ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, ApiEndpoint5, ApiEndpoint6, ApiEndpoint7, VersionOfApi) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user