mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:37:00 +00:00
feature/Add fields optional in POST Bank
This commit is contained in:
parent
afc46603f1
commit
2b04b7c97b
@ -866,6 +866,25 @@ object SwaggerDefinitionsJSON {
|
||||
website = "www.openbankproject.com",
|
||||
bank_routings = List(bankRoutingJsonV121),
|
||||
attributes = Some(List(bankAttributeBankResponseJsonV400))
|
||||
)
|
||||
val bankJson500 = BankJson500(
|
||||
id = "gh.29.uk",
|
||||
bank_code = "bank_code ",
|
||||
full_name = "full_name",
|
||||
logo = "logo",
|
||||
website = "www.openbankproject.com",
|
||||
bank_routings = List(bankRoutingJsonV121),
|
||||
attributes = Some(List(bankAttributeBankResponseJsonV400))
|
||||
)
|
||||
|
||||
val postBankJson500 = PostBankJson500(
|
||||
id = Some("gh.29.uk"),
|
||||
bank_code = "bank_code",
|
||||
full_name = Some("full_name"),
|
||||
logo = Some("logo"),
|
||||
website = Some("www.openbankproject.com"),
|
||||
bank_routings = Some(List(bankRoutingJsonV121)),
|
||||
attributes = Some(List(bankAttributeBankResponseJsonV400))
|
||||
)
|
||||
|
||||
val banksJSON400 = BanksJson400(
|
||||
|
||||
@ -2,15 +2,16 @@ package code.api.v5_0_0
|
||||
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiRole.{CanCreateUserAuthContextUpdate, canCreateUserAuthContext, canGetCustomers, canGetCustomersMinimal, canGetUserAuthContext}
|
||||
import code.api.util.ApiRole.{CanCreateEntitlementAtOneBank, CanCreateUserAuthContextUpdate, CanReadDynamicResourceDocsAtOneBank, canCreateBank, canCreateUserAuthContext, canGetCustomers, canGetCustomersMinimal, canGetUserAuthContext}
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.{APIUtil, ApiRole, Consent, NewStyle}
|
||||
import code.api.util.{APIUtil, ApiRole, Consent, ErrorMessages, NewStyle}
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.api.util.NewStyle.function.extractQueryParams
|
||||
import code.api.v2_1_0.JSONFactory210
|
||||
import code.api.v3_0_0.JSONFactory300
|
||||
import code.api.v3_1_0.{PostConsentBodyCommonJson, PostConsentEmailJsonV310, PostConsentEntitlementJsonV310, PostConsentPhoneJsonV310, PostConsentViewJsonV310, PostUserAuthContextJson, PostUserAuthContextUpdateJsonV310}
|
||||
import code.api.v4_0_0.{BankJson400, JSONFactory400}
|
||||
import code.api.v4_0_0.JSONFactory400.createCustomersMinimalJson
|
||||
import code.bankconnectors.Connector
|
||||
import code.consent.{ConsentRequests, Consents}
|
||||
@ -27,7 +28,7 @@ import net.liftweb.common.Full
|
||||
import net.liftweb.http.Req
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json.{compactRender}
|
||||
import net.liftweb.json.compactRender
|
||||
import net.liftweb.util.Props
|
||||
|
||||
import scala.collection.immutable.{List, Nil}
|
||||
@ -64,6 +65,90 @@ trait APIMethods500 {
|
||||
val apiRelations = ArrayBuffer[ApiRelation]()
|
||||
val codeContext = CodeContext(staticResourceDocs, apiRelations)
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
createBank,
|
||||
implementedInApiVersion,
|
||||
"createBank",
|
||||
"POST",
|
||||
"/banks",
|
||||
"Create Bank",
|
||||
s"""Create a new bank (Authenticated access).
|
||||
|
|
||||
|The user creating this will be automatically assigned the Role CanCreateEntitlementAtOneBank.
|
||||
|Thus the User can manage the bank they create and assign Roles to other Users.
|
||||
|
|
||||
|Only SANDBOX mode
|
||||
|The settlement accounts are created specified by the bank in the POST body.
|
||||
|Name and account id are created in accordance to the next rules:
|
||||
| - Incoming account (name: Default incoming settlement account, Account ID: OBP_DEFAULT_INCOMING_ACCOUNT_ID, currency: EUR)
|
||||
| - Outgoing account (name: Default outgoing settlement account, Account ID: OBP_DEFAULT_OUTGOING_ACCOUNT_ID, currency: EUR)
|
||||
|
|
||||
|""",
|
||||
postBankJson500,
|
||||
bankJson500,
|
||||
List(
|
||||
InvalidJsonFormat,
|
||||
$UserNotLoggedIn,
|
||||
InsufficientAuthorisationToCreateBank,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagBank, apiTagNewStyle),
|
||||
Some(List(canCreateBank))
|
||||
)
|
||||
|
||||
lazy val createBank: OBPEndpoint = {
|
||||
case "banks" :: Nil JsonPost json -> _ => {
|
||||
cc =>
|
||||
val failMsg = s"$InvalidJsonFormat The Json body should be the $BankJson400 "
|
||||
for {
|
||||
bank <- NewStyle.function.tryons(failMsg, 400, cc.callContext) {
|
||||
json.extract[PostBankJson500]
|
||||
}
|
||||
_ <- Helper.booleanToFuture(failMsg = ErrorMessages.InvalidConsumerCredentials, cc=cc.callContext) {
|
||||
cc.callContext.map(_.consumer.isDefined == true).isDefined
|
||||
}
|
||||
_ <- Helper.booleanToFuture(failMsg = s"$InvalidJsonFormat Min length of BANK_ID should be greater than 3 characters.", cc=cc.callContext) {
|
||||
bank.id.forall(_.length > 3)
|
||||
}
|
||||
_ <- Helper.booleanToFuture(failMsg = s"$InvalidJsonFormat BANK_ID can not contain space characters", cc=cc.callContext) {
|
||||
!bank.id.contains(" ")
|
||||
}
|
||||
(success, callContext) <- NewStyle.function.createOrUpdateBank(
|
||||
bank.id.getOrElse(APIUtil.generateUUID()),
|
||||
bank.full_name.getOrElse(""),
|
||||
bank.bank_code,
|
||||
bank.logo.getOrElse(""),
|
||||
bank.website.getOrElse(""),
|
||||
bank.bank_routings.getOrElse(Nil).find(_.scheme == "BIC").map(_.address).getOrElse(""),
|
||||
"",
|
||||
bank.bank_routings.getOrElse(Nil).filterNot(_.scheme == "BIC").headOption.map(_.scheme).getOrElse(""),
|
||||
bank.bank_routings.getOrElse(Nil).filterNot(_.scheme == "BIC").headOption.map(_.address).getOrElse(""),
|
||||
cc.callContext
|
||||
)
|
||||
entitlements <- NewStyle.function.getEntitlementsByUserId(cc.userId, callContext)
|
||||
entitlementsByBank = entitlements.filter(_.bankId==bank.id.getOrElse(""))
|
||||
_ <- entitlementsByBank.filter(_.roleName == CanCreateEntitlementAtOneBank.toString()).size > 0 match {
|
||||
case true =>
|
||||
// Already has entitlement
|
||||
Future()
|
||||
case false =>
|
||||
Future(Entitlement.entitlement.vend.addEntitlement(bank.id.getOrElse(""), cc.userId, CanCreateEntitlementAtOneBank.toString()))
|
||||
}
|
||||
_ <- entitlementsByBank.filter(_.roleName == CanReadDynamicResourceDocsAtOneBank.toString()).size > 0 match {
|
||||
case true =>
|
||||
// Already has entitlement
|
||||
Future()
|
||||
case false =>
|
||||
Future(Entitlement.entitlement.vend.addEntitlement(bank.id.getOrElse(""), cc.userId, CanReadDynamicResourceDocsAtOneBank.toString()))
|
||||
}
|
||||
} yield {
|
||||
(JSONFactory500.createBankJSON500(success), HttpCode.`201`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
createUserAuthContext,
|
||||
implementedInApiVersion,
|
||||
|
||||
@ -26,13 +26,38 @@
|
||||
*/
|
||||
package code.api.v5_0_0
|
||||
|
||||
import code.api.v3_1_0.{PostConsentEntitlementJsonV310}
|
||||
import com.openbankproject.commons.model.{AccountRoutingJsonV121, UserAuthContext, UserAuthContextUpdate}
|
||||
import code.api.v3_1_0.PostConsentEntitlementJsonV310
|
||||
import com.openbankproject.commons.model.{AccountRoutingJsonV121, Bank, UserAuthContext, UserAuthContextUpdate}
|
||||
import net.liftweb.json.JsonAST.JValue
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util.APIUtil.stringOrNull
|
||||
import code.api.v1_2_1.BankRoutingJsonV121
|
||||
import code.api.v4_0_0.{BankAttributeBankResponseJsonV400, BankJson400}
|
||||
import code.bankattribute.BankAttribute
|
||||
|
||||
import scala.collection.immutable.List
|
||||
|
||||
case class PostBankJson500(
|
||||
id: Option[String],
|
||||
bank_code: String,
|
||||
full_name: Option[String],
|
||||
logo: Option[String],
|
||||
website: Option[String],
|
||||
bank_routings: Option[List[BankRoutingJsonV121]],
|
||||
attributes: Option[List[BankAttributeBankResponseJsonV400]]
|
||||
)
|
||||
|
||||
case class BankJson500(
|
||||
id: String,
|
||||
bank_code: String,
|
||||
full_name: String,
|
||||
logo: String,
|
||||
website: String,
|
||||
bank_routings: List[BankRoutingJsonV121],
|
||||
attributes: Option[List[BankAttributeBankResponseJsonV400]]
|
||||
)
|
||||
|
||||
case class UserAuthContextJsonV500(
|
||||
user_auth_context_id: String,
|
||||
user_id: String,
|
||||
@ -109,5 +134,30 @@ object JSONFactory500 {
|
||||
consumer_id = userAuthContextUpdate.consumerId
|
||||
)
|
||||
}
|
||||
|
||||
def createBankJSON500(bank: Bank, attributes: List[BankAttribute] = Nil): BankJson500 = {
|
||||
val obp = BankRoutingJsonV121("OBP", bank.bankId.value)
|
||||
val bic = BankRoutingJsonV121("BIC", bank.swiftBic)
|
||||
val routings = bank.bankRoutingScheme match {
|
||||
case "OBP" => bic :: BankRoutingJsonV121(bank.bankRoutingScheme, bank.bankRoutingAddress) :: Nil
|
||||
case "BIC" => obp :: BankRoutingJsonV121(bank.bankRoutingScheme, bank.bankRoutingAddress) :: Nil
|
||||
case _ => obp :: bic :: BankRoutingJsonV121(bank.bankRoutingScheme, bank.bankRoutingAddress) :: Nil
|
||||
}
|
||||
new BankJson500(
|
||||
stringOrNull(bank.bankId.value),
|
||||
stringOrNull(bank.shortName),
|
||||
stringOrNull(bank.fullName),
|
||||
stringOrNull(bank.logoUrl),
|
||||
stringOrNull(bank.websiteUrl),
|
||||
routings.filter(a => stringOrNull(a.address) != null),
|
||||
Option(
|
||||
attributes.filter(_.isActive == Some(true)).map(a => BankAttributeBankResponseJsonV400(
|
||||
name = a.name,
|
||||
value = a.value)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
93
obp-api/src/test/scala/code/api/v5_0_0/BankTests.scala
Normal file
93
obp-api/src/test/scala/code/api/v5_0_0/BankTests.scala
Normal file
@ -0,0 +1,93 @@
|
||||
package code.api.v5_0_0
|
||||
|
||||
import code.api.Constant.{INCOMING_SETTLEMENT_ACCOUNT_ID, OUTGOING_SETTLEMENT_ACCOUNT_ID}
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.postBankJson500
|
||||
import code.api.util.ApiRole.CanCreateBank
|
||||
import code.api.util.ErrorMessages.UserHasMissingRoles
|
||||
import code.api.util.{ApiRole, ErrorMessages, NewStyle}
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import code.api.v5_0_0.APIMethods500.Implementations5_0_0
|
||||
import code.entitlement.Entitlement
|
||||
import code.setup.{APIResponse, DefaultUsers}
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, ErrorMessage}
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.json.Serialization.write
|
||||
import org.scalatest.Tag
|
||||
|
||||
class BankTests extends V500ServerSetupAsync with DefaultUsers {
|
||||
|
||||
override def beforeAll() {
|
||||
super.beforeAll()
|
||||
}
|
||||
|
||||
override def afterAll() {
|
||||
super.afterAll()
|
||||
}
|
||||
|
||||
/**
|
||||
* Test tags
|
||||
* Example: To run tests with tag "getPermissions":
|
||||
* mvn test -D tagsToInclude
|
||||
*
|
||||
* This is made possible by the scalatest maven plugin
|
||||
*/
|
||||
object VersionOfApi extends Tag(ApiVersion.v5_0_0.toString)
|
||||
object ApiEndpoint1 extends Tag(nameOf(Implementations5_0_0.createBank))
|
||||
|
||||
feature(s"Assuring that endpoint createBank works as expected - $VersionOfApi") {
|
||||
|
||||
scenario("We try to consume endpoint createBank - Anonymous access", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make the request")
|
||||
val request = (v5_0_0_Request / "banks").POST
|
||||
val response = makePostRequestAsync(request, write(postBankJson500))
|
||||
Then("We should get a 401")
|
||||
And("We should get a message: " + ErrorMessages.UserNotLoggedIn)
|
||||
response map { r =>
|
||||
r.code should equal(401)
|
||||
r.body.extract[ErrorMessage].message should equal(ErrorMessages.UserNotLoggedIn)
|
||||
}
|
||||
}
|
||||
|
||||
scenario("We try to consume endpoint createBank without proper role - Authorized access", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make the request")
|
||||
val request = (v5_0_0_Request / "banks").POST <@ (user1)
|
||||
val response = makePostRequestAsync(request, write(postBankJson500))
|
||||
Then("We should get a 403")
|
||||
And("We should get a message: " + s"$CanCreateBank entitlement required")
|
||||
response map { r =>
|
||||
r.code should equal(403)
|
||||
r.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanCreateBank)
|
||||
}
|
||||
}
|
||||
|
||||
scenario("We try to consume endpoint createBank with proper role - Authorized access", ApiEndpoint1, VersionOfApi) {
|
||||
When("We add required entitlement")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.CanCreateBank.toString)
|
||||
And("We make the request")
|
||||
val requestGet = (v5_0_0_Request / "banks").POST <@ (user1)
|
||||
val response = for {
|
||||
before <- NewStyle.function.getEntitlementsByUserId(resourceUser1.userId, None) map {
|
||||
_.exists( e => e.roleName == ApiRole.CanCreateEntitlementAtOneBank.toString && e.bankId == postBankJson500.id.getOrElse(""))
|
||||
}
|
||||
response: APIResponse <- makePostRequestAsync(requestGet, write(postBankJson500))
|
||||
after <- NewStyle.function.getEntitlementsByUserId(resourceUser1.userId, None) map {
|
||||
_.exists( e => e.roleName == ApiRole.CanCreateEntitlementAtOneBank.toString && e.bankId == postBankJson500.id.getOrElse(""))
|
||||
}
|
||||
} yield (before, after, response)
|
||||
Then("We should get a 201")
|
||||
response flatMap { r =>
|
||||
r._1 should equal(false) // Before we create a bank there is no role CanCreateEntitlementAtOneBank
|
||||
r._2 should equal(true) // After we create a bank there is a role CanCreateEntitlementAtOneBank
|
||||
r._3.code should equal(201)
|
||||
Then("Default settlement accounts should be created")
|
||||
val defaultOutgoingAccount = NewStyle.function.checkBankAccountExists(BankId(postBankJson500.id.getOrElse("")), AccountId(OUTGOING_SETTLEMENT_ACCOUNT_ID), None)
|
||||
val defaultIncomingAccount = NewStyle.function.checkBankAccountExists(BankId(postBankJson500.id.getOrElse("")), AccountId(INCOMING_SETTLEMENT_ACCOUNT_ID), None)
|
||||
defaultOutgoingAccount.map(account => account._1.accountId.value should equal(OUTGOING_SETTLEMENT_ACCOUNT_ID))
|
||||
defaultIncomingAccount.map(account => account._1.accountId.value should equal(INCOMING_SETTLEMENT_ACCOUNT_ID))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user