Merge branch 'hw-develop' into s-develop

This commit is contained in:
shuang 2020-03-27 21:10:00 +08:00
commit 8a84b4aeee
4 changed files with 221 additions and 33 deletions

View File

@ -604,7 +604,7 @@ object ExampleValue {
|}
|""".stripMargin
lazy val dynamicEndpointRequestBodyExample = json.parse(dynamicEndpointSwagger).asInstanceOf[JObject]
lazy val dynamicEndpointResponseBodyExample = ("dynamicEndpointId", "dynamic-endpoint-id") ~ ("swaggerString", dynamicEndpointRequestBodyExample)
lazy val dynamicEndpointResponseBodyExample = ("dynamic_endpoint_id", "dynamic-endpoint-id") ~ ("swagger_string", dynamicEndpointRequestBodyExample)
}

View File

@ -1997,12 +1997,6 @@ object NewStyle {
getConnectorByName(connectorName).flatMap(_.implementedMethods.get(methodName))
}
def deleteCustomerAttribute(customerAttributeId : String, callContext: Option[CallContext]): OBPReturnType[Boolean] = {
Connector.connector.vend.deleteCustomerAttribute(customerAttributeId, callContext) map {
i => (connectorEmptyResponse(i._1, callContext), i._2)
}
}
def createDynamicEndpoint(swaggerString: String, callContext: Option[CallContext]): OBPReturnType[DynamicEndpointT] = {
Connector.connector.vend.createDynamicEndpoint(
swaggerString,
@ -2024,7 +2018,13 @@ object NewStyle {
def getDynamicEndpoints(callContext: Option[CallContext]): OBPReturnType[List[DynamicEndpointT]] = {
Connector.connector.vend.getDynamicEndpoints(
callContext
)
)
}
def deleteCustomerAttribute(customerAttributeId : String, callContext: Option[CallContext]): OBPReturnType[Boolean] = {
Connector.connector.vend.deleteCustomerAttribute(customerAttributeId, callContext) map {
i => (connectorEmptyResponse(i._1, callContext), i._2)
}
}
}

View File

@ -3,7 +3,7 @@ package code.api.v4_0_0
import java.util.Date
import code.DynamicData.DynamicData
import code.DynamicEndpoint.DynamicEndpointSwagger
import code.DynamicEndpoint.{DynamicEndpointCommons, DynamicEndpointSwagger}
import code.accountattribute.AccountAttributeX
import code.api.ChargePolicy
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
@ -678,7 +678,7 @@ trait APIMethods400 {
|
|3) `id` : is `challenge.id` field in createTransactionRequest response body.
|
|4) `answer` : must be `123` in case that Strong Customer Authentication method for OTP challenge is dummy.
|4) `answer` : must be `123` in case that Strong Customer Authentication method for OTP challenge is dummy.
| For instance: SANDBOX_TAN_OTP_INSTRUCTION_TRANSPORT=dummy
| Possible values are dummy,email and sms
| In kafka mode, the answer can be got by phone message or other security ways.
@ -687,11 +687,11 @@ trait APIMethods400 {
| INITIATED => COMPLETED
|In case n persons needs to answer security challenge we have next flow of state of an `transaction request`:
| INITIATED => NEXT_CHALLENGE_PENDING => ... => NEXT_CHALLENGE_PENDING => COMPLETED
|
|
|The security challenge is bound to a user i.e. in case of right answer and the user is different than expected one the challenge will fail.
|
|Rule for calculating number of security challenges:
|If product Account attribute REQUIRED_CHALLENGE_ANSWERS=N then create N challenges
|If product Account attribute REQUIRED_CHALLENGE_ANSWERS=N then create N challenges
|(one for every user that has a View where permission "can_add_transaction_request_to_any_account"=true)
|In case REQUIRED_CHALLENGE_ANSWERS is not defined as an account attribute default value is 1.
|
@ -734,14 +734,14 @@ trait APIMethods400 {
account = BankIdAccountId(fromAccount.bankId, fromAccount.accountId)
_ <- NewStyle.function.checkAuthorisationToCreateTransactionRequest(viewId, account, u, cc.callContext)
// Check transReqId is valid
(existingTransactionRequest, callContext) <- NewStyle.function.getTransactionRequestImpl(transReqId, cc.callContext)
// Check the Transaction Request is still INITIATED
_ <- Helper.booleanToFuture(TransactionRequestStatusNotInitiatedOrPending) {
existingTransactionRequest.status.equals(TransactionRequestStatus.INITIATED.toString) ||
existingTransactionRequest.status.equals(TransactionRequestStatus.NEXT_CHALLENGE_PENDING.toString)
existingTransactionRequest.status.equals(TransactionRequestStatus.NEXT_CHALLENGE_PENDING.toString)
}
// Check the input transactionRequestType is the same as when the user created the TransactionRequest
@ -815,8 +815,8 @@ trait APIMethods400 {
nameOf(getDynamicEntities),
"GET",
"/management/dynamic-entities",
"Get DynamicEntities",
s"""Get the all DynamicEntities.""",
"Get Dynamic Entities",
s"""Get the all Dynamic Entities.""",
emptyObjectJson,
ListResult(
"dynamic_entities",
@ -852,7 +852,7 @@ trait APIMethods400 {
nameOf(createDynamicEntity),
"POST",
"/management/dynamic-entities",
"Create DynamicEntity",
"Create Dynamic Entity",
s"""Create a DynamicEntity.
|
|
@ -903,7 +903,7 @@ trait APIMethods400 {
nameOf(updateDynamicEntity),
"PUT",
"/management/dynamic-entities/DYNAMIC_ENTITY_ID",
"Update DynamicEntity",
"Update Dynamic Entity",
s"""Update a DynamicEntity.
|
|
@ -961,7 +961,7 @@ trait APIMethods400 {
nameOf(deleteDynamicEntity),
"DELETE",
"/management/dynamic-entities/DYNAMIC_ENTITY_ID",
"Delete DynamicEntity",
"Delete Dynamic Entity",
s"""Delete a DynamicEntity specified by DYNAMIC_ENTITY_ID.
|
|""",
@ -1174,7 +1174,7 @@ trait APIMethods400 {
hasEntitlement(bankId.value, loggedInUserId, canCreateAccount) || userIdAccountOwner == loggedInUserId
}
initialBalanceAsString = createAccountJson.balance.amount
//Note: here we map the product_code to account_type
//Note: here we map the product_code to account_type
accountType = createAccountJson.product_code
accountLabel = createAccountJson.label
initialBalanceAsNumber <- NewStyle.function.tryons(InvalidAccountInitialBalance, 400, callContext) {
@ -1215,9 +1215,9 @@ trait APIMethods400 {
}
}
}
private def getApiInfoJSON() = {
val (apiVersion, apiVersionStatus) = (implementedInApiVersion, OBPAPI4_0_0.versionStatus)
val organisation = APIUtil.getPropsValue("hosted_by.organisation", "TESOBE")
@ -1759,9 +1759,9 @@ trait APIMethods400 {
(_, callContext) <- NewStyle.function.getCounterpartyByCounterpartyId(CounterpartyId(postJson.counterparty_id), callContext)
(directDebit, callContext) <- NewStyle.function.createDirectDebit(
bankId.value,
accountId.value,
postJson.customer_id,
postJson.user_id,
accountId.value,
postJson.customer_id,
postJson.user_id,
postJson.counterparty_id,
if (postJson.date_signed.isDefined) postJson.date_signed.get else new Date(),
postJson.date_starts,
@ -1829,7 +1829,7 @@ trait APIMethods400 {
}
}
}
resourceDocs += ResourceDoc(
createStandingOrder,
implementedInApiVersion,
@ -2030,8 +2030,8 @@ trait APIMethods400 {
}
}
}
resourceDocs += ResourceDoc(
revokeUserAccessToView,
implementedInApiVersion,
@ -2338,8 +2338,8 @@ trait APIMethods400 {
}
}
}
resourceDocs += ResourceDoc(
createTransactionAttribute,
implementedInApiVersion,
@ -2651,7 +2651,7 @@ trait APIMethods400 {
}
}
resourceDocs += ResourceDoc(
createConsumer,
implementedInApiVersion,
@ -2886,7 +2886,7 @@ trait APIMethods400 {
} yield {
val resultList = dynamicEndpoints.map[JObject, List[JObject]] { dynamicEndpoint=>
val swaggerJson = parse(dynamicEndpoint.swaggerString)
("dynamicEndpointId", dynamicEndpoint.dynamicEndpointId) ~ ("swaggerString", swaggerJson)
("dynamic_endpoint_id", dynamicEndpoint.dynamicEndpointId) ~ ("swagger_string", swaggerJson)
}
(ListResult("dynamic_endpoints", resultList), HttpCode.`200`(cc.callContext))
}

View File

@ -0,0 +1,188 @@
package code.api.v4_0_0
import code.api.util.APIUtil.OAuth._
import code.api.util.ApiRole._
import code.api.util.ErrorMessages.{UserHasMissingRoles, UserNotLoggedIn}
import code.api.util.ExampleValue
import code.api.v4_0_0.OBPAPI4_0_0.Implementations4_0_0
import code.entitlement.Entitlement
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.model.ErrorMessage
import com.openbankproject.commons.util.ApiVersion
import net.liftweb.json.Serialization.write
import org.scalatest.Tag
class DynamicEndpointsTest extends V400ServerSetup {
/**
* 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.v4_0_0.toString)
object ApiEndpoint1 extends Tag(nameOf(Implementations4_0_0.createDynamicEndpoint))
object ApiEndpoint2 extends Tag(nameOf(Implementations4_0_0.getDynamicEndpoints))
object ApiEndpoint3 extends Tag(nameOf(Implementations4_0_0.getDynamicEndpoint))
feature(s"test $ApiEndpoint1 version $VersionOfApi - Unauthorized access") {
scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
val postDynamicEndpointRequestBodyExample = ExampleValue.dynamicEndpointRequestBodyExample
When("We make a request v4.0.0")
val request400 = (v4_0_0_Request / "management" / "dynamic-endpoints").POST
val response400 = makePostRequest(request400, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 400")
response400.code should equal(400)
response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
}
}
feature(s"test $ApiEndpoint1 version $VersionOfApi - authorized access- missing role") {
scenario("We will call the endpoint with user credentials", ApiEndpoint1, VersionOfApi) {
val postDynamicEndpointRequestBodyExample = ExampleValue.dynamicEndpointRequestBodyExample
When("We make a request v4.0.0")
val request = (v4_0_0_Request / "management" / "dynamic-endpoints").POST<@ (user1)
val response = makePostRequest(request, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 403")
response.code should equal(403)
response.body.extract[ErrorMessage].message.toString contains (UserHasMissingRoles) should be (true)
}
}
feature(s"test $ApiEndpoint1 version $VersionOfApi - authorized access - with role - should be success!") {
scenario("We will call the endpoint with user credentials", ApiEndpoint1, VersionOfApi) {
When("We make a request v4.0.0")
val postDynamicEndpointRequestBodyExample = ExampleValue.dynamicEndpointRequestBodyExample
When("We make a request v4.0.0")
val request = (v4_0_0_Request / "management" / "dynamic-endpoints").POST<@ (user1)
val response = makePostRequest(request, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 403")
response.code should equal(403)
response.body.extract[ErrorMessage].message.toString contains (UserHasMissingRoles) should be (true)
Then("We grant the role to the user1")
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, canCreateDynamicEndpoint.toString)
val responseWithRole = makePostRequest(request, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 201")
responseWithRole.code should equal(201)
responseWithRole.body.toString contains("dynamic_endpoint_id") should be (true)
responseWithRole.body.toString contains("swagger_string") should be (true)
responseWithRole.body.toString contains("Portus EVS sandbox demo API") should be (true)
responseWithRole.body.toString contains("content user-friendly error message") should be (true)
responseWithRole.body.toString contains("create user successful and return created user object") should be (true)
}
}
feature(s"test $ApiEndpoint2 version $VersionOfApi - Unauthorized access") {
scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
When("We make a request v4.0.0")
val request400 = (v4_0_0_Request / "management" / "dynamic-endpoints").GET
val response400 = makeGetRequest(request400)
Then("We should get a 400")
response400.code should equal(400)
response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
}
}
feature(s"test $ApiEndpoint2 version $VersionOfApi - authorized access- missing role") {
scenario("We will call the endpoint with user credentials", ApiEndpoint1, VersionOfApi) {
When("We make a request v4.0.0")
val request = (v4_0_0_Request / "management" / "dynamic-endpoints").GET<@ (user1)
val response = makeGetRequest(request)
Then("We should get a 400")
response.code should equal(403)
response.body.extract[ErrorMessage].message.toString contains (UserHasMissingRoles) should be (true)
}
}
feature(s"test $ApiEndpoint2 version $VersionOfApi - authorized access - with role - should be success!") {
scenario("We will call the endpoint with user credentials", ApiEndpoint1, VersionOfApi) {
When("We make a request v4.0.0")
val postDynamicEndpointRequestBodyExample = ExampleValue.dynamicEndpointRequestBodyExample
When("We make a request v4.0.0")
val request = (v4_0_0_Request / "management" / "dynamic-endpoints").POST<@ (user1)
val response = makePostRequest(request, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 403")
response.code should equal(403)
response.body.extract[ErrorMessage].message.toString contains (UserHasMissingRoles) should be (true)
Then("We grant the role to the user1")
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetDynamicEndpoints.toString)
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateDynamicEndpoint.toString)
val responseWithRole = makePostRequest(request, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 201")
responseWithRole.code should equal(201)
val request400 = (v4_0_0_Request / "management" / "dynamic-endpoints").GET<@ (user1)
val response400 = makeGetRequest(request400)
response400.code should be (200)
response400.body.toString contains("Portus EVS sandbox demo API") should be (true)
response400.body.toString contains("content user-friendly error message") should be (true)
response400.body.toString contains("create user successful and return created user object") should be (true)
}
}
feature(s"test $ApiEndpoint3 version $VersionOfApi - Unauthorized access") {
scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
When("We make a request v4.0.0")
val request400 = (v4_0_0_Request / "management" / "dynamic-endpoints"/ "some-id").GET
val response400 = makeGetRequest(request400)
Then("We should get a 400")
response400.code should equal(400)
response400.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
}
}
feature(s"test $ApiEndpoint3 version $VersionOfApi - authorized access- missing role") {
scenario("We will call the endpoint with user credentials", ApiEndpoint1, VersionOfApi) {
When("We make a request v4.0.0")
val request = (v4_0_0_Request / "management" / "dynamic-endpoints" /"some-id").GET<@ (user1)
val response = makeGetRequest(request)
Then("We should get a 400")
response.code should equal(403)
response.body.extract[ErrorMessage].message.toString contains (UserHasMissingRoles) should be (true)
}
}
feature(s"test $ApiEndpoint3 version $VersionOfApi - authorized access - with role - should be success!") {
scenario("We will call the endpoint with user credentials", ApiEndpoint1, VersionOfApi) {
When("We make a request v4.0.0")
val postDynamicEndpointRequestBodyExample = ExampleValue.dynamicEndpointRequestBodyExample
When("We make a request v4.0.0")
val request = (v4_0_0_Request / "management" / "dynamic-endpoints").POST<@ (user1)
val response = makePostRequest(request, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 403")
response.code should equal(403)
response.body.extract[ErrorMessage].message.toString contains (UserHasMissingRoles) should be (true)
Then("We grant the role to the user1")
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetDynamicEndpoint.toString)
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateDynamicEndpoint.toString)
val responseWithRole = makePostRequest(request, write(postDynamicEndpointRequestBodyExample))
Then("We should get a 201")
responseWithRole.code should equal(201)
val id = responseWithRole.body.\\("dynamic_endpoint_id").values.get("dynamic_endpoint_id").head.toString
val request400 = (v4_0_0_Request / "management" / "dynamic-endpoints" /id).GET<@ (user1)
val response400 = makeGetRequest(request400)
response400.code should be (200)
response400.body.toString contains("dynamic_endpoint_id") should be (true)
response400.body.toString contains("swagger_string") should be (true)
response400.body.toString contains("Portus EVS sandbox demo API") should be (true)
response400.body.toString contains("content user-friendly error message") should be (true)
response400.body.toString contains("create user successful and return created user object") should be (true)
}
}
}