mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 16:56:56 +00:00
Merge pull request #2137 from constantine2nd/develop
Show which fields are optional / required in API Explorer
This commit is contained in:
commit
9bbf67dbd4
@ -96,6 +96,12 @@ object ApiRole {
|
||||
|
||||
case class CanGetCustomer(requiresBankId: Boolean = true) extends ApiRole
|
||||
lazy val canGetCustomer = CanGetCustomer()
|
||||
|
||||
case class CanGetCustomerOverview(requiresBankId: Boolean = true) extends ApiRole
|
||||
lazy val canGetCustomerOverview = CanGetCustomerOverview()
|
||||
|
||||
case class CanGetCustomerOverviewFlat(requiresBankId: Boolean = true) extends ApiRole
|
||||
lazy val canGetCustomerOverviewFlat = CanGetCustomerOverviewFlat()
|
||||
|
||||
case class CanCreateCustomer(requiresBankId: Boolean = true) extends ApiRole
|
||||
lazy val canCreateCustomer = CanCreateCustomer()
|
||||
|
||||
50
obp-api/src/main/scala/code/api/util/NotificationUtil.scala
Normal file
50
obp-api/src/main/scala/code/api/util/NotificationUtil.scala
Normal file
@ -0,0 +1,50 @@
|
||||
package code.api.util
|
||||
|
||||
import code.api.Constant
|
||||
import code.entitlement.Entitlement
|
||||
import code.users.Users
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.openbankproject.commons.model.User
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.util.Mailer
|
||||
import net.liftweb.util.Mailer._
|
||||
|
||||
import scala.collection.immutable.List
|
||||
|
||||
object NotificationUtil extends MdcLoggable {
|
||||
def sendEmailRegardingAssignedRole(userId : String, entitlement: Entitlement): Unit = {
|
||||
val user = Users.users.vend.getUserByUserId(userId)
|
||||
sendEmailRegardingAssignedRole(user, entitlement)
|
||||
}
|
||||
def sendEmailRegardingAssignedRole(user: Box[User], entitlement: Entitlement): Unit = {
|
||||
val mailSent = for {
|
||||
user <- user
|
||||
from <- APIUtil.getPropsValue("mail.api.consumer.registered.sender.address") ?~ "Could not send mail: Missing props param for 'from'"
|
||||
} yield {
|
||||
val bodyOfMessage : String = s"""Dear ${user.name},
|
||||
|
|
||||
|You have been granted the entitlement to use ${entitlement.roleName} on ${Constant.HostName}
|
||||
|
|
||||
|Cheers
|
||||
|""".stripMargin
|
||||
val params = PlainMailBodyType(bodyOfMessage) :: List(To(user.emailAddress))
|
||||
val subjectOfMessage = "You have been granted the role"
|
||||
//this is an async call
|
||||
Mailer.sendMail(
|
||||
From(from),
|
||||
Subject(subjectOfMessage),
|
||||
params :_*
|
||||
)
|
||||
}
|
||||
if(mailSent.isEmpty) {
|
||||
val info =
|
||||
s"""
|
||||
|Sending email is omitted.
|
||||
|User: $user
|
||||
|Props mail.api.consumer.registered.sender.address: ${APIUtil.getPropsValue("mail.api.consumer.registered.sender.address")}
|
||||
|""".stripMargin
|
||||
this.logger.warn(info)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -408,7 +408,7 @@ object JSONFactory1_4_0 extends MdcLoggable{
|
||||
|
||||
if(findMatches.nonEmpty) {
|
||||
val urlParameters: List[String] = findMatches.toList.sorted
|
||||
val parametersDescription: List[String] = urlParameters.map(prepareDescription)
|
||||
val parametersDescription: List[String] = urlParameters.map(i => prepareDescription(i, Nil))
|
||||
parametersDescription.mkString("\n\n\n**URL Parameters:**", "", "\n")
|
||||
} else {
|
||||
""
|
||||
@ -420,31 +420,44 @@ object JSONFactory1_4_0 extends MdcLoggable{
|
||||
* @param parameter BANK_ID
|
||||
* @return [BANK_ID](/glossary#Bank.bank_id):gh.29.uk
|
||||
*/
|
||||
def prepareDescription(parameter: String): String = {
|
||||
def prepareDescription(parameter: String, types: List[(String, Boolean)]): String = {
|
||||
val glossaryItemTitle = getGlossaryItemTitle(parameter)
|
||||
val exampleFieldValue = getExampleFieldValue(parameter)
|
||||
def boldIfMandatory() = {
|
||||
types.exists(i => i._1 == parameter && i._2 == false) match {
|
||||
case true =>
|
||||
s"**$parameter**"
|
||||
case false =>
|
||||
s"$parameter"
|
||||
}
|
||||
}
|
||||
if(exampleFieldValue.contains(ExampleValue.NoExampleProvided)){
|
||||
""
|
||||
} else {
|
||||
s"""
|
||||
|
|
||||
|* [${parameter}](/glossary#$glossaryItemTitle): $exampleFieldValue
|
||||
|* [${boldIfMandatory()}](/glossary#$glossaryItemTitle): $exampleFieldValue
|
||||
|
|
||||
|""".stripMargin
|
||||
}
|
||||
}
|
||||
|
||||
def prepareJsonFieldDescription(jsonBody: scala.Product, jsonType: String): String = {
|
||||
|
||||
val jsonBodyJValue = jsonBody match {
|
||||
jsonBody.productIterator
|
||||
val (jsonBodyJValue: json.JValue, types) = jsonBody match {
|
||||
case JvalueCaseClass(jValue) =>
|
||||
jValue
|
||||
case _ => decompose(jsonBody)
|
||||
val types = Nil
|
||||
(jValue, types)
|
||||
case _ =>
|
||||
val types = jsonBody.getClass()
|
||||
.getDeclaredFields().toList
|
||||
.map(f => (f.getName(), f.getType().getCanonicalName().contains("Option")))
|
||||
(decompose(jsonBody), types)
|
||||
}
|
||||
|
||||
val jsonBodyFields =JsonUtils.collectFieldNames(jsonBodyJValue).keySet.toList.sorted
|
||||
|
||||
val jsonFieldsDescription = jsonBodyFields.map(prepareDescription)
|
||||
val jsonFieldsDescription = jsonBodyFields.map(i => prepareDescription(i, types))
|
||||
|
||||
val jsonTitleType = if (jsonType.contains("request")) "\n\n\n**JSON request body fields:**\n\n" else "\n\n\n**JSON response body fields:**\n\n"
|
||||
|
||||
|
||||
@ -1040,21 +1040,17 @@ trait APIMethods500 {
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagCustomer, apiTagKyc ,apiTagNewStyle),
|
||||
Some(List(canGetCustomer))
|
||||
Some(List(canGetCustomerOverview))
|
||||
)
|
||||
|
||||
lazy val getCustomerOverview : OBPEndpoint = {
|
||||
case "banks" :: BankId(bankId) :: "customers" :: "customer-number-query" :: "overview" :: Nil JsonPost json -> req => {
|
||||
cc =>
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
(bank, callContext) <- NewStyle.function.getBank(bankId, callContext)
|
||||
_ <- NewStyle.function.hasEntitlement(bankId.value, u.userId, canGetCustomer, callContext)
|
||||
failMsg = s"$InvalidJsonFormat The Json body should be the $PostCustomerOverviewJsonV500 "
|
||||
postedData <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PostCustomerOverviewJsonV500 ", 400, cc.callContext) {
|
||||
json.extract[PostCustomerOverviewJsonV500]
|
||||
}
|
||||
(customer, callContext) <- NewStyle.function.getCustomerByCustomerNumber(postedData.customer_number, bank.bankId, callContext)
|
||||
(customer, callContext) <- NewStyle.function.getCustomerByCustomerNumber(postedData.customer_number, bankId, cc.callContext)
|
||||
(customerAttributes, callContext) <- NewStyle.function.getCustomerAttributes(
|
||||
bankId,
|
||||
CustomerId(customer.customerId),
|
||||
@ -1093,21 +1089,17 @@ trait APIMethods500 {
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagCustomer, apiTagKyc ,apiTagNewStyle),
|
||||
Some(List(canGetCustomer))
|
||||
Some(List(canGetCustomerOverviewFlat))
|
||||
)
|
||||
|
||||
lazy val getCustomerOverviewFlat : OBPEndpoint = {
|
||||
case "banks" :: BankId(bankId) :: "customers" :: "customer-number-query" :: "overview-flat" :: Nil JsonPost json -> req => {
|
||||
cc =>
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
(bank, callContext) <- NewStyle.function.getBank(bankId, callContext)
|
||||
_ <- NewStyle.function.hasEntitlement(bankId.value, u.userId, canGetCustomer, callContext)
|
||||
failMsg = s"$InvalidJsonFormat The Json body should be the $PostCustomerOverviewJsonV500 "
|
||||
postedData <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PostCustomerOverviewJsonV500 ", 400, cc.callContext) {
|
||||
json.extract[PostCustomerOverviewJsonV500]
|
||||
}
|
||||
(customer, callContext) <- NewStyle.function.getCustomerByCustomerNumber(postedData.customer_number, bank.bankId, callContext)
|
||||
(customer, callContext) <- NewStyle.function.getCustomerByCustomerNumber(postedData.customer_number, bankId, cc.callContext)
|
||||
(customerAttributes, callContext) <- NewStyle.function.getCustomerAttributes(
|
||||
bankId,
|
||||
CustomerId(customer.customerId),
|
||||
|
||||
@ -2,7 +2,7 @@ package code.entitlement
|
||||
|
||||
import code.api.dynamic.endpoint.helper.DynamicEntityInfo
|
||||
import code.api.util.ApiRole.{CanCreateEntitlementAtAnyBank, CanCreateEntitlementAtOneBank}
|
||||
import code.api.util.ErrorMessages
|
||||
import code.api.util.{ErrorMessages, NotificationUtil}
|
||||
import code.util.{MappedUUID, UUIDString}
|
||||
import net.liftweb.common.{Box, Failure, Full}
|
||||
import net.liftweb.mapper._
|
||||
@ -110,6 +110,8 @@ object MappedEntitlementsProvider extends EntitlementProvider {
|
||||
val addEntitlement: MappedEntitlement =
|
||||
MappedEntitlement.create.mBankId(bankId).mUserId(userId).mRoleName(roleName).mCreatedByProcess(createdByProcess)
|
||||
.saveMe()
|
||||
// When a role is Granted, we should send an email to the Recipient telling them they have been granted the role.
|
||||
NotificationUtil.sendEmailRegardingAssignedRole(userId: String, addEntitlement: Entitlement)
|
||||
Full(addEntitlement)
|
||||
}
|
||||
// Return a Box so we can handle errors later.
|
||||
|
||||
@ -47,7 +47,7 @@ class JSONFactory1_4_0Test extends V140ServerSetup with DefaultUsers {
|
||||
feature("Test JSONFactory1_4_0") {
|
||||
|
||||
scenario("prepareDescription should work well, extract the parameters from URL") {
|
||||
val description = JSONFactory1_4_0.prepareDescription("BANK_ID")
|
||||
val description = JSONFactory1_4_0.prepareDescription("BANK_ID", Nil)
|
||||
description.contains("[BANK_ID](/glossary#Bank.bank_id): gh.29.uk") should be (true)
|
||||
}
|
||||
|
||||
|
||||
@ -87,13 +87,13 @@ class CustomerOverviewTest extends V500ServerSetup {
|
||||
val response = makePostRequest(request, write(getCustomerJson))
|
||||
Then("We should get a 403")
|
||||
response.code should equal(403)
|
||||
And("error should be " + canGetCustomer)
|
||||
And("error should be " + canGetCustomerOverview)
|
||||
val errorMessage = response.body.extract[ErrorMessage].message
|
||||
errorMessage contains (UserHasMissingRoles) should be (true)
|
||||
errorMessage contains (canGetCustomer.toString()) should be (true)
|
||||
errorMessage contains (canGetCustomerOverview.toString()) should be (true)
|
||||
}
|
||||
scenario(s"We will call the endpoint $ApiEndpoint1 with a user credentials and a proper role", ApiEndpoint1, VersionOfApi) {
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomer.toString)
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomerOverview.toString)
|
||||
When(s"We make a request $VersionOfApi")
|
||||
val request = (v5_0_0_Request / "banks" / bankId / "customers" / "customer-number-query" / "overview").POST <@(user1)
|
||||
val response = makePostRequest(request, write(getCustomerJson))
|
||||
@ -106,7 +106,7 @@ class CustomerOverviewTest extends V500ServerSetup {
|
||||
val legalName = "Evelin Doe"
|
||||
val mobileNumber = "+44 123 456"
|
||||
val customer: CustomerJsonV310 = createCustomerEndpointV500(bankId, legalName, mobileNumber)
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomer.toString)
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomerOverview.toString)
|
||||
When(s"We make a request $VersionOfApi")
|
||||
val request = (v5_0_0_Request / "banks" / bankId / "customers" / "customer-number-query" / "overview").POST <@(user1)
|
||||
val response = makePostRequest(request, write(PostCustomerOverviewJsonV500(customer.customer_number)))
|
||||
@ -140,13 +140,13 @@ class CustomerOverviewTest extends V500ServerSetup {
|
||||
val response = makePostRequest(request, write(getCustomerJson))
|
||||
Then("We should get a 403")
|
||||
response.code should equal(403)
|
||||
And("error should be " + canGetCustomer)
|
||||
And("error should be " + canGetCustomerOverviewFlat)
|
||||
val errorMessage = response.body.extract[ErrorMessage].message
|
||||
errorMessage contains (UserHasMissingRoles) should be (true)
|
||||
errorMessage contains (canGetCustomer.toString()) should be (true)
|
||||
errorMessage contains (canGetCustomerOverviewFlat.toString()) should be (true)
|
||||
}
|
||||
scenario(s"We will call the endpoint $ApiEndpoint2 with a user credentials and a proper role", ApiEndpoint1, VersionOfApi) {
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomer.toString)
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomerOverviewFlat.toString)
|
||||
When(s"We make a request $VersionOfApi")
|
||||
val request = (v5_0_0_Request / "banks" / bankId / "customers" / "customer-number-query" / "overview-flat").POST <@(user1)
|
||||
val response = makePostRequest(request, write(getCustomerJson))
|
||||
@ -159,7 +159,7 @@ class CustomerOverviewTest extends V500ServerSetup {
|
||||
val legalName = "Evelin Doe"
|
||||
val mobileNumber = "+44 123 456"
|
||||
val customer: CustomerJsonV310 = createCustomerEndpointV500(bankId, legalName, mobileNumber)
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomer.toString)
|
||||
Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, CanGetCustomerOverviewFlat.toString)
|
||||
When(s"We make a request $VersionOfApi")
|
||||
val request = (v5_0_0_Request / "banks" / bankId / "customers" / "customer-number-query" / "overview-flat").POST <@(user1)
|
||||
val response = makePostRequest(request, write(PostCustomerOverviewJsonV500(customer.customer_number)))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user