diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala index 5a4e7d979..afb8831fd 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/SwaggerDefinitionsJSON.scala @@ -282,7 +282,7 @@ object SwaggerDefinitionsJSON { can_revoke_access_to_views = Some(List("owner")) ) - val updateViewJSON = UpdateViewJSON( + val updateViewJsonV300 = UpdateViewJsonV300( description = "this is for family", is_public = true, metadata_view = SYSTEM_OWNER_VIEW_ID, @@ -361,8 +361,91 @@ object SwaggerDefinitionsJSON { "can_query_available_funds" ) ) + lazy val updateSystemViewJson310 = updateViewJsonV300.copy(is_public = false, is_firehose = Some(false)) - lazy val updateSystemViewJson310 = updateViewJSON.copy(is_public = false, is_firehose = Some(false)) + val updateViewJsonV500 = UpdateViewJsonV500( + description = "this is for family", + is_public = true, + metadata_view = SYSTEM_OWNER_VIEW_ID, + which_alias_to_use = "family", + hide_metadata_if_alias_used = true, + allowed_actions = List( + "can_see_transaction_this_bank_account", + "can_see_transaction_other_bank_account", + "can_see_transaction_metadata", + "can_see_transaction_label", + "can_see_transaction_amount", + "can_see_transaction_type", + "can_see_transaction_currency", + "can_see_transaction_start_date", + "can_see_transaction_finish_date", + "can_see_transaction_balance", + "can_see_comments", + "can_see_narrative", "can_see_tags", + "can_see_images", + "can_see_bank_account_owners", + "can_see_bank_account_type", + "can_see_bank_account_balance", + "can_see_bank_account_currency", + "can_see_bank_account_label", + "can_see_bank_account_national_identifier", + "can_see_bank_account_swift_bic", + "can_see_bank_account_iban", + "can_see_bank_account_number", + "can_see_bank_account_bank_name", + "can_see_other_account_national_identifier", + "can_see_other_account_swift_bic", + "can_see_other_account_iban", + "can_see_other_account_bank_name", + "can_see_other_account_number", + "can_see_other_account_metadata", + "can_see_other_account_kind", + "can_see_more_info", + "can_see_url", + "can_see_image_url", + "can_see_open_corporates_url", + "can_see_corporate_location", + "can_see_physical_location", + "can_see_public_alias", + "can_see_private_alias", + "can_add_more_info", + "can_add_url", + "can_add_image_url", + "can_add_open_corporates_url", + "can_add_corporate_location", + "can_add_physical_location", + "can_add_public_alias", + "can_add_private_alias", + "can_delete_corporate_location", + "can_delete_physical_location", + "can_edit_narrative", + "can_add_comment", + "can_delete_comment", + "can_add_tag", + "can_delete_tag", + "can_add_image", + "can_delete_image", + "can_add_where_tag", + "can_see_where_tag", + "can_delete_where_tag", + "can_create_counterparty", + //V300 New + "can_see_bank_routing_scheme", + "can_see_bank_routing_address", + "can_see_bank_account_routing_scheme", + "can_see_bank_account_routing_address", + "can_see_other_bank_routing_scheme", + "can_see_other_bank_routing_address", + "can_see_other_account_routing_scheme", + "can_see_other_account_routing_address", + //v310 + "can_query_available_funds" + ), + // Version 5.0.0 + can_grant_access_to_views = Some(List("owner")), + can_revoke_access_to_views = Some(List("owner")) + ) + lazy val updateSystemViewJson500 = updateViewJsonV500.copy(is_public = false, is_firehose = Some(false)) val transactionTypeIdSwagger = TransactionTypeId(value = "123") diff --git a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala index 8dd586a68..8c5e0cdd2 100644 --- a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala +++ b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala @@ -233,7 +233,7 @@ trait APIMethods300 { | |The json sent is the same as during view creation (above), with one difference: the 'name' field |of a view is not editable (it is only set when a view is created)""", - updateViewJSON, + updateViewJsonV300, viewJsonV300, List( InvalidJsonFormat, @@ -251,7 +251,7 @@ trait APIMethods300 { val res = for { (Full(u), callContext) <- authenticatedAccess(cc) - updateJson <- Future { tryo{json.extract[UpdateViewJSON]} } map { + updateJson <- Future { tryo{json.extract[UpdateViewJsonV300]} } map { val msg = s"$InvalidJsonFormat The Json body should be the $UpdateViewJSON " x => unboxFullOrFail(x, callContext, msg) } @@ -270,7 +270,7 @@ trait APIMethods300 { (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) } yield { for { - updatedView <- account.updateView(u, viewId, updateJson) + updatedView <- account.updateView(u, viewId, updateJson.toUpdateViewJson) } yield { (JSONFactory300.createViewJSON(updatedView), HttpCode.`200`(callContext)) } diff --git a/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala b/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala index 6fad31d2d..330543c9f 100644 --- a/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala +++ b/obp-api/src/main/scala/code/api/v3_0_0/JSONFactory3.0.0.scala @@ -90,6 +90,25 @@ case class CreateViewJsonV300( allowed_actions = this.allowed_actions ) } +case class UpdateViewJsonV300( + description: String, + metadata_view: String, + is_public: Boolean, + is_firehose: Option[Boolean] = None, + which_alias_to_use: String, + hide_metadata_if_alias_used: Boolean, + allowed_actions: List[String] +) { + def toUpdateViewJson = UpdateViewJSON( + description = this.description, + metadata_view = this.metadata_view, + is_public = this.is_public, + is_firehose = this.is_firehose, + which_alias_to_use = this.which_alias_to_use, + hide_metadata_if_alias_used = this.hide_metadata_if_alias_used, + allowed_actions = this.allowed_actions + ) +} case class ViewsJsonV300( views : List[ViewJsonV300] ) diff --git a/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala b/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala index 503015d0d..e276b2ebb 100644 --- a/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala +++ b/obp-api/src/main/scala/code/api/v5_0_0/APIMethods500.scala @@ -37,6 +37,7 @@ import net.liftweb.http.Req import net.liftweb.http.rest.RestHelper import net.liftweb.json import net.liftweb.json.{Extraction, compactRender, prettyRender} +import net.liftweb.util.Helpers.tryo import net.liftweb.util.Props import scala.collection.immutable.{List, Nil} @@ -1591,8 +1592,55 @@ trait APIMethods500 { } } } - + + staticResourceDocs += ResourceDoc( + updateSystemView, + implementedInApiVersion, + nameOf(updateSystemView), + "PUT", + "/system-views/VIEW_ID", + "Update System View", + s"""Update an existing view on a bank account + | + |${authenticationRequiredMessage(true)} and the user needs to have access to the owner view. + | + |The json sent is the same as during view creation (above), with one difference: the 'name' field + |of a view is not editable (it is only set when a view is created)""", + updateSystemViewJson500, + viewJsonV500, + List( + InvalidJsonFormat, + UserNotLoggedIn, + BankAccountNotFound, + UnknownError + ), + List(apiTagSystemView, apiTagNewStyle), + Some(List(canUpdateSystemView)) + ) + + lazy val updateSystemView : OBPEndpoint = { + //updates a view on a bank account + case "system-views" :: viewId :: Nil JsonPut json -> _ => { + cc => + for { + (Full(user), callContext) <- authenticatedAccess(cc) + _ <- NewStyle.function.hasEntitlement("", user.userId, canUpdateSystemView, callContext) + updateJson <- Future { tryo{json.extract[UpdateViewJsonV500]} } map { + val msg = s"$InvalidJsonFormat The Json body should be the $UpdateViewJSON " + x => unboxFullOrFail(x, callContext, msg) + } + _ <- Helper.booleanToFuture(SystemViewCannotBePublicError, failCode=400, cc=callContext) { + updateJson.is_public == false + } + _ <- NewStyle.function.systemView(ViewId(viewId), callContext) + updatedView <- NewStyle.function.updateSystemView(ViewId(viewId), updateJson.toUpdateViewJson, callContext) + } yield { + (JSONFactory310.createViewJSON(updatedView), HttpCode.`200`(callContext)) + } + } + } + staticResourceDocs += ResourceDoc( createCustomerAccountLink, implementedInApiVersion, diff --git a/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala b/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala index 6865bdd21..55557908e 100644 --- a/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala +++ b/obp-api/src/main/scala/code/api/v5_0_0/JSONFactory5.0.0.scala @@ -393,7 +393,29 @@ case class CreateViewJsonV500( can_revoke_access_to_views = this.can_revoke_access_to_views ) } - +case class UpdateViewJsonV500( + description: String, + metadata_view: String, + is_public: Boolean, + is_firehose: Option[Boolean] = None, + which_alias_to_use: String, + hide_metadata_if_alias_used: Boolean, + allowed_actions: List[String], + can_grant_access_to_views : Option[List[String]] = None, + can_revoke_access_to_views : Option[List[String]] = None + ) { + def toUpdateViewJson = UpdateViewJSON( + description = this.description, + metadata_view = this.metadata_view, + is_public = this.is_public, + is_firehose = this.is_firehose, + which_alias_to_use = this.which_alias_to_use, + hide_metadata_if_alias_used = this.hide_metadata_if_alias_used, + allowed_actions = this.allowed_actions, + can_grant_access_to_views = this.can_grant_access_to_views, + can_revoke_access_to_views = this.can_revoke_access_to_views + ) +} case class ViewsJsonV500(views : List[ViewJsonV500]) case class ViewJsonV500( diff --git a/obp-api/src/test/scala/code/api/v5_0_0/SystemViewsTests.scala b/obp-api/src/test/scala/code/api/v5_0_0/SystemViewsTests.scala index 2373dc4f4..47e3358a5 100644 --- a/obp-api/src/test/scala/code/api/v5_0_0/SystemViewsTests.scala +++ b/obp-api/src/test/scala/code/api/v5_0_0/SystemViewsTests.scala @@ -33,7 +33,6 @@ import code.api.util.APIUtil import code.api.util.APIUtil.OAuth._ import code.api.util.ApiRole.{CanCreateSystemView, CanDeleteSystemView, CanGetSystemView, CanUpdateSystemView} import code.api.util.ErrorMessages.{UserHasMissingRoles, UserNotLoggedIn} -import code.api.v3_0_0.ViewJsonV300 import code.api.v3_1_0.APIMethods310.Implementations3_1_0 import code.api.v5_0_0.APIMethods500.Implementations5_0_0 import code.entitlement.Entitlement @@ -67,7 +66,7 @@ class SystemViewsTests extends V500ServerSetup { object VersionOfApi extends Tag(ApiVersion.v5_0_0.toString) object ApiEndpoint1 extends Tag(nameOf(Implementations5_0_0.getSystemView)) object ApiEndpoint2 extends Tag(nameOf(Implementations5_0_0.createSystemView)) - object ApiEndpoint3 extends Tag(nameOf(Implementations3_1_0.updateSystemView)) + object ApiEndpoint3 extends Tag(nameOf(Implementations5_0_0.updateSystemView)) object ApiEndpoint4 extends Tag(nameOf(Implementations3_1_0.deleteSystemView)) // Custom view, name starts from `_` @@ -128,7 +127,7 @@ class SystemViewsTests extends V500ServerSetup { val response400 = postSystemView(postBodySystemViewJson, user1) Then("We should get a 201") response400.code should equal(201) - response400.body.extract[ViewJsonV300] + response400.body.extract[ViewJsonV500] } } @@ -189,7 +188,7 @@ class SystemViewsTests extends V500ServerSetup { val updatedAliasToUse = "public" val allowedActions = List("can_see_images", "can_delete_comment") - def viewUpdateJson(originalView : ViewJsonV300) = { + def viewUpdateJson(originalView : ViewJsonV500) = { //it's not perfect, assumes too much about originalView (i.e. randomView(true, "")) UpdateViewJSON( description = updatedViewDescription, @@ -198,7 +197,9 @@ class SystemViewsTests extends V500ServerSetup { is_firehose = Some(true), which_alias_to_use = updatedAliasToUse, hide_metadata_if_alias_used = !originalView.hide_metadata_if_alias_used, - allowed_actions = allowedActions + allowed_actions = allowedActions, + can_grant_access_to_views = Some(originalView.can_grant_access_to_views), + can_revoke_access_to_views = Some(originalView.can_revoke_access_to_views) ) } Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanCreateSystemView.toString) @@ -207,7 +208,7 @@ class SystemViewsTests extends V500ServerSetup { Given("A view exists") val creationReply = postSystemView(postBodySystemViewJson, user1) creationReply.code should equal (201) - val createdView : ViewJsonV300 = creationReply.body.extract[ViewJsonV300] + val createdView : ViewJsonV500 = creationReply.body.extract[ViewJsonV500] createdView.id should not startWith("_") createdView.can_see_images should equal(true) createdView.can_delete_comment should equal(true) @@ -220,7 +221,7 @@ class SystemViewsTests extends V500ServerSetup { val reply = putSystemView(createdView.id, viewUpdateJson(createdView), user1) Then("We should get back the updated view") reply.code should equal (200) - val updatedView = reply.body.extract[ViewJsonV300] + val updatedView = reply.body.extract[ViewJsonV500] updatedView.can_see_images should equal(true) updatedView.can_delete_comment should equal(true) updatedView.can_delete_physical_location should equal(false) diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala b/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala index 8bb090e4d..057b97bb5 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/model/ViewModel.scala @@ -82,7 +82,9 @@ case class UpdateViewJSON( override val is_firehose: Option[Boolean] = None, which_alias_to_use: String, hide_metadata_if_alias_used: Boolean, - allowed_actions: List[String]) extends ViewSpecification + allowed_actions: List[String], + override val can_grant_access_to_views : Option[List[String]] = None, + override val can_revoke_access_to_views : Option[List[String]] = None) extends ViewSpecification