From 7e7fabb09ba6ed209c5667d6babf42a49e4a24a4 Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 01:50:59 +0200 Subject: [PATCH 01/10] refactor(v1.4.0): rewire OBPAPI1_4_0 to http4s, drop APIMethods140 mixin from downstream - Rewrite OBPAPI1_4_0: routes=Nil, allResourceDocs aggregates OBPAPI1_3_0+Http4s140 - Drop APIMethods140 import/mixin from OBPAPI5_1_0 and OBPAPI6_0_0 - Add v1_4_0 skip-filter in ResourceDocsAPIMethods.activeResourceDocs - Fix v1_4_0 case in getResourceDocsList to use OBPAPI1_4_0.allResourceDocs - Update JSONFactory1_4_0Test liftDoc reference to OBPAPI1_3_0 --- .../ResourceDocsAPIMethods.scala | 3 +- .../scala/code/api/v1_4_0/OBPAPI1_4_0.scala | 126 +++--------------- .../scala/code/api/v5_1_0/OBPAPI5_1_0.scala | 2 - .../scala/code/api/v6_0_0/OBPAPI6_0_0.scala | 2 - .../api/v1_4_0/JSONFactory1_4_0Test.scala | 2 +- 5 files changed, 18 insertions(+), 117 deletions(-) diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala index 9f30502b27..92eb4d3e7a 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala @@ -133,7 +133,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth case ApiVersion.v2_2_0 => OBPAPI2_2_0.allResourceDocs case ApiVersion.v2_1_0 => OBPAPI2_1_0.allResourceDocs case ApiVersion.v2_0_0 => OBPAPI2_0_0.allResourceDocs - case ApiVersion.v1_4_0 => Implementations1_4_0.resourceDocs ++ Implementations1_3_0.resourceDocs ++ Implementations1_2_1.resourceDocs + case ApiVersion.v1_4_0 => OBPAPI1_4_0.allResourceDocs case ApiVersion.v1_3_0 => Implementations1_3_0.resourceDocs ++ Implementations1_2_1.resourceDocs case ApiVersion.v1_2_1 => code.api.v1_2_1.Http4s121.resourceDocs case ApiVersion.`dynamic-endpoint` => OBPAPIDynamicEndpoint.allResourceDocs @@ -186,6 +186,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth case ApiVersion.v2_2_0 => resourceDocs // fully on http4s — no Lift route filter case ApiVersion.v2_1_0 => resourceDocs // fully on http4s — no Lift route filter case ApiVersion.v2_0_0 => resourceDocs // fully on http4s — no Lift route filter + case ApiVersion.v1_4_0 => resourceDocs // fully on http4s — no Lift route filter case _ => resourceDocs.filter(rd => versionRoutesClasses.contains(rd.partialFunction.getClass)) } diff --git a/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala b/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala index de40c8e33a..29cfaf17bc 100644 --- a/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala +++ b/obp-api/src/main/scala/code/api/v1_4_0/OBPAPI1_4_0.scala @@ -2,125 +2,29 @@ package code.api.v1_4_0 import scala.language.reflectiveCalls import code.api.OBPRestHelper -import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} -import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} +import code.api.util.APIUtil.OBPEndpoint import code.api.util.VersionedOBPApis +import code.api.v1_3_0.OBPAPI1_3_0 import code.util.Helper.MdcLoggable +import com.openbankproject.commons.util.{ApiVersion, ApiVersionStatus} +/* +This file defines which endpoints from all the versions are available in v1.4.0. +All v1.4.0 endpoints have been migrated to Http4s140 — this object is retained +only for resource-doc aggregation and the Lift dispatch registry. + */ +object OBPAPI1_4_0 extends OBPRestHelper with MdcLoggable with VersionedOBPApis { -object OBPAPI1_4_0 extends OBPRestHelper with APIMethods140 with MdcLoggable with VersionedOBPApis{ - - val version : ApiVersion = ApiVersion.v1_4_0 //"1.4.0" + val version: ApiVersion = ApiVersion.v1_4_0 val versionStatus = ApiVersionStatus.DEPRECATED.toString - lazy val endpointsOf1_2_1 = List( - Implementations1_2_1.getBanks, - Implementations1_2_1.bankById, - Implementations1_2_1.getPrivateAccountsAllBanks, - Implementations1_2_1.privateAccountsAllBanks, - Implementations1_2_1.publicAccountsAllBanks, - Implementations1_2_1.getPrivateAccountsAtOneBank, - Implementations1_2_1.privateAccountsAtOneBank, - Implementations1_2_1.publicAccountsAtOneBank, - Implementations1_2_1.accountById, - Implementations1_2_1.updateAccountLabel, - Implementations1_2_1.getViewsForBankAccount, - Implementations1_2_1.createViewForBankAccount, - Implementations1_2_1.updateViewForBankAccount, - Implementations1_2_1.deleteViewForBankAccount, - Implementations1_2_1.getPermissionsForBankAccount, - Implementations1_2_1.getPermissionForUserForBankAccount, - Implementations1_2_1.addPermissionForUserForBankAccountForMultipleViews, - Implementations1_2_1.addPermissionForUserForBankAccountForOneView, - Implementations1_2_1.removePermissionForUserForBankAccountForOneView, - Implementations1_2_1.removePermissionForUserForBankAccountForAllViews, - Implementations1_2_1.getOtherAccountsForBankAccount, - Implementations1_2_1.getOtherAccountByIdForBankAccount, - Implementations1_2_1.getOtherAccountMetadata, - Implementations1_2_1.getCounterpartyPublicAlias, - Implementations1_2_1.addCounterpartyPublicAlias, - Implementations1_2_1.updateCounterpartyPublicAlias, - Implementations1_2_1.deleteCounterpartyPublicAlias, - Implementations1_2_1.getOtherAccountPrivateAlias, - Implementations1_2_1.addOtherAccountPrivateAlias, - Implementations1_2_1.updateCounterpartyPrivateAlias, - Implementations1_2_1.deleteCounterpartyPrivateAlias, - Implementations1_2_1.addCounterpartyMoreInfo, - Implementations1_2_1.updateCounterpartyMoreInfo, - Implementations1_2_1.deleteCounterpartyMoreInfo, - Implementations1_2_1.addCounterpartyUrl, - Implementations1_2_1.updateCounterpartyUrl, - Implementations1_2_1.deleteCounterpartyUrl, - Implementations1_2_1.addCounterpartyImageUrl, - Implementations1_2_1.updateCounterpartyImageUrl, - Implementations1_2_1.deleteCounterpartyImageUrl, - Implementations1_2_1.addCounterpartyOpenCorporatesUrl, - Implementations1_2_1.updateCounterpartyOpenCorporatesUrl, - Implementations1_2_1.deleteCounterpartyOpenCorporatesUrl, - Implementations1_2_1.addCounterpartyCorporateLocation, - Implementations1_2_1.updateCounterpartyCorporateLocation, - Implementations1_2_1.deleteCounterpartyCorporateLocation, - Implementations1_2_1.addCounterpartyPhysicalLocation, - Implementations1_2_1.updateCounterpartyPhysicalLocation, - Implementations1_2_1.deleteCounterpartyPhysicalLocation, - Implementations1_2_1.getTransactionsForBankAccount, - Implementations1_2_1.getTransactionByIdForBankAccount, - Implementations1_2_1.getTransactionNarrative, - Implementations1_2_1.addTransactionNarrative, - Implementations1_2_1.updateTransactionNarrative, - Implementations1_2_1.deleteTransactionNarrative, - Implementations1_2_1.getCommentsForViewOnTransaction, - Implementations1_2_1.addCommentForViewOnTransaction, - Implementations1_2_1.deleteCommentForViewOnTransaction, - Implementations1_2_1.getTagsForViewOnTransaction, - Implementations1_2_1.addTagForViewOnTransaction, - Implementations1_2_1.deleteTagForViewOnTransaction, - Implementations1_2_1.getImagesForViewOnTransaction, - Implementations1_2_1.addImageForViewOnTransaction, - Implementations1_2_1.deleteImageForViewOnTransaction, - Implementations1_2_1.getWhereTagForViewOnTransaction, - Implementations1_2_1.addWhereTagForViewOnTransaction, - Implementations1_2_1.updateWhereTagForViewOnTransaction, - Implementations1_2_1.deleteWhereTagForViewOnTransaction, - Implementations1_2_1.getOtherAccountForTransaction - //Implementations1_2_1.makePayment // Back for a while - ) - - // New in 1.3.0 - val endpointsOf1_3_0 = List( - Implementations1_3_0.getCards, - Implementations1_3_0.getCardsForBank - ) - - - // New in 1.4.0 - val endpointsOf1_4_0 = List( - Implementations1_4_0.root, - Implementations1_4_0.getCustomer, - Implementations1_4_0.addCustomer, - Implementations1_4_0.getCustomersMessages, - Implementations1_4_0.addCustomerMessage, - Implementations1_4_0.getBranches, - Implementations1_4_0.getAtms, - Implementations1_4_0.getProducts, - Implementations1_4_0.getCrmEvents, - Implementations1_4_0.getTransactionRequestTypes - ) - - - val allResourceDocs = - Implementations1_4_0.resourceDocs ++ - Implementations1_3_0.resourceDocs ++ - Implementations1_2_1.resourceDocs + val Implementations1_4_0 = Http4s140.Implementations1_4_0 - // Filter the possible endpoints by the disabled / enabled Props settings and add them together - val routes : List[OBPEndpoint] = - getAllowedEndpoints(endpointsOf1_2_1, Implementations1_2_1.resourceDocs) ::: - getAllowedEndpoints(endpointsOf1_3_0, Implementations1_3_0.resourceDocs) ::: - getAllowedEndpoints(endpointsOf1_4_0, Implementations1_4_0.resourceDocs) + def allResourceDocs = collectResourceDocs(OBPAPI1_3_0.allResourceDocs, Http4s140.resourceDocs) - registerRoutes(routes, allResourceDocs, apiPrefix) + val routes: List[OBPEndpoint] = Nil - logger.info(s"version $version has been run! There are ${routes.length} routes.") + registerRoutes(routes, allResourceDocs, apiPrefix, true) + logger.info(s"version $version has been run! There are ${routes.length} routes, ${allResourceDocs.length} allResourceDocs.") } diff --git a/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala b/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala index 5f8de5517b..f8c020ea76 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala @@ -31,7 +31,6 @@ import code.api.OBPRestHelper import code.api.util.APIUtil.OBPEndpoint import code.api.util.VersionedOBPApis import code.api.v1_3_0.APIMethods130 -import code.api.v1_4_0.APIMethods140 import code.api.v3_0_0.Http4s300 import code.api.v3_1_0.{APIMethods310, Http4s310} import code.api.v4_0_0.{APIMethods400, Http4s400} @@ -47,7 +46,6 @@ only for resource-doc aggregation and the Lift dispatch registry. */ object OBPAPI5_1_0 extends OBPRestHelper with APIMethods130 - with APIMethods140 with APIMethods310 with APIMethods400 with APIMethods500 diff --git a/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala b/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala index a6c0d2d73b..c45d123252 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala @@ -32,7 +32,6 @@ import code.api.OBPRestHelper import code.api.util.APIUtil.OBPEndpoint import code.api.util.VersionedOBPApis import code.api.v1_3_0.APIMethods130 -import code.api.v1_4_0.APIMethods140 import code.api.v3_0_0.Http4s300 import code.api.v3_1_0.{APIMethods310, Http4s310} import code.api.v4_0_0.{APIMethods400, Http4s400} @@ -49,7 +48,6 @@ only for resource-doc aggregation and the Lift dispatch registry. */ object OBPAPI6_0_0 extends OBPRestHelper with APIMethods130 - with APIMethods140 with APIMethods310 with APIMethods400 with APIMethods500 diff --git a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala index 845f6fc6bd..16f7581fdf 100644 --- a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala +++ b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala @@ -8,7 +8,7 @@ import code.api.util.{APIUtil, ExampleValue} import code.api.util.CustomJsonFormats import code.api.v1_4_0.JSONFactory1_4_0.ResourceDocJson import code.api.v3_0_0.OBPAPI3_0_0 -import code.api.v1_4_0.OBPAPI1_4_0 +import code.api.v1_3_0.OBPAPI1_3_0 import net.liftweb.json.Extraction.decompose import net.liftweb.json._ import org.everit.json.schema.loader.SchemaLoader From b6d77655e5adbfcb5452ed3780f94a0d530c50cc Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 01:51:11 +0200 Subject: [PATCH 02/10] =?UTF-8?q?refactor(v1.4.0):=20stub=20APIMethods140?= =?UTF-8?q?=20=E2=80=94=20replace=20556-line=20Lift=20handler=20with=20emp?= =?UTF-8?q?ty=20trait?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All v1.4.0 endpoints are served by Http4s140. The Lift dispatch code is dead. --- .../scala/code/api/v1_4_0/APIMethods140.scala | 554 +----------------- 1 file changed, 3 insertions(+), 551 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala b/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala index d135f952f6..3ab8787c66 100644 --- a/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala +++ b/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala @@ -1,556 +1,8 @@ package code.api.v1_4_0 -import scala.language.reflectiveCalls -import code.api.Constant._ -import code.api.util.ApiRole._ -import code.api.util.ApiTag._ -import code.api.util.FutureUtil.EndpointContext -import code.api.util.NewStyle.HttpCode -import code.api.util._ -import code.api.util.newstyle.ViewNewStyle -import code.api.v1_2_1.JSONFactory -import code.api.v1_4_0.JSONFactory1_4_0._ -import code.api.v2_0_0.CreateCustomerJson -import code.atms.Atms -import code.bankconnectors.Connector -import code.branches.Branches -import code.customer.CustomerX -import code.usercustomerlinks.UserCustomerLink -import code.util.Helper -import code.views.system.ViewPermission -import com.github.dwickern.macros.NameOf.nameOf -import com.openbankproject.commons.model._ -import com.openbankproject.commons.util.ApiVersion -import net.liftweb.common.{Box, Full} import net.liftweb.http.rest.RestHelper -import net.liftweb.json.Extraction -import net.liftweb.json.JsonAST.JValue -import net.liftweb.util.Helpers.tryo -import net.liftweb.util.Props -import scala.collection.immutable.{List, Nil} -import scala.concurrent.Future - -// JObject creation -import code.api.APIFailure -import code.api.v1_2_1.{APIInfoJSON, APIMethods121, HostedBy} -import code.api.v1_3_0.APIMethods130 - -import scala.collection.mutable.ArrayBuffer -//import code.api.v2_0_0.{OBPAPI2_0_0, APIMethods200} - -// So we can include resource docs from future versions -//import code.api.v1_4_0.JSONFactory1_4_0._ -import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ -import code.api.util.APIUtil._ -import code.api.util.ErrorMessages -import code.api.util.ErrorMessages._ -import code.customer.CustomerMessages -import code.model._ -import code.products.Products -import code.util.Helper._ -import com.openbankproject.commons.ExecutionContext.Implicits.global - -trait APIMethods140 extends MdcLoggable with APIMethods130 with APIMethods121{ - //needs to be a RestHelper to get access to JsonGet, JsonPost, etc. - // We add previous APIMethods so we have access to the Resource Docs - self: RestHelper => - - val Implementations1_4_0 = new Object() { - - val resourceDocs = ArrayBuffer[ResourceDoc]() - val apiVersion = ApiVersion.v1_4_0 // was noV i.e. "1_4_0" - val apiVersionStatus : String = "STABLE" - - - resourceDocs += ResourceDoc( - root, - apiVersion, - "root", - "GET", - "/root", - "Get API Info (root)", - """Returns information about: - | - |* API version - |* Hosted by information - |* Git Commit""", - EmptyBody, - apiInfoJSON, - List(UnknownError, MandatoryPropertyIsNotSet), - apiTagApi :: Nil) - - lazy val root : OBPEndpoint = { - case (Nil | "root" :: Nil) JsonGet _ => { - cc => - implicit val ec = EndpointContext(Some(cc)) - for { - _ <- Future(()) // Just start async call - } yield { - (JSONFactory.getApiInfoJSON(OBPAPI1_4_0.version, OBPAPI1_4_0.versionStatus), HttpCode.`200`(cc.callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getCustomer, - apiVersion, - "getCustomer", - "GET", - "/banks/BANK_ID/customer", - "Get customer for logged in user", - """Information about the currently authenticated user. - | - |Authentication via OAuth is required.""", - EmptyBody, - customerJsonV140, - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagCustomer, apiTagOldStyle)) - - lazy val getCustomer : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "customer" :: Nil JsonGet _ => { - cc => { - for { - u <- cc.user ?~! ErrorMessages.AuthenticatedUserIsRequired - (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} - ucls <- tryo{UserCustomerLink.userCustomerLink.vend.getUserCustomerLinksByUserId(u.userId)} ?~! ErrorMessages.UserCustomerLinksNotFoundForUser - ucl <- tryo{ucls.find(x=>CustomerX.customerProvider.vend.getBankIdByCustomerId(x.customerId) == bankId.value)} - _ <- booleanToBox(ucl.size > 0, ErrorMessages.UserCustomerLinksNotFoundForUser) - u <- ucl - info <- CustomerX.customerProvider.vend.getCustomerByCustomerId(u.customerId) ?~! ErrorMessages.CustomerNotFoundByCustomerId - } yield { - val json = JSONFactory1_4_0.createCustomerJson(info) - successJsonResponse(Extraction.decompose(json)) - } - } - } - } - - resourceDocs += ResourceDoc( - getCustomersMessages, - apiVersion, - "getCustomersMessages", - "GET", - "/banks/BANK_ID/customer/messages", - "Get Customer Messages for all Customers", - """Get messages for the logged in customer - |Messages sent to the currently authenticated user. - | - |Authentication via OAuth is required.""", - EmptyBody, - customerMessagesJson, - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagMessage, apiTagCustomer)) - - lazy val getCustomersMessages : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "customer" :: "messages" :: Nil JsonGet _ => { - cc => { - implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - //au <- ResourceUser.find(By(ResourceUser.id, u.apiId)) - //role <- au.isCustomerMessageAdmin ~> APIFailure("User does not have sufficient permissions", 401) - } yield { - val messages = CustomerMessages.customerMessageProvider.vend.getMessages(u, bankId) - val json = JSONFactory1_4_0.createCustomerMessagesJson(messages) - (json, HttpCode.`200`(callContext)) - } - } - } - } - - resourceDocs += ResourceDoc( - addCustomerMessage, - apiVersion, - nameOf(addCustomerMessage), - "POST", - "/banks/BANK_ID/customer/CUSTOMER_ID/messages", - "Create Customer Message", - "Create a message for the customer specified by CUSTOMER_ID", - // We use Extraction.decompose to convert to json - addCustomerMessageJson, - successMessage, - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagMessage, apiTagCustomer, apiTagPerson) - ) - - // TODO Add Role - - lazy val addCustomerMessage : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "customer" :: customerId :: "messages" :: Nil JsonPost json -> _ => { - cc =>{ - implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - failMsg = s"$InvalidJsonFormat The Json body should be the $AddCustomerMessageJson " - postedData <- NewStyle.function.tryons(failMsg, 400, callContext) { - json.extract[AddCustomerMessageJson] - } - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (_, callContext) <- NewStyle.function.getCustomerByCustomerId(customerId, callContext) - (userCustomerLink, callContext) <- NewStyle.function.getUserCustomerLinkByCustomerId(customerId, callContext) - (user, callContext) <- NewStyle.function.findByUserId(userCustomerLink.userId, callContext) - (_, callContext)<- NewStyle.function.createMessage(user, bankId, postedData.message, postedData.from_department, postedData.from_person, callContext) - - } yield { - (successMessage, HttpCode.`201`(callContext)) - } - } - } - } - - - val getBranchesIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getBranchesIsPublic", true) - - resourceDocs += ResourceDoc( - getBranches, - apiVersion, - "getBranches", - "GET", - "/banks/BANK_ID/branches", - "Get Bank Branches", - s"""Returns information about branches for a single bank specified by BANK_ID including: - | - |* Name - |* Address - |* Geo Location - |* License the data under this endpoint is released under - | - ${urlParametersDocument(false, false)} - | - |You can use the url query parameters *limit* and *offset* for pagination - | - |${userAuthenticationMessage(!getBranchesIsPublic)}""".stripMargin, - EmptyBody, - branchesJson, - List( - AuthenticatedUserIsRequired, - BankNotFound, - "No branches available. License may not be set.", - UnknownError), - List(apiTagBranch, apiTagOldStyle) - ) - - lazy val getBranches : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "branches" :: Nil JsonGet req => { - cc =>{ - for { - _ <- if(getBranchesIsPublic) - Box(Some(1)) - else - cc.user ?~! AuthenticatedUserIsRequired - (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} - // Get branches from the active provider - httpParams <- createHttpParamsByUrl(cc.url) - obpQueryParams <- createQueriesByHttpParams(httpParams) - branches <- Box(Branches.branchesProvider.vend.getBranches(bankId, obpQueryParams)) ~> APIFailure("No branches available. License may not be set.", 204) - } yield { - // Format the data as json - val json = JSONFactory1_4_0.createBranchesJson(branches) - successJsonResponse(Extraction.decompose(json)) - } - } - } - } - - - val getAtmsIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getAtmsIsPublic", true) - - resourceDocs += ResourceDoc( - getAtms, - apiVersion, - "getAtms", - "GET", - "/banks/BANK_ID/atms", - "Get Bank ATMS", - s"""Returns information about ATMs for a single bank specified by BANK_ID including: - | - |* Address - |* Geo Location - |* License the data under this endpoint is released under - | - | - |${urlParametersDocument(false,false)} - | - |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, - EmptyBody, - atmsJson, - List( - AuthenticatedUserIsRequired, - BankNotFound, - "No ATMs available. License may not be set.", - UnknownError), - List(apiTagBank, apiTagOldStyle) - ) - - lazy val getAtms : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "atms" :: Nil JsonGet req => { - cc =>{ - for { - // Get atms from the active provider - - _ <- if(getAtmsIsPublic) - Box(Some(1)) - else - cc.user ?~! AuthenticatedUserIsRequired - (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} - - httpParams <- createHttpParamsByUrl(cc.url) - obpQueryParams <- createQueriesByHttpParams(httpParams) - atms <- Box(Atms.atmsProvider.vend.getAtms(bankId, obpQueryParams)) ~> APIFailure("No ATMs available. License may not be set.", 204) - } yield { - // Format the data as json - val json = JSONFactory1_4_0.createAtmsJson(atms) - // Return - successJsonResponse(Extraction.decompose(json)) - } - } - } - } - - - val getProductsIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getProductsIsPublic", true) - - - resourceDocs += ResourceDoc( - getProducts, - apiVersion, - "getProducts", - "GET", - "/banks/BANK_ID/products", - "Get Bank Products", - s"""Returns information about the financial products offered by a bank specified by BANK_ID including: - | - |* Name - |* Code - |* Category - |* Family - |* Super Family - |* More info URL - |* Description - |* Terms and Conditions - |* License the data under this endpoint is released under - |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, - EmptyBody, - productsJson, - List( - AuthenticatedUserIsRequired, - BankNotFound, - "No products available.", - "License may not be set.", - UnknownError), - List(apiTagBank, apiTagOldStyle) - ) - - lazy val getProducts : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "products" :: Nil JsonGet _ => { - cc =>{ - for { - // Get products from the active provider - _ <- if(getProductsIsPublic) - Box(Some(1)) - else - cc.user ?~! AuthenticatedUserIsRequired - (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} - products <- Box(Products.productsProvider.vend.getProducts(bankId)) ~> APIFailure("No products available. License may not be set.", 204) - } yield { - // Format the data as json - val json = JSONFactory1_4_0.createProductsJson(products) - // Return - successJsonResponse(Extraction.decompose(json)) - } - } - } - } - - - resourceDocs += ResourceDoc( - getCrmEvents, - apiVersion, - "getCrmEvents", - "GET", - "/banks/BANK_ID/crm-events", - "Get CRM Events", - "", - EmptyBody, - crmEventsJson, - List( - AuthenticatedUserIsRequired, - BankNotFound, - "No CRM Events available.", - UnknownError), - List(apiTagCustomer) - ) - - // TODO Require Role - - lazy val getCrmEvents : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "crm-events" :: Nil JsonGet _ => { - cc => { - implicit val ec = EndpointContext(Some(cc)) - for { - (_, callContext) <- authenticatedAccess(cc) - (bank, callContext ) <- NewStyle.function.getBank(bankId, callContext) - crmEvents <- NewStyle.function.getCrmEvents(bank.bankId, callContext) - } yield { - val json = JSONFactory1_4_0.createCrmEventsJson(crmEvents) - (json, HttpCode.`200`(callContext)) - } - } - } - } - - /* - transaction requests (new payments since 1.4.0) - */ - - resourceDocs += ResourceDoc( - getTransactionRequestTypes, - apiVersion, - "getTransactionRequestTypes", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types", - "Get Transaction Request Types for Account", - """Returns the Transaction Request Types that the account specified by ACCOUNT_ID and view specified by VIEW_ID has access to. - | - |These are the ways this API Server can create a Transaction via a Transaction Request - |(as opposed to Transaction Types which include external types too e.g. for Transactions created by core banking etc.) - | - | A Transaction Request Type internally determines: - | - | * the required Transaction Request 'body' i.e. fields that define the 'what' and 'to' of a Transaction Request, - | * the type of security challenge that may be be raised before the Transaction Request proceeds, and - | * the threshold of that challenge. - | - | For instance in a 'SANDBOX_TAN' Transaction Request, for amounts over 1000 currency units, the user must supply a positive integer to complete the Transaction Request and create a Transaction. - | - | This approach aims to provide only one endpoint for initiating transactions, and one that handles challenges, whilst still allowing flexibility with the payload and internal logic. - | - """.stripMargin, - EmptyBody, - transactionRequestTypesJsonV140, - List( - AuthenticatedUserIsRequired, - BankNotFound, - AccountNotFound, - "Please specify a valid value for CURRENCY of your Bank Account. " - ,"Current user does not have access to the view ", - "account not found at bank", - "user does not have access to owner view", - TransactionRequestsNotEnabled, - UnknownError), - List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2)) - - lazy val getTransactionRequestTypes: OBPEndpoint = { - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transaction-request-types" :: - Nil JsonGet _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - _ <- NewStyle.function.isEnabledTransactionRequests(callContext) - (bank, callContext ) <- NewStyle.function.getBank(bankId, callContext) - (fromAccount, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) - failMsg = ErrorMessages.InvalidISOCurrencyCode.concat("Please specify a valid value for CURRENCY of your Bank Account. ") - _ <- NewStyle.function.isValidCurrencyISOCode(fromAccount.currency, failMsg, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(fromAccount.bankId, fromAccount.accountId), Some(u), callContext) - _ <- Helper.booleanToFuture( - s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_SEE_TRANSACTION_REQUEST_TYPES)}` permission on the View(${viewId.value} )", - cc = callContext - ) { - ViewPermission.findViewPermissions(view).exists(_.permission.get == CAN_SEE_TRANSACTION_REQUEST_TYPES) - } - // TODO: Consider storing allowed_transaction_request_types (List of String) in View Definition. - // TODO: This would allow us to restrict transaction request types available to the User for an Account - (transactionRequestTypes, callContext) <- Future(Connector.connector.vend.getTransactionRequestTypes(u, fromAccount, callContext)) map { - connectorEmptyResponse(_, callContext) - } - (transactionRequestTypeCharges, callContext) <- NewStyle.function.getTransactionRequestTypeCharges(bankId, accountId, viewId, transactionRequestTypes, callContext) - } yield { - val json = JSONFactory1_4_0.createTransactionRequestTypesJSONs(transactionRequestTypeCharges) - (json, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addCustomer, - apiVersion, - "addCustomer", - "POST", - "/banks/BANK_ID/customer", - "Add a customer.", - s"""Add a customer linked to the currently authenticated user. - |The Customer resource stores the customer number, legal name, email, phone number, their date of birth, relationship status, education attained, a url for a profile image, KYC status etc. - |This call may require additional permissions/role in the future. - |For now the authenticated user can create at most one linked customer. - |Dates need to be in the format 2013-01-21T23:08:00Z - |${userAuthenticationMessage(true) } - |Note: This call is depreciated in favour of v.2.0.0 createCustomer - |""", - code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createCustomerJson, - customerJsonV140, - List( - AuthenticatedUserIsRequired, - BankNotFound, - InvalidJsonFormat, - "entitlements required", - CustomerNumberAlreadyExists, - "Problem getting user_id", - UserNotFoundById, - "Could not create customer", - "Could not create user_customer_links", - UnknownError), - List(apiTagCustomer, apiTagOldStyle), - Some(List(canCreateCustomer, canCreateUserCustomerLink))) - - lazy val addCustomer : OBPEndpoint = { - //updates a view on a bank account - case "banks" :: BankId(bankId) :: "customer" :: Nil JsonPost json -> _ => { - cc => - for { - u <- cc.user ?~! "User must be logged in to post Customer" - (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} - postedData <- tryo{json.extract[CreateCustomerJson]} ?~! ErrorMessages.InvalidJsonFormat - requiredEntitlements = ApiRole.canCreateCustomer :: ApiRole.canCreateUserCustomerLink :: Nil - _ <- NewStyle.function.hasAllEntitlements(bankId.value, u.userId, requiredEntitlements, callContext) - _ <- tryo(assert(CustomerX.customerProvider.vend.checkCustomerNumberAvailable(bankId, postedData.customer_number) == true)) ?~! ErrorMessages.CustomerNumberAlreadyExists - user_id <- tryo{if (postedData.user_id.nonEmpty) postedData.user_id else u.userId} ?~ s"Problem getting user_id" - _ <- UserX.findByUserId(user_id) ?~! ErrorMessages.UserNotFoundById - customer <- CustomerX.customerProvider.vend.addCustomer(bankId, - postedData.customer_number, - postedData.legal_name, - postedData.mobile_phone_number, - postedData.email, - CustomerFaceImage(postedData.face_image.date, postedData.face_image.url), - postedData.date_of_birth, - postedData.relationship_status, - postedData.dependants, - postedData.dob_of_dependants, - postedData.highest_education_attained, - postedData.employment_status, - postedData.kyc_status, - postedData.last_ok_date, - None, - None, - "", - "", - "" - ) ?~! "Could not create customer" - _ <- UserCustomerLink.userCustomerLink.vend.createUserCustomerLink(user_id, customer.customerId, DateWithMsExampleObject, true) ?~! "Could not create user_customer_links" - } yield { - val successJson = JSONFactory1_4_0.createCustomerJson(customer) - successJsonResponse(Extraction.decompose(successJson)) - } - } - } - - - - // `testResourceDoc` (dev-mode-only `GET /dummy` stub) deleted in the auth-stack / - // bridge-removal cleanup sweep. It returned a dummy `APIInfoJSON`, had no production - // behaviour, and its sole purpose was exercising the resource-doc renderer's - // description-markdown handling — covered today by real endpoints. - - } +trait APIMethods140 { self: RestHelper => } +object APIMethods140 extends RestHelper with APIMethods140 { + val Implementations1_4_0 = Http4s140.Implementations1_4_0 } From 89ae78394098335879c8c463bae2ac473a34b337 Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 02:06:49 +0200 Subject: [PATCH 03/10] fix(test): fix JSONFactory1_4_0Test to use OBPAPI1_3_0 Lift doc for technology check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OBPAPI1_4_0.allResourceDocs now uses collectResourceDocs — http4s v1.4.0 docs sort to the front so allResourceDocs.head is http4s. Use OBPAPI1_3_0.allResourceDocs.head (still a Lift doc from APIMethods130) for the technology=liftweb assertion. --- .../src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala index 16f7581fdf..9e60701f23 100644 --- a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala +++ b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala @@ -127,8 +127,8 @@ class JSONFactory1_4_0Test extends code.setup.ServerSetup { } scenario("Technology field should be None unless includeTechnology=true") { - // allResourceDocs(0) is now an http4s doc (v3.0.0 sorts above v2.2.0); use a v2.2.0 Lift doc instead. - val liftDoc: ResourceDoc = OBPAPI1_4_0.allResourceDocs.head + // OBPAPI1_4_0 now uses collectResourceDocs — http4s v1.4.0 docs sort first; use a v1.3.0 Lift doc instead. + val liftDoc: ResourceDoc = OBPAPI1_3_0.allResourceDocs.head val json1 = JSONFactory1_4_0.createLocalisedResourceDocJson(liftDoc, false, None, includeTechnology = false, urlParameters, "JSON request body fields:", "JSON response body fields:") json1.implemented_by.technology shouldBe None From 08dddb7d6b6569834086b0940016a61f9ab241a2 Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 02:11:47 +0200 Subject: [PATCH 04/10] refactor(v1.3.0): rewire OBPAPI1_3_0 to http4s, drop APIMethods130 mixin from downstream - Rewrite OBPAPI1_3_0: routes=Nil, allResourceDocs aggregates OBPAPI1_2_1+Http4s130 - Drop APIMethods130 import/mixin from OBPAPI5_1_0 and OBPAPI6_0_0 (zero APIMethods remain) - Add v1_3_0 skip-filter in ResourceDocsAPIMethods.activeResourceDocs - Fix v1_3_0 case in getResourceDocsList to use OBPAPI1_3_0.allResourceDocs - Update JSONFactory1_4_0Test liftDoc reference to OBPAPI1_2_1 --- .../ResourceDocsAPIMethods.scala | 3 +- .../scala/code/api/v1_3_0/OBPAPI1_3_0.scala | 115 +++--------------- .../scala/code/api/v5_1_0/OBPAPI5_1_0.scala | 2 - .../scala/code/api/v6_0_0/OBPAPI6_0_0.scala | 2 - .../api/v1_4_0/JSONFactory1_4_0Test.scala | 6 +- 5 files changed, 20 insertions(+), 108 deletions(-) diff --git a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala index 92eb4d3e7a..2ffa0e23ed 100644 --- a/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala +++ b/obp-api/src/main/scala/code/api/ResourceDocs1_4_0/ResourceDocsAPIMethods.scala @@ -134,7 +134,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth case ApiVersion.v2_1_0 => OBPAPI2_1_0.allResourceDocs case ApiVersion.v2_0_0 => OBPAPI2_0_0.allResourceDocs case ApiVersion.v1_4_0 => OBPAPI1_4_0.allResourceDocs - case ApiVersion.v1_3_0 => Implementations1_3_0.resourceDocs ++ Implementations1_2_1.resourceDocs + case ApiVersion.v1_3_0 => OBPAPI1_3_0.allResourceDocs case ApiVersion.v1_2_1 => code.api.v1_2_1.Http4s121.resourceDocs case ApiVersion.`dynamic-endpoint` => OBPAPIDynamicEndpoint.allResourceDocs case ApiVersion.`dynamic-entity` => OBPAPIDynamicEntity.allResourceDocs @@ -187,6 +187,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth case ApiVersion.v2_1_0 => resourceDocs // fully on http4s — no Lift route filter case ApiVersion.v2_0_0 => resourceDocs // fully on http4s — no Lift route filter case ApiVersion.v1_4_0 => resourceDocs // fully on http4s — no Lift route filter + case ApiVersion.v1_3_0 => resourceDocs // fully on http4s — no Lift route filter case _ => resourceDocs.filter(rd => versionRoutesClasses.contains(rd.partialFunction.getClass)) } diff --git a/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala b/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala index d5b6ce0507..f27c8c0d77 100644 --- a/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala +++ b/obp-api/src/main/scala/code/api/v1_3_0/OBPAPI1_3_0.scala @@ -2,114 +2,29 @@ package code.api.v1_3_0 import scala.language.reflectiveCalls import code.api.OBPRestHelper -import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} -import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} +import code.api.util.APIUtil.OBPEndpoint import code.api.util.VersionedOBPApis -import code.api.v1_2_1.APIMethods121 +import code.api.v1_2_1.OBPAPI1_2_1 import code.util.Helper.MdcLoggable +import com.openbankproject.commons.util.{ApiVersion, ApiVersionStatus} +/* +This file defines which endpoints from all the versions are available in v1.3.0. +All v1.3.0 endpoints have been migrated to Http4s130 — this object is retained +only for resource-doc aggregation and the Lift dispatch registry. + */ +object OBPAPI1_3_0 extends OBPRestHelper with MdcLoggable with VersionedOBPApis { -// Added so we can add resource docs for this version of the API - -//has APIMethods121 as all api calls that went unchanged from 1.2.1 to 1.3.0 will use the old -//implementation -object OBPAPI1_3_0 extends OBPRestHelper with APIMethods130 with APIMethods121 with MdcLoggable with VersionedOBPApis{ - - val version : ApiVersion = ApiVersion.v1_3_0 // "1.3.0" + val version: ApiVersion = ApiVersion.v1_3_0 val versionStatus = ApiVersionStatus.DEPRECATED.toString - //TODO: check all these calls to see if they should really have the same behaviour as 1.2.1 - - lazy val endpointsOf1_2_1 = List( - Implementations1_2_1.getBanks, - Implementations1_2_1.bankById, - Implementations1_2_1.getPrivateAccountsAllBanks, - Implementations1_2_1.privateAccountsAllBanks, - Implementations1_2_1.publicAccountsAllBanks, - Implementations1_2_1.getPrivateAccountsAtOneBank, - Implementations1_2_1.privateAccountsAtOneBank, - Implementations1_2_1.publicAccountsAtOneBank, - Implementations1_2_1.accountById, - Implementations1_2_1.getViewsForBankAccount, - Implementations1_2_1.createViewForBankAccount, - Implementations1_2_1.updateViewForBankAccount, - Implementations1_2_1.deleteViewForBankAccount, - Implementations1_2_1.getPermissionsForBankAccount, - Implementations1_2_1.getPermissionForUserForBankAccount, - Implementations1_2_1.addPermissionForUserForBankAccountForMultipleViews, - Implementations1_2_1.addPermissionForUserForBankAccountForOneView, - Implementations1_2_1.removePermissionForUserForBankAccountForOneView, - Implementations1_2_1.removePermissionForUserForBankAccountForAllViews, - Implementations1_2_1.getOtherAccountsForBankAccount, - Implementations1_2_1.getOtherAccountByIdForBankAccount, - Implementations1_2_1.getOtherAccountMetadata, - Implementations1_2_1.getCounterpartyPublicAlias, - Implementations1_2_1.addCounterpartyPublicAlias, - Implementations1_2_1.updateCounterpartyPublicAlias, - Implementations1_2_1.deleteCounterpartyPublicAlias, - Implementations1_2_1.getOtherAccountPrivateAlias, - Implementations1_2_1.addOtherAccountPrivateAlias, - Implementations1_2_1.updateCounterpartyPrivateAlias, - Implementations1_2_1.deleteCounterpartyPrivateAlias, - Implementations1_2_1.addCounterpartyMoreInfo, - Implementations1_2_1.updateCounterpartyMoreInfo, - Implementations1_2_1.deleteCounterpartyMoreInfo, - Implementations1_2_1.addCounterpartyUrl, - Implementations1_2_1.updateCounterpartyUrl, - Implementations1_2_1.deleteCounterpartyUrl, - Implementations1_2_1.addCounterpartyImageUrl, - Implementations1_2_1.updateCounterpartyImageUrl, - Implementations1_2_1.deleteCounterpartyImageUrl, - Implementations1_2_1.addCounterpartyOpenCorporatesUrl, - Implementations1_2_1.updateCounterpartyOpenCorporatesUrl, - Implementations1_2_1.deleteCounterpartyOpenCorporatesUrl, - Implementations1_2_1.addCounterpartyCorporateLocation, - Implementations1_2_1.updateCounterpartyCorporateLocation, - Implementations1_2_1.deleteCounterpartyCorporateLocation, - Implementations1_2_1.addCounterpartyPhysicalLocation, - Implementations1_2_1.updateCounterpartyPhysicalLocation, - Implementations1_2_1.deleteCounterpartyPhysicalLocation, - Implementations1_2_1.getTransactionsForBankAccount, - Implementations1_2_1.getTransactionByIdForBankAccount, - Implementations1_2_1.getTransactionNarrative, - Implementations1_2_1.addTransactionNarrative, - Implementations1_2_1.updateTransactionNarrative, - Implementations1_2_1.deleteTransactionNarrative, - Implementations1_2_1.getCommentsForViewOnTransaction, - Implementations1_2_1.addCommentForViewOnTransaction, - Implementations1_2_1.deleteCommentForViewOnTransaction, - Implementations1_2_1.getTagsForViewOnTransaction, - Implementations1_2_1.addTagForViewOnTransaction, - Implementations1_2_1.deleteTagForViewOnTransaction, - Implementations1_2_1.getImagesForViewOnTransaction, - Implementations1_2_1.addImageForViewOnTransaction, - Implementations1_2_1.deleteImageForViewOnTransaction, - Implementations1_2_1.getWhereTagForViewOnTransaction, - Implementations1_2_1.addWhereTagForViewOnTransaction, - Implementations1_2_1.updateWhereTagForViewOnTransaction, - Implementations1_2_1.deleteWhereTagForViewOnTransaction, - Implementations1_2_1.getOtherAccountForTransaction - //Implementations1_2_1.makePayment - ) - - val endpointsOf1_3_0 = List( - Implementations1_3_0.root, - Implementations1_3_0.getCards, - Implementations1_3_0.getCardsForBank - ) - - val allResourceDocs = - Implementations1_3_0.resourceDocs ++ - Implementations1_2_1.resourceDocs - - // Filter the possible endpoints by the disabled / enabled Props settings and add them together - val routes : List[OBPEndpoint] = - getAllowedEndpoints(endpointsOf1_2_1, Implementations1_2_1.resourceDocs) ::: - getAllowedEndpoints(endpointsOf1_3_0, Implementations1_3_0.resourceDocs) + val Implementations1_3_0 = Http4s130.Implementations1_3_0 + def allResourceDocs = collectResourceDocs(OBPAPI1_2_1.allResourceDocs, Http4s130.resourceDocs) - registerRoutes(routes, allResourceDocs, apiPrefix) + val routes: List[OBPEndpoint] = Nil - logger.info(s"version $version has been run! There are ${routes.length} routes.") + registerRoutes(routes, allResourceDocs, apiPrefix, true) + logger.info(s"version $version has been run! There are ${routes.length} routes, ${allResourceDocs.length} allResourceDocs.") } diff --git a/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala b/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala index f8c020ea76..453a7fcc01 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/OBPAPI5_1_0.scala @@ -30,7 +30,6 @@ import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.OBPEndpoint import code.api.util.VersionedOBPApis -import code.api.v1_3_0.APIMethods130 import code.api.v3_0_0.Http4s300 import code.api.v3_1_0.{APIMethods310, Http4s310} import code.api.v4_0_0.{APIMethods400, Http4s400} @@ -45,7 +44,6 @@ All v5.1.0 endpoints have been migrated to Http4s510 — this object is retained only for resource-doc aggregation and the Lift dispatch registry. */ object OBPAPI5_1_0 extends OBPRestHelper - with APIMethods130 with APIMethods310 with APIMethods400 with APIMethods500 diff --git a/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala b/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala index c45d123252..4ef61ee0fb 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/OBPAPI6_0_0.scala @@ -31,7 +31,6 @@ import scala.language.reflectiveCalls import code.api.OBPRestHelper import code.api.util.APIUtil.OBPEndpoint import code.api.util.VersionedOBPApis -import code.api.v1_3_0.APIMethods130 import code.api.v3_0_0.Http4s300 import code.api.v3_1_0.{APIMethods310, Http4s310} import code.api.v4_0_0.{APIMethods400, Http4s400} @@ -47,7 +46,6 @@ All v6.0.0 endpoints have been migrated to Http4s600 — this object is retained only for resource-doc aggregation and the Lift dispatch registry. */ object OBPAPI6_0_0 extends OBPRestHelper - with APIMethods130 with APIMethods310 with APIMethods400 with APIMethods500 diff --git a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala index 9e60701f23..1a2ad8f5a9 100644 --- a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala +++ b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala @@ -8,7 +8,7 @@ import code.api.util.{APIUtil, ExampleValue} import code.api.util.CustomJsonFormats import code.api.v1_4_0.JSONFactory1_4_0.ResourceDocJson import code.api.v3_0_0.OBPAPI3_0_0 -import code.api.v1_3_0.OBPAPI1_3_0 +import code.api.v1_2_1.OBPAPI1_2_1 import net.liftweb.json.Extraction.decompose import net.liftweb.json._ import org.everit.json.schema.loader.SchemaLoader @@ -127,8 +127,8 @@ class JSONFactory1_4_0Test extends code.setup.ServerSetup { } scenario("Technology field should be None unless includeTechnology=true") { - // OBPAPI1_4_0 now uses collectResourceDocs — http4s v1.4.0 docs sort first; use a v1.3.0 Lift doc instead. - val liftDoc: ResourceDoc = OBPAPI1_3_0.allResourceDocs.head + // OBPAPI1_3_0 now uses collectResourceDocs — http4s v1.3.0 docs sort first; use a v1.2.1 Lift doc instead. + val liftDoc: ResourceDoc = OBPAPI1_2_1.allResourceDocs.head val json1 = JSONFactory1_4_0.createLocalisedResourceDocJson(liftDoc, false, None, includeTechnology = false, urlParameters, "JSON request body fields:", "JSON response body fields:") json1.implemented_by.technology shouldBe None From c4683ea9f2873aae9ddea69371904d2bcc3c469f Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 02:12:16 +0200 Subject: [PATCH 05/10] =?UTF-8?q?refactor(v1.3.0):=20stub=20APIMethods130?= =?UTF-8?q?=20=E2=80=94=20replace=20120-line=20Lift=20handler=20with=20emp?= =?UTF-8?q?ty=20trait?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All v1.3.0 endpoints are served by Http4s130. The Lift dispatch code is dead. --- .../scala/code/api/v1_3_0/APIMethods130.scala | 117 +----------------- 1 file changed, 1 insertion(+), 116 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala b/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala index f3abe43b1b..3ccd0ec214 100644 --- a/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala +++ b/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala @@ -1,120 +1,5 @@ package code.api.v1_3_0 -import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ -import code.api.util.APIUtil._ -import code.api.util.ApiTag._ -import code.api.util.ErrorMessages._ -import code.api.util.FutureUtil.EndpointContext -import code.api.util.NewStyle.HttpCode -import code.api.util.ApiRole._ -import code.api.util.{ApiRole, NewStyle} -import code.api.v1_2_1.JSONFactory -import com.openbankproject.commons.ExecutionContext.Implicits.global -import com.openbankproject.commons.model.BankId -import com.openbankproject.commons.util.ApiVersion -import net.liftweb.common.Full import net.liftweb.http.rest.RestHelper -import scala.collection.mutable.ArrayBuffer -import scala.concurrent.Future - -trait APIMethods130 { - //needs to be a RestHelper to get access to JsonGet, JsonPost, etc. - self: RestHelper => - - val Implementations1_3_0 = new Object(){ - - val resourceDocs = ArrayBuffer[ResourceDoc]() - val apiVersion = ApiVersion.v1_3_0 // was String "1_3_0" - - - resourceDocs += ResourceDoc( - root, - apiVersion, - "root", - "GET", - "/root", - "Get API Info (root)", - """Returns information about: - | - |* API version - |* Hosted by information - |* Git Commit""", - EmptyBody, - apiInfoJSON, - List(UnknownError, MandatoryPropertyIsNotSet), - apiTagApi :: Nil) - - lazy val root : OBPEndpoint = { - case (Nil | "root" :: Nil) JsonGet _ => { - cc => - implicit val ec = EndpointContext(Some(cc)) - for { - _ <- Future(()) // Just start async call - } yield { - (JSONFactory.getApiInfoJSON(OBPAPI1_3_0.version, OBPAPI1_3_0.versionStatus), HttpCode.`200`(cc.callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getCards, - apiVersion, - "getCards", - "GET", - "/cards", - "Get cards for the current user", - "Returns data about all the physical cards a user has been issued. These could be debit cards, credit cards, etc.", - EmptyBody, - physicalCardsJSON, - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagCard)) - - lazy val getCards : OBPEndpoint = { - case "cards" :: Nil JsonGet _ => { - cc => { - implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (cards,callContext) <- NewStyle.function.getPhysicalCardsForUser(u, callContext) - } yield { - (JSONFactory1_3_0.createPhysicalCardsJSON(cards, u), HttpCode.`200`(callContext)) - } - } - } - } - - - resourceDocs += ResourceDoc( - getCardsForBank, - apiVersion, - "getCardsForBank", - "GET", - "/banks/BANK_ID/cards", - "Get cards for the specified bank", - "", - EmptyBody, - physicalCardsJSON, - List(AuthenticatedUserIsRequired,BankNotFound, UnknownError), - List(apiTagCard), - Some(List(canGetCardsForBank))) - - lazy val getCardsForBank : OBPEndpoint = { - case "banks" :: BankId(bankId) :: "cards" :: Nil JsonGet _ => { - cc => { - implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - httpParams <- NewStyle.function.extractHttpParamsFromUrl(cc.url) - (obpQueryParams, callContext) <- createQueriesByHttpParamsFuture(httpParams, callContext) - _ <- NewStyle.function.hasEntitlement(bankId.value, u.userId, ApiRole.canGetCardsForBank, callContext) - (bank, callContext) <- NewStyle.function.getBank(bankId, callContext) - (cards, callContext) <- NewStyle.function.getPhysicalCardsForBank(bank, u, obpQueryParams, callContext) - } yield { - (JSONFactory1_3_0.createPhysicalCardsJSON(cards, u), HttpCode.`200`(callContext)) - } - } - } - } - } -} +trait APIMethods130 { self: RestHelper => } From cb6ba6213072ef8792bc9042cf0d9045db0ce884 Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 02:16:16 +0200 Subject: [PATCH 06/10] refactor(v1.2.1): rewire OBPAPI1_2_1 to http4s; rewrite JSONFactory1_4_0Test technology check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite OBPAPI1_2_1: routes=Nil, allResourceDocs = Http4s121.resourceDocs - All versions now fully on http4s — update JSONFactory1_4_0Test to assert TECHNOLOGY_HTTP4S --- .../scala/code/api/v1_2_1/OBPAPI1.2.1.scala | 141 ++---------------- .../api/v1_4_0/JSONFactory1_4_0Test.scala | 10 +- 2 files changed, 20 insertions(+), 131 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala b/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala index 113d684b1e..f2821eb7a9 100644 --- a/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala +++ b/obp-api/src/main/scala/code/api/v1_2_1/OBPAPI1.2.1.scala @@ -1,139 +1,28 @@ -/** -Open Bank Project - API -Copyright (C) 2011-2019, TESOBE GmbH. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . - -Email: contact@tesobe.com -TESOBE GmbH. -Osloer Strasse 16/17 -Berlin 13359, Germany - -This product includes software developed at -TESOBE (http://www.tesobe.com/) - - */ package code.api.v1_2_1 -import scala.language.implicitConversions -import scala.language.reflectiveCalls import code.api.OBPRestHelper -import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints} -import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus} +import code.api.util.APIUtil.OBPEndpoint import code.api.util.VersionedOBPApis import code.util.Helper.MdcLoggable +import com.openbankproject.commons.util.{ApiVersion, ApiVersionStatus} -// Added so we can add resource docs for this version of the API - -object OBPAPI1_2_1 extends OBPRestHelper with APIMethods121 with MdcLoggable with VersionedOBPApis{ +/* +This file defines which endpoints from all the versions are available in v1.2.1. +All v1.2.1 endpoints have been migrated to Http4s121 — this object is retained +only for resource-doc aggregation and the Lift dispatch registry. + */ +object OBPAPI1_2_1 extends OBPRestHelper with MdcLoggable with VersionedOBPApis { - - val version : ApiVersion = ApiVersion.v1_2_1 // "1.2.1" + val version: ApiVersion = ApiVersion.v1_2_1 val versionStatus = ApiVersionStatus.DEPRECATED.toString - lazy val endpointsOf1_2_1: Seq[OBPEndpoint] = List( - Implementations1_2_1.root, - Implementations1_2_1.getBanks, - Implementations1_2_1.bankById, - Implementations1_2_1.getPrivateAccountsAllBanks, - Implementations1_2_1.privateAccountsAllBanks, - Implementations1_2_1.publicAccountsAllBanks, - Implementations1_2_1.getPrivateAccountsAtOneBank, - Implementations1_2_1.privateAccountsAtOneBank, - Implementations1_2_1.publicAccountsAtOneBank, - Implementations1_2_1.accountById, - Implementations1_2_1.updateAccountLabel, - Implementations1_2_1.getViewsForBankAccount, - Implementations1_2_1.createViewForBankAccount, - Implementations1_2_1.updateViewForBankAccount, - Implementations1_2_1.deleteViewForBankAccount, - Implementations1_2_1.getPermissionsForBankAccount, - Implementations1_2_1.getPermissionForUserForBankAccount, - Implementations1_2_1.addPermissionForUserForBankAccountForMultipleViews, - Implementations1_2_1.addPermissionForUserForBankAccountForOneView, - Implementations1_2_1.removePermissionForUserForBankAccountForOneView, - Implementations1_2_1.removePermissionForUserForBankAccountForAllViews, - Implementations1_2_1.getOtherAccountsForBankAccount, - Implementations1_2_1.getOtherAccountByIdForBankAccount, - Implementations1_2_1.getOtherAccountMetadata, - Implementations1_2_1.getCounterpartyPublicAlias, - Implementations1_2_1.addCounterpartyPublicAlias, - Implementations1_2_1.updateCounterpartyPublicAlias, - Implementations1_2_1.deleteCounterpartyPublicAlias, - Implementations1_2_1.getOtherAccountPrivateAlias, - Implementations1_2_1.addOtherAccountPrivateAlias, - Implementations1_2_1.updateCounterpartyPrivateAlias, - Implementations1_2_1.deleteCounterpartyPrivateAlias, - Implementations1_2_1.addCounterpartyMoreInfo, - Implementations1_2_1.updateCounterpartyMoreInfo, - Implementations1_2_1.deleteCounterpartyMoreInfo, - Implementations1_2_1.addCounterpartyUrl, - Implementations1_2_1.updateCounterpartyUrl, - Implementations1_2_1.deleteCounterpartyUrl, - Implementations1_2_1.addCounterpartyImageUrl, - Implementations1_2_1.updateCounterpartyImageUrl, - Implementations1_2_1.deleteCounterpartyImageUrl, - Implementations1_2_1.addCounterpartyOpenCorporatesUrl, - Implementations1_2_1.updateCounterpartyOpenCorporatesUrl, - Implementations1_2_1.deleteCounterpartyOpenCorporatesUrl, - Implementations1_2_1.addCounterpartyCorporateLocation, - Implementations1_2_1.updateCounterpartyCorporateLocation, - Implementations1_2_1.deleteCounterpartyCorporateLocation, - Implementations1_2_1.addCounterpartyPhysicalLocation, - Implementations1_2_1.updateCounterpartyPhysicalLocation, - Implementations1_2_1.deleteCounterpartyPhysicalLocation, - Implementations1_2_1.getTransactionsForBankAccount, - Implementations1_2_1.getTransactionByIdForBankAccount, - Implementations1_2_1.getTransactionNarrative, - Implementations1_2_1.addTransactionNarrative, - Implementations1_2_1.updateTransactionNarrative, - Implementations1_2_1.deleteTransactionNarrative, - Implementations1_2_1.getCommentsForViewOnTransaction, - Implementations1_2_1.addCommentForViewOnTransaction, - Implementations1_2_1.deleteCommentForViewOnTransaction, - Implementations1_2_1.getTagsForViewOnTransaction, - Implementations1_2_1.addTagForViewOnTransaction, - Implementations1_2_1.deleteTagForViewOnTransaction, - Implementations1_2_1.getImagesForViewOnTransaction, - Implementations1_2_1.addImageForViewOnTransaction, - Implementations1_2_1.deleteImageForViewOnTransaction, - Implementations1_2_1.getWhereTagForViewOnTransaction, - Implementations1_2_1.addWhereTagForViewOnTransaction, - Implementations1_2_1.updateWhereTagForViewOnTransaction, - Implementations1_2_1.deleteWhereTagForViewOnTransaction, - Implementations1_2_1.getOtherAccountForTransaction - //Implementations1_2_1.makePayment - ) - val allResourceDocs = Implementations1_2_1.resourceDocs - - // Filter the possible endpoints by the disabled / enabled Props settings and add them together - val routes : List[OBPEndpoint] = - getAllowedEndpoints(endpointsOf1_2_1, Implementations1_2_1.resourceDocs) - - - registerRoutes(routes, allResourceDocs, apiPrefix) - - logger.info(s"version $version has been run! There are ${routes.length} routes.") - + val Implementations1_2_1 = Http4s121.Implementations1_2_1 + def allResourceDocs = Http4s121.resourceDocs + val routes: List[OBPEndpoint] = Nil - //TODO: call for get more info of other bank account? - //TODO: call for get url of other bank account? - //TODO: call for get image url of other bank account? - //TODO: call for get open corporates url of other bank account? - //TODO: call for get corporate location of other bank account? - //TODO: call for get physical location of other bank account? + registerRoutes(routes, allResourceDocs, apiPrefix, true) -} \ No newline at end of file + logger.info(s"version $version has been run! There are ${routes.length} routes, ${allResourceDocs.length} allResourceDocs.") +} diff --git a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala index 1a2ad8f5a9..064dc57d74 100644 --- a/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala +++ b/obp-api/src/test/scala/code/api/v1_4_0/JSONFactory1_4_0Test.scala @@ -127,13 +127,13 @@ class JSONFactory1_4_0Test extends code.setup.ServerSetup { } scenario("Technology field should be None unless includeTechnology=true") { - // OBPAPI1_3_0 now uses collectResourceDocs — http4s v1.3.0 docs sort first; use a v1.2.1 Lift doc instead. - val liftDoc: ResourceDoc = OBPAPI1_2_1.allResourceDocs.head - val json1 = JSONFactory1_4_0.createLocalisedResourceDocJson(liftDoc, false, None, includeTechnology = false, urlParameters, "JSON request body fields:", "JSON response body fields:") + // All versions are now on http4s — use any http4s doc. + val http4sDoc: ResourceDoc = OBPAPI1_2_1.allResourceDocs.head + val json1 = JSONFactory1_4_0.createLocalisedResourceDocJson(http4sDoc, false, None, includeTechnology = false, urlParameters, "JSON request body fields:", "JSON response body fields:") json1.implemented_by.technology shouldBe None - val json2 = JSONFactory1_4_0.createLocalisedResourceDocJson(liftDoc, false, None, includeTechnology = true, urlParameters, "JSON request body fields:", "JSON response body fields:") - json2.implemented_by.technology shouldBe Some(Constant.TECHNOLOGY_LIFTWEB) + val json2 = JSONFactory1_4_0.createLocalisedResourceDocJson(http4sDoc, false, None, includeTechnology = true, urlParameters, "JSON request body fields:", "JSON response body fields:") + json2.implemented_by.technology shouldBe Some(Constant.TECHNOLOGY_HTTP4S) } scenario("Technology field should be http4s when includeTechnology=true and doc is http4s") { From 4f5c5fc2ffb587d3794d65c422ee1e082608b51f Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 02:16:27 +0200 Subject: [PATCH 07/10] =?UTF-8?q?refactor(v1.2.1):=20stub=20APIMethods121?= =?UTF-8?q?=20=E2=80=94=20replace=203218-line=20Lift=20handler=20with=20em?= =?UTF-8?q?pty=20trait?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All v1.2.1 endpoints are served by Http4s121. The Lift dispatch code is dead. --- .../scala/code/api/v1_2_1/APIMethods121.scala | 3216 +---------------- 1 file changed, 3 insertions(+), 3213 deletions(-) diff --git a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala index a8cbead5b0..7d36e7fd9c 100644 --- a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala +++ b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala @@ -1,3218 +1,8 @@ package code.api.v1_2_1 -import code.api.Constant._ -import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ -import code.api.cache.Caching -import code.api.util.APIUtil._ -import code.api.util.ApiTag._ -import code.api.util.ErrorMessages._ -import code.api.util.FutureUtil.EndpointContext -import code.api.util.NewStyle.HttpCode -import code.api.util._ -import code.api.util.newstyle.ViewNewStyle -import code.bankconnectors._ -import code.metadata.counterparties.Counterparties -import code.model.{BankAccountX, BankX, ModeratedTransactionMetadata, UserX, toBankAccountExtended, toBankExtended} -import code.util.Helper -import code.util.Helper.booleanToBox -import code.views.Views -import com.openbankproject.commons.ExecutionContext.Implicits.global -import com.openbankproject.commons.model._ -import com.openbankproject.commons.util.ApiVersion -import com.tesobe.CacheKeyFromArguments -import net.liftweb.common._ -import net.liftweb.http.JsonResponse import net.liftweb.http.rest.RestHelper -import net.liftweb.json.Extraction -import net.liftweb.json.JsonAST.JValue -import net.liftweb.util.Helpers._ -import java.net.URL -import java.util.UUID.randomUUID -import scala.collection.mutable.ArrayBuffer -import scala.concurrent.Future -import scala.concurrent.duration._ -import scala.language.postfixOps - -trait APIMethods121 { - //needs to be a RestHelper to get access to JsonGet, JsonPost, etc. - self: RestHelper => - - val apiMethods121GetTransactionsTTL = APIUtil.getPropsValue("api.cache.ttl.seconds.APIMethods121.getTransactions", "0").toInt * 1000 // Miliseconds - - // helper methods begin here - - private def privateBankAccountsListToJson(bankAccounts: List[BankAccount], privateViewsUserCanAccess: List[View]): JValue = { - val accJson : List[AccountJSON] = bankAccounts.map( account => { - val viewsAvailable : List[ViewJSONV121] = - (privateViewsUserCanAccess - .filter(v =>v.bankId==account.bankId && v.accountId ==account.accountId && v.isPrivate)//filter the view for this account. - .map(JSONFactory.createViewJSON(_)) - .distinct) ++ - (privateViewsUserCanAccess - .filter(v =>v.isSystem && v.isPrivate)//plus the system views. - .map(JSONFactory.createViewJSON(_)) - .distinct) - JSONFactory.createAccountJSON(account,viewsAvailable) - }) - - val accounts = new AccountsJSON(accJson) - Extraction.decompose(accounts) - } - - private def publicBankAccountsListToJson(bankAccounts: List[BankAccount], publicViews: List[View]): JValue = { - val accJson : List[AccountJSON] = bankAccounts.map( account => { - val viewsAvailable : List[ViewJSONV121] = - publicViews - .filter(v =>v.bankId==account.bankId && v.accountId ==account.accountId && v.isPublic) - .map(v => JSONFactory.createViewJSON(v)) - .distinct - JSONFactory.createAccountJSON(account,viewsAvailable) - }) - - val accounts = new AccountsJSON(accJson) - Extraction.decompose(accounts) - } - - def checkIfLocationPossible(lat:Double,lon:Double) : Box[Unit] = { - if(scala.math.abs(lat) <= 90 & scala.math.abs(lon) <= 180) - Full(()) - else - Failure("Coordinates not possible") - } - - private def moderatedTransactionMetadata(bankId : BankId, accountId : AccountId, viewId : ViewId, transactionID : TransactionId, user : Box[User], callContext: Option[CallContext]) : Box[ModeratedTransactionMetadata] ={ - for { - (account, callContext) <- BankAccountX(bankId, accountId, callContext) ?~! BankAccountNotFound - view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), user, callContext) - (moderatedTransaction, callContext) <- account.moderatedTransaction(transactionID, view, BankIdAccountId(bankId,accountId), user, callContext) - metadata <- Box(moderatedTransaction.metadata) ?~ { s"$NoViewPermission can_see_transaction_metadata. Current ViewId($viewId)" } - } yield metadata - } - private def moderatedTransactionMetadataFuture(bankId : BankId, accountId : AccountId, viewId : ViewId, transactionID : TransactionId, user : Box[User], callContext: Option[CallContext]): Future[ModeratedTransactionMetadata] = { - for { - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view: View <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), user, callContext) - (moderatedTransaction, callContext) <- account.moderatedTransactionFuture(transactionID, view, user, callContext) map { - unboxFullOrFail(_, callContext, GetTransactionsException) - } - metadata <- Future(moderatedTransaction.metadata) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_transaction_metadata. Current ViewId($viewId)") - } - } yield metadata - } - - // helper methods end here - - val Implementations1_2_1 = new Object(){ - - val resourceDocs = ArrayBuffer[ResourceDoc]() - val apiVersion = ApiVersion.v1_2_1 // was String "1_2_1" - val apiVersionStatus : String = "STABLE" - - resourceDocs += ResourceDoc( - root, - apiVersion, - "root", - "GET", - "/root", - "Get API Info (root)", - """Returns information about: - | - |* API version - |* Hosted by information - |* Git Commit""", - EmptyBody, - apiInfoJSON, - List(UnknownError, MandatoryPropertyIsNotSet), - apiTagApi :: Nil) - - lazy val root : OBPEndpoint = { - case (Nil | "root" :: Nil) JsonGet _ => { - cc => - implicit val ec = EndpointContext(Some(cc)) - for { - _ <- Future(()) // Just start async call - } yield { - (JSONFactory.getApiInfoJSON(apiVersion,apiVersionStatus), HttpCode.`200`(cc.callContext)) - } - } - } - - - resourceDocs += ResourceDoc( - getBanks, - apiVersion, - "getBanks", - "GET", - "/banks", - "Get Banks", - """Get banks on this API instance - |Returns a list of banks supported on this server: - | - |* ID used as parameter in URLs - |* Short and full name of bank - |* Logo URL - |* Website""", - EmptyBody, - banksJSON, - List(UnknownError), - apiTagBank :: apiTagPsd2 :: apiTagOldStyle :: Nil) - - lazy val getBanks : OBPEndpoint = { - //get banks - case "banks" :: Nil JsonGet req => { - cc => - def banksToJson(banksList: List[Bank]): JValue = { - val banksJSON: List[BankJSON] = banksList.map(b => { - JSONFactory.createBankJSON(b) - }) - val banks = new BanksJSON(banksJSON) - Extraction.decompose(banks) - } - for((banks, callContext)<- Connector.connector.vend.getBanksLegacy(Some(cc))) - yield(successJsonResponse(banksToJson(banks))) - } - } - - - resourceDocs += ResourceDoc( - bankById, - apiVersion, - "bankById", - "GET", - "/banks/BANK_ID", - "Get Bank", - """Get the bank specified by BANK_ID - |Returns information about a single bank specified by BANK_ID including: - | - |* Short and full name of bank - |* Logo URL - |* Website""", - EmptyBody, - bankJSON, - List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), - apiTagBank :: apiTagPsd2 :: apiTagOldStyle :: Nil) - - - lazy val bankById : OBPEndpoint = { - //get bank by id - case "banks" :: BankId(bankId) :: Nil JsonGet req => { - cc => - def bankToJson(bank : Bank) : JValue = { - val bankJSON = JSONFactory.createBankJSON(bank) - Extraction.decompose(bankJSON) - } - for((bank, callContext)<- BankX(bankId, Some(cc)) ?~! BankNotFound) - yield successJsonResponse(bankToJson(bank)) - } - } - - - resourceDocs += ResourceDoc( - getPrivateAccountsAllBanks, - apiVersion, - "getPrivateAccountsAllBanks", - "GET", - "/accounts", - "Get accounts at all banks (Private, inc views)", - s"""Returns the list of accounts at that the user has access to at all banks. - |For each account the API returns the account ID and the available views. - | - |${userAuthenticationMessage(true)} - |""".stripMargin, - EmptyBody, - accountJSON, - List(AuthenticatedUserIsRequired, UnknownError), - apiTagAccount :: apiTagPsd2 :: apiTagOldStyle :: Nil) - - //TODO double check with `lazy val privateAccountsAllBanks :`, they are the same now. - lazy val getPrivateAccountsAllBanks : OBPEndpoint = { - //get accounts for all banks (private + public) - case "accounts" :: Nil JsonGet req => { - cc => - for { - u <- cc.user ?~ AuthenticatedUserIsRequired - (privateViewsUserCanAccess, privateAccountAccess) <- Full(Views.views.vend.privateViewsUserCanAccess(u)) - availablePrivateAccounts <- Full(BankAccountX.privateAccounts(privateAccountAccess)) - } yield { - successJsonResponse(privateBankAccountsListToJson(availablePrivateAccounts, privateViewsUserCanAccess)) - } - } - } - - resourceDocs += ResourceDoc( - privateAccountsAllBanks, - apiVersion, - "privateAccountsAllBanks", - "GET", - "/accounts/private", - "Get private accounts at all banks (Authenticated access)", - """Returns the list of private accounts the user has access to at all banks. - |For each account the API returns the ID and the available views. - | - |Authentication via OAuth is required. - | - |""".stripMargin, - EmptyBody, - accountJSON, - List(AuthenticatedUserIsRequired, UnknownError), - apiTagAccount :: apiTagPsd2 :: apiTagOldStyle :: Nil) - - lazy val privateAccountsAllBanks : OBPEndpoint = { - //get private accounts for all banks - case "accounts" :: "private" :: Nil JsonGet req => { - cc => - for { - u <- cc.user ?~ AuthenticatedUserIsRequired - (privateViewsUserCanAccess, privateAccountAccess) <- Full(Views.views.vend.privateViewsUserCanAccess(u)) - privateAccounts <- Full(BankAccountX.privateAccounts(privateAccountAccess)) - } yield { - successJsonResponse(privateBankAccountsListToJson(privateAccounts, privateViewsUserCanAccess)) - } - } - } - - resourceDocs += ResourceDoc( - publicAccountsAllBanks, - apiVersion, - "publicAccountsAllBanks", - "GET", - "/accounts/public", - "Get public accounts at all banks (Anonymous access)", - """ - |Returns the list of private accounts the user has access to at all banks. - |For each account the API returns the ID and the available views. - |Authentication via OAuth is required. - | - |""".stripMargin, - EmptyBody, - accountJSON, - List(UnknownError), - apiTagAccount :: apiTagOldStyle :: Nil) - - lazy val publicAccountsAllBanks : OBPEndpoint = { - //get public accounts for all banks - case "accounts" :: "public" :: Nil JsonGet req => { - cc => - for{ - (publicViews, publicAccountAccess) <- Full(Views.views.vend.publicViews) - publicAccounts <- Full(BankAccountX.publicAccounts(publicAccountAccess)) - publicAccountsJson <- Full(publicBankAccountsListToJson(publicAccounts, publicViews)) - } yield{ - successJsonResponse(publicAccountsJson) - } - } - } - - resourceDocs += ResourceDoc( - getPrivateAccountsAtOneBank, - apiVersion, - "getPrivateAccountsAtOneBank", - "GET", - "/banks/BANK_ID/accounts", - "Get accounts at bank (Private)", - s"""Returns the list of accounts at BANK_ID that the user has access to. - |For each account the API returns the account ID and the available views. - | - |${userAuthenticationMessage(true)} - | - """, - EmptyBody, - accountJSON, - List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), - apiTagAccount :: apiTagOldStyle :: Nil) - - lazy val getPrivateAccountsAtOneBank : OBPEndpoint = { - //get accounts for a single bank (private + public) - case "banks" :: BankId(bankId) :: "accounts" :: Nil JsonGet req => { - cc => - for{ - u <- cc.user ?~! ErrorMessages.AuthenticatedUserIsRequired - (bank, callContext) <- BankX(bankId, Some(cc)) ?~! BankNotFound - } yield { - val (privateViewsUserCanAccessAtOneBank, privateAccountAccess) = Views.views.vend.privateViewsUserCanAccessAtBank(u, bankId) - val availablePrivateAccounts = bank.privateAccounts(privateAccountAccess) - successJsonResponse(privateBankAccountsListToJson(availablePrivateAccounts, privateViewsUserCanAccessAtOneBank)) - } - } - } - - resourceDocs += ResourceDoc( - privateAccountsAtOneBank, - apiVersion, - "privateAccountsAtOneBank", - "GET", - "/banks/BANK_ID/accounts/private", - "Get private accounts at one bank", - s"""Returns the list of private accounts at BANK_ID that the user has access to. - |For each account the API returns the ID and the available views. - | - |${userAuthenticationMessage(true)} - | - |""".stripMargin, - EmptyBody, - accountJSON, - List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), - List(apiTagAccount, apiTagPsd2, apiTagOldStyle)) - - lazy val privateAccountsAtOneBank : OBPEndpoint = { - //get private accounts for a single bank - case "banks" :: BankId(bankId) :: "accounts" :: "private" :: Nil JsonGet req => { - cc => - for { - u <- cc.user ?~ AuthenticatedUserIsRequired - (bank, callContext) <- BankX(bankId, Some(cc)) ?~! BankNotFound - } yield { - val (privateViewsUserCanAccessAtOneBank, privateAccountAccess) = Views.views.vend.privateViewsUserCanAccessAtBank(u, bankId) - val availablePrivateAccounts = bank.privateAccounts(privateAccountAccess) - successJsonResponse(privateBankAccountsListToJson(availablePrivateAccounts, privateViewsUserCanAccessAtOneBank)) - } - } - } - - resourceDocs += ResourceDoc( - publicAccountsAtOneBank, - apiVersion, - "publicAccountsAtOneBank", - "GET", - "/banks/BANK_ID/accounts/public", - "Get public accounts at one bank (Anonymous access)", - """Returns a list of the public accounts at BANK_ID. For each account the API returns the ID and the available views. - | - |Authentication via OAuth is not required. - | - |""".stripMargin, - EmptyBody, - accountJSON, - List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), - apiTagAccountPublic :: apiTagAccount :: apiTagPublicData :: apiTagOldStyle :: Nil) - - lazy val publicAccountsAtOneBank : OBPEndpoint = { - //get public accounts for a single bank - case "banks" :: BankId(bankId) :: "accounts" :: "public" :: Nil JsonGet req => { - cc => - for { - (bank, callContext) <- BankX(bankId, Some(cc)) ?~! BankNotFound - (publicViewsForBank, publicAccountAccess) <- Full(Views.views.vend.publicViewsForBank(bank.bankId)) - publicAccounts<- Full(bank.publicAccounts(publicAccountAccess)) - } yield { - val publicAccountsJson = publicBankAccountsListToJson(publicAccounts, publicViewsForBank) - successJsonResponse(publicAccountsJson) - } - } - } - - resourceDocs += ResourceDoc( - accountById, - apiVersion, - "accountById", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/account", - "Get account by id", - s"""Information returned about an account specified by ACCOUNT_ID as moderated by the view (VIEW_ID): - | - |* Number - |* Owners - |* Type - |* Balance - |* IBAN - |* Available views - | - |More details about the data moderation by the view [here](#1_2_1-getViewsForBankAccount). - | - |${userAuthenticationMessage(false)} - | - |Authentication is required if the 'is_public' field in view (VIEW_ID) is not set to `true`. - | - |""".stripMargin, - EmptyBody, - moderatedAccountJSON, - List(AuthenticatedUserIsRequired, UnknownError, BankAccountNotFound), - apiTagAccount :: apiTagOldStyle :: Nil) - - lazy val accountById : OBPEndpoint = { - //get account by id - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "account" :: Nil JsonGet req => { - cc => - for { - u <- cc.user ?~ AuthenticatedUserIsRequired - (account, callContext) <- BankAccountX(bankId, accountId, Some(cc)) ?~! BankAccountNotFound - availableviews <- Full(Views.views.vend.privateViewsUserCanAccessForAccount(u, BankIdAccountId(account.bankId, account.accountId))) - view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), Some(u), callContext) - moderatedAccount <- account.moderatedBankAccount(view, BankIdAccountId(bankId, accountId), cc.user, callContext) - } yield { - val viewsAvailable = availableviews.map(JSONFactory.createViewJSON) - val moderatedAccountJson = JSONFactory.createBankAccountJSON(moderatedAccount, viewsAvailable) - successJsonResponse(Extraction.decompose(moderatedAccountJson)) - } - } - } - - resourceDocs += ResourceDoc( - updateAccountLabel, - apiVersion, - "updateAccountLabel", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID", - "Update Account Label", - s"""Update the label for the account. The label is how the account is known to the account owner e.g. 'My savings account' - | - | - |${userAuthenticationMessage(true)} - | - """.stripMargin, - updateAccountJSON, - successMessage, - List(InvalidJsonFormat, AuthenticatedUserIsRequired, UnknownError, BankAccountNotFound, "user does not have access to owner view on account"), - List(apiTagAccount) - ) - - lazy val updateAccountLabel : OBPEndpoint = { - //change account label - // TODO Remove BANK_ID AND ACCOUNT_ID from the body? (duplicated in URL) - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - json <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[UpdateAccountJSON] } - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - permission <- NewStyle.function.permission(account.bankId, account.accountId, u, callContext) - anyViewContainsCanUpdateBankAccountLabelPermission = permission.views.map(_.allowed_actions.exists(_ == CAN_UPDATE_BANK_ACCOUNT_LABEL)).find(true == _).getOrElse(false) - _ <- Helper.booleanToFuture( - s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_UPDATE_BANK_ACCOUNT_LABEL)}` permission on any your views", - cc = callContext - ) { - anyViewContainsCanUpdateBankAccountLabelPermission - } - (success, callContext) <- - Connector.connector.vend.updateAccountLabel(bankId, accountId, json.label, callContext) map { i => - (unboxFullOrFail(i._1, i._2, - s"$UpdateBankAccountLabelError Current BankId is $bankId and Current AccountId is $accountId", 404), i._2) - } - } yield { - (successMessage, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getViewsForBankAccount, - apiVersion, - "getViewsForBankAccount", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/views", - "Get Views for Account", - s"""#Views - | - | - |Views in Open Bank Project provide a mechanism for fine grained access control and delegation to Accounts and Transactions. Account holders use the 'owner' view by default. Delegated access is made through other views for example 'accountants', 'share-holders' or 'tagging-application'. Views can be created via the API and each view has a list of entitlements. - | - |Views on accounts and transactions filter the underlying data to redact certain fields for certain users. For instance the balance on an account may be hidden from the public. The way to know what is possible on a view is determined in the following JSON. - | - |**Data:** When a view moderates a set of data, some fields my contain the value `null` rather than the original value. This indicates either that the user is not allowed to see the original data or the field is empty. - | - |There is currently one exception to this rule; the 'holder' field in the JSON contains always a value which is either an alias or the real name - indicated by the 'is_alias' field. - | - |**Action:** When a user performs an action like trying to post a comment (with POST API call), if he is not allowed, the body response will contain an error message. - | - |**Metadata:** - |Transaction metadata (like images, tags, comments, etc.) will appears *ONLY* on the view where they have been created e.g. comments posted to the public view only appear on the public view. - | - |The other account metadata fields (like image_URL, more_info, etc.) are unique through all the views. Example, if a user edits the 'more_info' field in the 'team' view, then the view 'authorities' will show the new value (if it is allowed to do it). - | - |# All - |*Optional* - | - |Returns the list of the views created for account ACCOUNT_ID at BANK_ID. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", - EmptyBody, - viewsJSONV121, - List(AuthenticatedUserIsRequired, BankAccountNotFound, UnknownError, "user does not have owner access"), - List(apiTagView, apiTagAccount, apiTagOldStyle)) - - lazy val getViewsForBankAccount : OBPEndpoint = { - //get the available views on an bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonGet req => { - cc => - for { - u <- cc.user ?~ AuthenticatedUserIsRequired - bankAccount <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound - permission <- Views.views.vend.permission(BankIdAccountId(bankAccount.bankId, bankAccount.accountId), u) - anyViewContainsCanSeeAvailableViewsForBankAccountPermission = permission.views.map(_.allowed_actions.exists(_ == CAN_SEE_AVAILABLE_VIEWS_FOR_BANK_ACCOUNT)).find(_.==(true)).getOrElse(false) - _ <- Helper.booleanToBox( - anyViewContainsCanSeeAvailableViewsForBankAccountPermission, - s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_SEE_AVAILABLE_VIEWS_FOR_BANK_ACCOUNT)}` permission on any your views" - ) - views <- Full(Views.views.vend.availableViewsForAccount(BankIdAccountId(bankAccount.bankId, bankAccount.accountId))) - } yield { - val viewsJSON = JSONFactory.createViewsJSON(views) - successJsonResponse(Extraction.decompose(viewsJSON)) - } - } - } - - resourceDocs += ResourceDoc( - createViewForBankAccount, - apiVersion, - "createViewForBankAccount", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/views", - "Create View", - s"""#Create a view on bank account - | - | ${userAuthenticationMessage(true)} and the user needs to have access to the owner view. - | The 'alias' field in the JSON can take one of three values: - | - | * _public_: to use the public alias if there is one specified for the other account. - | * _private_: to use the private alias if there is one specified for the other account. - | - | * _''(empty string)_: to use no alias; the view shows the real name of the other account. - | - | The 'hide_metadata_if_alias_used' field in the JSON can take boolean values. If it is set to `true` and there is an alias on the other account then the other accounts' metadata (like more_info, url, image_url, open_corporates_url, etc.) will be hidden. Otherwise the metadata will be shown. - | - | The 'allowed_actions' field is a list containing the name of the actions allowed on this view, all the actions contained will be set to `true` on the view creation, the rest will be set to `false`.""", - createViewJsonV121, - viewJSONV121, - List( - AuthenticatedUserIsRequired, - InvalidJsonFormat, - BankAccountNotFound, - UnknownError, - "user does not have owner access" - ), - List(apiTagAccount, apiTagView, apiTagOldStyle) - ) - - lazy val createViewForBankAccount : OBPEndpoint = { - //creates a view on an bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonPost json -> _ => { - cc => - for { - u <- cc.user ?~ AuthenticatedUserIsRequired - createViewJsonV121 <- tryo{json.extract[CreateViewJsonV121]} ?~ InvalidJsonFormat - //customer views are started ith `_`,eg _life, _work, and System views startWith letter, eg: owner - _<- booleanToBox(isValidCustomViewName(createViewJsonV121.name), InvalidCustomViewFormat+s"Current view_name (${createViewJsonV121.name})") - account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound - createViewJson = CreateViewJson( - createViewJsonV121.name, - createViewJsonV121.description, - metadata_view = "", //this only used from V300 - createViewJsonV121.is_public, - createViewJsonV121.which_alias_to_use, - createViewJsonV121.hide_metadata_if_alias_used, - createViewJsonV121.allowed_actions - ) - anyViewContainsCanCreateCustomViewPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) - .map(_.views.map(_.allowed_actions.exists(_ == CAN_CREATE_CUSTOM_VIEW))).getOrElse(Nil).find(_.==(true)).getOrElse(false) - _ <- booleanToBox( - anyViewContainsCanCreateCustomViewPermission, - s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_CREATE_CUSTOM_VIEW)}` permission on any your views" - ) - view <- Views.views.vend.createCustomView(BankIdAccountId(bankId,accountId), createViewJson)?~ CreateCustomViewError - } yield { - val viewJSON = JSONFactory.createViewJSON(view) - successJsonResponse(Extraction.decompose(viewJSON), 201) - } - } - } - - resourceDocs += ResourceDoc( - updateViewForBankAccount, - apiVersion, - "updateViewForBankAccount", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID", - "Update View", - s"""Update an existing view on a bank account - | - |${userAuthenticationMessage(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)""", - updateViewJsonV121, - viewJSONV121, - List( - InvalidJsonFormat, - AuthenticatedUserIsRequired, - BankAccountNotFound, - ViewNotFound, - UnknownError, - "user does not have owner access" - ), - List(apiTagAccount, apiTagView, apiTagOldStyle) - ) - - //TODO. remove and replace it with V510. - lazy val updateViewForBankAccount: OBPEndpoint = { - //updates a view on a bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId - ) :: "views" :: ViewId(viewId) :: Nil JsonPut json -> _ => { - cc => - for { - updateJsonV121 <- tryo{ json.extract[UpdateViewJsonV121] } ?~ InvalidJsonFormat - account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound - u <- cc.user ?~ AuthenticatedUserIsRequired - //customer views are started ith `_`,eg _life, _work, and System views startWith letter, eg: owner - _ <- booleanToBox(viewId.value.startsWith("_"), InvalidCustomViewFormat +s"Current view_id (${viewId.value})") - view <- Views.views.vend.customView(viewId, BankIdAccountId(bankId, accountId)) ?~! ViewNotFound - _ <- booleanToBox(!view.isSystem, SystemViewsCanNotBeModified) - updateViewJson = UpdateViewJSON( - description = updateJsonV121.description, - metadata_view = view.metadataView, //this only used from V300, here just copy from currentView . - is_public = updateJsonV121.is_public, - which_alias_to_use = updateJsonV121.which_alias_to_use, - hide_metadata_if_alias_used = updateJsonV121.hide_metadata_if_alias_used, - allowed_actions = updateJsonV121.allowed_actions - ) - anyViewContainsCanUpdateCustomViewPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) - .map(_.views.map(_.allowed_actions.exists(_ == CAN_UPDATE_CUSTOM_VIEW))).getOrElse(Nil).find(_.==(true)).getOrElse(false) - _ <- booleanToBox( - anyViewContainsCanUpdateCustomViewPermission, - s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_UPDATE_CUSTOM_VIEW)}` permission on any your views" - ) - updatedView <- Views.views.vend.updateCustomView(BankIdAccountId(bankId, accountId),viewId, updateViewJson) ?~ CreateCustomViewError - } yield { - val viewJSON = JSONFactory.createViewJSON(updatedView) - successJsonResponse(Extraction.decompose(viewJSON), 200) - } - } - } - - resourceDocs += ResourceDoc( - deleteViewForBankAccount, - apiVersion, - "deleteViewForBankAccount", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID", - "Delete Custom View", - "Deletes the custom view specified by VIEW_ID on the bank account specified by ACCOUNT_ID at bank BANK_ID", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - UnknownError, - "user does not have owner access" - ), - List(apiTagView, apiTagAccount) - ) - - lazy val deleteViewForBankAccount: OBPEndpoint = { - //deletes a view on an bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId - ) :: "views" :: ViewId(viewId) :: Nil JsonDelete req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) - // custom views start with `_` eg _play, _work, and System views start with a letter, eg: owner - _ <- Helper.booleanToFuture(InvalidCustomViewFormat+s"Current view_name (${viewId.value})", cc=callContext) { viewId.value.startsWith("_") } - _ <- ViewNewStyle.customView(viewId, BankIdAccountId(bankId, accountId), callContext) - - anyViewContainsCanDeleteCustomViewPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) - .map(_.views.map(_.allowed_actions.exists(_ == CAN_DELETE_CUSTOM_VIEW))).getOrElse(Nil).find(_.==(true)).getOrElse(false) - _ <- Helper.booleanToFuture( - s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_DELETE_CUSTOM_VIEW)}` permission on any your views", - cc = callContext - ) { - anyViewContainsCanDeleteCustomViewPermission - } - - deleted <- ViewNewStyle.removeCustomView(viewId, BankIdAccountId(bankId, accountId),callContext) - } yield { - (Full(deleted), HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getPermissionsForBankAccount, - apiVersion, - "getPermissionsForBankAccount", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions", - "Get access", - s"""Returns the list of the permissions at BANK_ID for account ACCOUNT_ID, with each time a pair composed of the user and the views that he has access to. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", - EmptyBody, - permissionsJSON, - List(AuthenticatedUserIsRequired, UnknownError), - List(apiTagView, apiTagAccount, apiTagEntitlement, apiTagOldStyle) - ) - - lazy val getPermissionsForBankAccount: OBPEndpoint = { - //get access - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: Nil JsonGet req => { - cc => - for { - u <- cc.user ?~ AuthenticatedUserIsRequired - account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound - anyViewContainsCanSeeViewsWithPermissionsForAllUsersPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) - .map(_.views.map(_.allowed_actions.exists(_ == CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ALL_USERS))).getOrElse(Nil).find(_.==(true)).getOrElse(false) - _ <- booleanToBox( - anyViewContainsCanSeeViewsWithPermissionsForAllUsersPermission, - s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ALL_USERS)}` permission on any your views" - ) - permissions = Views.views.vend.permissions(BankIdAccountId(bankId, accountId)) - } yield { - val permissionsJSON = JSONFactory.createPermissionsJSON(permissions) - successJsonResponse(Extraction.decompose(permissionsJSON)) - } - } - } - - resourceDocs += ResourceDoc( - getPermissionForUserForBankAccount, - apiVersion, - "getPermissionForUserForBankAccount", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER_ID/USER_ID", - "Get access for specific user", - s"""Returns the list of the views at BANK_ID for account ACCOUNT_ID that a USER_ID at their provider PROVIDER_ID has access to. - |All url parameters must be [%-encoded](http://en.wikipedia.org/wiki/Percent-encoding), which is often especially relevant for USER_ID and PROVIDER_ID. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", - EmptyBody, - viewsJSONV121, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - UnknownError, - "user does not have access to owner view on account" - ), - List(apiTagAccount, apiTagView, apiTagEntitlement, apiTagOldStyle) - ) - - - lazy val getPermissionForUserForBankAccount: OBPEndpoint = { - //get access for specific user - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: Nil JsonGet req => { - cc => - for { - loggedInUser <- cc.user ?~ AuthenticatedUserIsRequired - account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound - loggedInUserPermissionBox = Views.views.vend.permission(BankIdAccountId(bankId, accountId), loggedInUser) - anyViewContainsCanSeeViewsWithPermissionsForOneUserPermission = loggedInUserPermissionBox.map(_.views.map(_.allowed_actions.exists(_ == CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ONE_USER))) - .getOrElse(Nil).find(_.==(true)).getOrElse(false) - _ <- booleanToBox( - anyViewContainsCanSeeViewsWithPermissionsForOneUserPermission, - s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ONE_USER)}` permission on any your views" - ) - userFromURL <- UserX.findByProviderId(provider, providerId) ?~! UserNotFoundByProviderAndProvideId - permission <- Views.views.vend.permission(BankIdAccountId(bankId, accountId), userFromURL) - } yield { - val views = JSONFactory.createViewsJSON(permission.views) - successJsonResponse(Extraction.decompose(views)) - } - } - } - - resourceDocs += ResourceDoc( - addPermissionForUserForBankAccountForMultipleViews, - apiVersion, - "addPermissionForUserForBankAccountForMultipleViews", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views", - "Grant User access to a list of views", - s"""Grants the user identified by PROVIDER_ID at their provider PROVIDER access to a list of views at BANK_ID for account ACCOUNT_ID. - | - |All url parameters must be [%-encoded](http://en.wikipedia.org/wiki/Percent-encoding), which is often especially relevant for PROVIDER_ID and PROVIDER. - | - |${userAuthenticationMessage(true)} - | - |The User needs to have access to the owner view.""", - viewIdsJson, - viewsJSONV121, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - UnknownError, - "wrong format JSON", - "could not save the privilege", - "user does not have access to owner view on account" - ), - List(apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired)) - - lazy val addPermissionForUserForBankAccountForMultipleViews : OBPEndpoint = { - //add access for specific user to a list of views - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) - failMsg = "wrong format JSON" - viewIds <- NewStyle.function.tryons(failMsg, 400, callContext) { json.extract[ViewIdsJson] } - (addedViews, callContext) <- ViewNewStyle.grantAccessToMultipleViews( - account, u, - viewIds.views.map(viewIdString => BankIdAccountIdViewId(bankId, accountId,ViewId(viewIdString))), - provider, - providerId, - callContext - ) - } yield { - (JSONFactory.createViewsJSON(addedViews), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addPermissionForUserForBankAccountForOneView, - apiVersion, - "addPermissionForUserForBankAccountForOneView", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views/VIEW_ID", - "Grant User access to View", - s"""Grants the User identified by PROVIDER_ID at PROVIDER access to the view VIEW_ID at BANK_ID for account ACCOUNT_ID. - | - |All url parameters must be [%-encoded](http://en.wikipedia.org/wiki/Percent-encoding), which is often especially relevant for PROVIDER and PROVIDER_ID. - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view. - | - |Granting access to a public view will return an error message, as the user already has access.""", - EmptyBody, // No Json body required - viewJSONV121, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - UnknownError, - UserLacksPermissionCanGrantAccessToViewForTargetAccount, - "could not save the privilege", - "user does not have access to owner view on account" - ), - List(apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired)) - - lazy val addPermissionForUserForBankAccountForOneView : OBPEndpoint = { - //add access for specific user to a specific view - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: ViewId(viewId) :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) - (addedView, callContext) <- ViewNewStyle.grantAccessToView(account, u, BankIdAccountIdViewId(bankId, accountId, viewId), provider, providerId, callContext) - } yield { - val viewJson = JSONFactory.createViewJSON(addedView) - (viewJson, HttpCode.`201`(callContext)) - } - } - } - - - val generalRevokeAccessToViewText : String = - """ - |The User is identified by PROVIDER_ID at their PROVIDER. - | - |The Account is specified by BANK_ID and ACCOUNT_ID. - | - |The View is specified by VIEW_ID. - | - | - |PROVIDER (may be a URL so) must be URL Encoded. - | - |PROVIDER_ID is normally equivalent to USERNAME. However, see Get User by ID or GET Current User for Provider information. - | - |Attempting to revoke access to a public view will return an error message. - | - |An Account Owner cannot revoke access to an Owner View unless at least one other User has Owner View access. - | - """.stripMargin - - - resourceDocs += ResourceDoc( - removePermissionForUserForBankAccountForOneView, - apiVersion, - "removePermissionForUserForBankAccountForOneView", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views/VIEW_ID", - "Revoke access to one View", - s"""Revokes access to a View on an Account for a certain User. - | - |$generalRevokeAccessToViewText - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "could not save the privilege", - "user does not have access to owner view on account", - UnknownError - ), - List(apiTagView, apiTagAccount, apiTagUser, apiTagEntitlement, apiTagOwnerRequired)) - - lazy val removePermissionForUserForBankAccountForOneView : OBPEndpoint = { - //delete access for specific user to one view - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: ViewId(viewId) :: Nil JsonDelete req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) - _ <- ViewNewStyle.revokeAccessToView(account, u, BankIdAccountIdViewId(bankId, accountId, viewId), provider, providerId, callContext) - } yield { - (Full(""), HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - removePermissionForUserForBankAccountForAllViews, - apiVersion, - "removePermissionForUserForBankAccountForAllViews", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views", - "Revoke access to all Views on Account", - s""""Revokes access to all Views on an Account for a certain User. - | - |$generalRevokeAccessToViewText - | - |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - UnknownError, - "user does not have access to owner view on account" - ), - List(apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired)) - - lazy val removePermissionForUserForBankAccountForAllViews : OBPEndpoint = { - //delete access for specific user to all the views - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: Nil JsonDelete req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) - _ <- NewStyle.function.revokeAllAccountAccess(account, u, provider, providerId, callContext) - } yield { - (Full(""), HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getOtherAccountsForBankAccount, - apiVersion, - "getOtherAccountsForBankAccount", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts", - "Get Other Accounts of one Account", - s"""Returns data about all the other accounts that have shared at least one transaction with the ACCOUNT_ID at BANK_ID. - |${userAuthenticationMessage(false)} - |Authentication is required if the view VIEW_ID is not public.""", - EmptyBody, - otherAccountsJSON, - List( - BankAccountNotFound, - UnknownError - ), - List(apiTagCounterparty, apiTagAccount, apiTagPsd2, apiTagOldStyle)) - - lazy val getOtherAccountsForBankAccount : OBPEndpoint = { - //get other accounts for one account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, Some(cc)) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), cc.user, callContext) - (otherBankAccounts, callContext) <- NewStyle.function.moderatedOtherBankAccounts(account, view, cc.user, callContext) - } yield { - (JSONFactory.createOtherBankAccountsJSON(otherBankAccounts), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getOtherAccountByIdForBankAccount, - apiVersion, - "getOtherAccountByIdForBankAccount", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID", - "Get Other Account by Id", - s"""Returns data about the Other Account that has shared at least one transaction with ACCOUNT_ID at BANK_ID. - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public.""", - EmptyBody, - otherAccountJSON, - List(BankAccountNotFound, UnknownError), - List(apiTagCounterparty, apiTagAccount)) - - lazy val getOtherAccountByIdForBankAccount : OBPEndpoint = { - //get one other account by id - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (u, callContext) <- authenticatedAccess(cc) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), u, callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, u, callContext) - } yield { - val otherBankAccountJson = JSONFactory.createOtherBankAccount(otherBankAccount) - (otherBankAccountJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getOtherAccountMetadata, - apiVersion, - "getOtherAccountMetadata", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata", - "Get Other Account Metadata", - """Get metadata of one other account. - |Returns only the metadata about one other bank account (OTHER_ACCOUNT_ID) that had shared at least one transaction with ACCOUNT_ID at BANK_ID. - | - |Authentication via OAuth is required if the view is not public.""", - EmptyBody, - otherAccountMetadataJSON, - List(AuthenticatedUserIsRequired, UnknownError, "the view does not allow metadata access"), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val getOtherAccountMetadata : OBPEndpoint = { - //get metadata of one other account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - } yield { - val metadataJson = JSONFactory.createOtherAccountMetaDataJSON(otherBankAccount.metadata.get) - (metadataJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getCounterpartyPublicAlias, - apiVersion, - "getCounterpartyPublicAlias", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", - "Get public alias of other bank account", - s"""Returns the public alias of the other account OTHER_ACCOUNT_ID. - |${userAuthenticationMessage(false)} - |${userAuthenticationMessage(true)} if the view is not public.""", - EmptyBody, - aliasJSON, - List( - BankAccountNotFound, - UnknownError, - "the view does not allow metadata access", - "the view does not allow public alias access" - ), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val getCounterpartyPublicAlias : OBPEndpoint = { - //get public alias of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a public alias", cc=callContext) { - otherBankAccount.metadata.get.publicAlias.isDefined - } - } yield { - val aliasJson = JSONFactory.createAliasJSON(otherBankAccount.metadata.get.publicAlias.get) - (aliasJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addCounterpartyPublicAlias, - apiVersion, - "addCounterpartyPublicAlias", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", - "Add public alias to other bank account", - s"""Creates the public alias for the other account OTHER_ACCOUNT_ID. - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public. - | - |Note: Public aliases are automatically generated for new 'other accounts / counterparties', so this call should only be used if - |the public alias was deleted. - | - |The VIEW_ID parameter should be a view the caller is permitted to access to and that has permission to create public aliases.""", - aliasJSON, - successMessage, - List( - BankAccountNotFound, - InvalidJsonFormat, - UnknownError, - "the view does not allow metadata access", - "the view does not allow adding a public alias", - "Alias cannot be added", - "public alias added" - ), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val addCounterpartyPublicAlias : OBPEndpoint = { - //add public alias to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a public alias", cc=callContext) { - otherBankAccount.metadata.get.addPublicAlias.isDefined - } - aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[AliasJSON] - } - (added, _) <- Future(Counterparties.counterparties.vend.addPublicAlias(other_account_id, aliasJson.alias)) map { i => - (unboxFullOrFail(i, callContext, "Alias cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("public alias added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyPublicAlias, - apiVersion, - "updateCounterpartyPublicAlias", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", - "Update public alias of other bank account", - s"""Updates the public alias of the other account / counterparty OTHER_ACCOUNT_ID. - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public.""", - aliasJSON, - successMessage, - List( - BankAccountNotFound, - InvalidJsonFormat, - AuthenticatedUserIsRequired, - "the view does not allow metadata access", - "the view does not allow updating the public alias", - "Alias cannot be updated", - UnknownError - ), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyPublicAlias : OBPEndpoint = { - //update public alias of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a public alias", cc=callContext) { - otherBankAccount.metadata.get.addPublicAlias.isDefined - } - aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[AliasJSON] - } - (updated, _) <- Future(Counterparties.counterparties.vend.addPublicAlias(other_account_id, aliasJson.alias)) map { i => - (unboxFullOrFail(i, callContext, "Alias cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("public alias updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyPublicAlias, - apiVersion, - "deleteCounterpartyPublicAlias", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", - "Delete Counterparty Public Alias", - s"""Deletes the public alias of the other account OTHER_ACCOUNT_ID. - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public.""", - EmptyBody, - EmptyBody, - List( - BankAccountNotFound, - "the view does not allow metadata access", - "the view does not allow deleting the public alias", - "Alias cannot be deleted", - UnknownError - ), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val deleteCounterpartyPublicAlias : OBPEndpoint = { - //delete public alias of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a public alias", cc=callContext) { - otherBankAccount.metadata.get.addPublicAlias.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.addPublicAlias(other_account_id, "")) map { i => - (unboxFullOrFail(i, callContext, "Alias cannot be deleted", 400), i) - } - if(deleted) - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getOtherAccountPrivateAlias, - apiVersion, - "getOtherAccountPrivateAlias", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", - "Get Other Account Private Alias", - s"""Returns the private alias of the other account OTHER_ACCOUNT_ID. - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public.""", - EmptyBody, - aliasJSON, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "the view does not allow metadata access", - "the view does not allow private alias access", - UnknownError - ), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val getOtherAccountPrivateAlias : OBPEndpoint = { - //get private alias of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a private alias", cc=callContext) { - otherBankAccount.metadata.get.privateAlias.isDefined - } - } yield { - val aliasJson = JSONFactory.createAliasJSON(otherBankAccount.metadata.get.privateAlias.get) - (aliasJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addOtherAccountPrivateAlias, - apiVersion, - "addOtherAccountPrivateAlias", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", - "Create Other Account Private Alias", - s"""Creates a private alias for the other account OTHER_ACCOUNT_ID. - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public.""", - aliasJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow adding a private alias", - "Alias cannot be added", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val addOtherAccountPrivateAlias : OBPEndpoint = { - //add private alias to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a private alias", cc=callContext) { - otherBankAccount.metadata.get.addPrivateAlias.isDefined - } - aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[AliasJSON] - } - (added, _) <- Future(Counterparties.counterparties.vend.addPrivateAlias(other_account_id, aliasJson.alias)) map { i => - (unboxFullOrFail(i, callContext, "Alias cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("private alias added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyPrivateAlias, - apiVersion, - "updateCounterpartyPrivateAlias", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", - "Update Counterparty Private Alias", - s"""Updates the private alias of the counterparty (AKA other account) OTHER_ACCOUNT_ID. - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public.""", - aliasJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow updating the private alias", - "Alias cannot be updated", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyPrivateAlias : OBPEndpoint = { - //update private alias of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a private alias", cc=callContext) { - otherBankAccount.metadata.get.addPrivateAlias.isDefined - } - aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[AliasJSON] - } - (updated, _) <- Future(Counterparties.counterparties.vend.addPrivateAlias(other_account_id, aliasJson.alias)) map { i => - (unboxFullOrFail(i, callContext, "Alias cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("private alias updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyPrivateAlias, - apiVersion, - "deleteCounterpartyPrivateAlias", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", - "Delete Counterparty Private Alias", - s"""Deletes the private alias of the other account OTHER_ACCOUNT_ID. - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public.""", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "the view does not allow metadata access", - "the view does not allow deleting the private alias", - "Alias cannot be deleted", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val deleteCounterpartyPrivateAlias : OBPEndpoint = { - //delete private alias of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a private alias", cc=callContext) { - otherBankAccount.metadata.get.addPrivateAlias.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.addPrivateAlias(other_account_id, "")) map { i => - (unboxFullOrFail(i, callContext, "Alias cannot be deleted", 400), i) - } - if(deleted) - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - //TODO: get more info of counterparty? - - resourceDocs += ResourceDoc( - addCounterpartyMoreInfo, - apiVersion, - "addCounterpartyMoreInfo", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/more_info", - "Add Counterparty More Info", - "Add a description of the counter party from the perpestive of the account e.g. My dentist", - moreInfoJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - NoViewPermission, - "the view " + viewIdSwagger + "does not allow adding more info", - "More Info cannot be added", - UnknownError - ), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val addCounterpartyMoreInfo : OBPEndpoint = { - //add more info to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "more_info" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding more info", cc=callContext) { - otherBankAccount.metadata.get.addMoreInfo.isDefined - } - moreInfoJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[MoreInfoJSON] - } - (added, _) <- Future(Counterparties.counterparties.vend.addMoreInfo(other_account_id, moreInfoJson.more_info)) map { i => - (unboxFullOrFail(i, callContext, "More Info cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("more info added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyMoreInfo, - apiVersion, - "updateCounterpartyMoreInfo", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/more_info", - "Update Counterparty More Info", - "Update the more info description of the counter party from the perpestive of the account e.g. My dentist", - moreInfoJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow updating more info", - "More Info cannot be updated", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyMoreInfo : OBPEndpoint = { - //update more info of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "more_info" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating more info", cc=callContext) { - otherBankAccount.metadata.get.addMoreInfo.isDefined - } - moreInfoJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[MoreInfoJSON] - } - (updated, _) <- Future(Counterparties.counterparties.vend.addMoreInfo(other_account_id, moreInfoJson.more_info)) map { i => - (unboxFullOrFail(i, callContext, "More Info cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("more info updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyMoreInfo, - apiVersion, - "deleteCounterpartyMoreInfo", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/more_info", - "Delete more info of other bank account", - "", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "the view does not allow metadata access", - "the view does not allow deleting more info", - "More Info cannot be deleted", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val deleteCounterpartyMoreInfo : OBPEndpoint = { - //delete more info of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "more_info" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting more info", cc=callContext) { - otherBankAccount.metadata.get.addMoreInfo.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.addMoreInfo(other_account_id, "")) map { i => - (unboxFullOrFail(i, callContext, "More Info cannot be deleted", 400), i) - } - if(deleted) - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - //TODO: get url of counterparty? - - resourceDocs += ResourceDoc( - addCounterpartyUrl, - apiVersion, - "addCounterpartyUrl", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/url", - "Add url to other bank account", - "A url which represents the counterparty (home page url etc.)", - urlJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow adding a url", - "URL cannot be added", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - - lazy val addCounterpartyUrl : OBPEndpoint = { - //add url to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "url" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a url", cc=callContext) { - otherBankAccount.metadata.get.addURL.isDefined - } - urlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[UrlJSON] - } - (added, _) <- Future(Counterparties.counterparties.vend.addURL(other_account_id, urlJson.URL)) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("url added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyUrl, - apiVersion, - "updateCounterpartyUrl", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/url", - "Update url of other bank account", - "A url which represents the counterparty (home page url etc.)", - urlJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - NoViewPermission, - ViewNotFound, - "URL cannot be updated", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyUrl : OBPEndpoint = { - //update url of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "url" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a url", cc=callContext) { - otherBankAccount.metadata.get.addURL.isDefined - } - urlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[UrlJSON] - } - (updated, _) <- Future(Counterparties.counterparties.vend.addURL(other_account_id, urlJson.URL)) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("url updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyUrl, - apiVersion, - "deleteCounterpartyUrl", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/url", - "Delete url of other bank account", - "", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "the view does not allow metadata access", - "the view does not allow deleting a url", - "URL cannot be deleted", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val deleteCounterpartyUrl : OBPEndpoint = { - //delete url of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "url" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a url", cc=callContext) { - otherBankAccount.metadata.get.addURL.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.addURL(other_account_id, "")) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be deleted", 400), i) - } - if(deleted) - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - //TODO: get image url of counterparty? - - resourceDocs += ResourceDoc( - addCounterpartyImageUrl, - apiVersion, - "addCounterpartyImageUrl", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/image_url", - "Add image url to other bank account", - "Add a url that points to the logo of the counterparty", - imageUrlJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow adding an image url", - "URL cannot be added", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val addCounterpartyImageUrl : OBPEndpoint = { - //add image url to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "image_url" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding an image url", cc=callContext) { - otherBankAccount.metadata.get.addImageURL.isDefined - } - imageUrlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[ImageUrlJSON] - } - (added, _) <- Future(Counterparties.counterparties.vend.addImageURL(other_account_id, imageUrlJson.image_URL)) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("image url added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyImageUrl, - apiVersion, - "updateCounterpartyImageUrl", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/image_url", - "Update Counterparty Image Url", - "Update the url that points to the logo of the counterparty", - imageUrlJSON, - successMessage, - List( - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow updating an image url", - "URL cannot be updated", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyImageUrl : OBPEndpoint = { - //update image url of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "image_url" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating an image url", cc=callContext) { - otherBankAccount.metadata.get.addImageURL.isDefined - } - imageUrlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[ImageUrlJSON] - } - (updated, _) <- Future(Counterparties.counterparties.vend.addImageURL(other_account_id, imageUrlJson.image_URL)) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("image url updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyImageUrl, - apiVersion, - "deleteCounterpartyImageUrl", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/image_url", - "Delete Counterparty Image URL", - "Delete image url of other bank account", - EmptyBody, - EmptyBody, - List(UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) // Tag general then specific for consistent sorting - - lazy val deleteCounterpartyImageUrl : OBPEndpoint = { - //delete image url of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "image_url" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting an image url", cc=callContext) { - otherBankAccount.metadata.get.addImageURL.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.addImageURL(other_account_id, "")) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be deleted", 400), i) - } - if(deleted) - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - //TODO: get open corporates url of counterparty? - - resourceDocs += ResourceDoc( - addCounterpartyOpenCorporatesUrl, - apiVersion, - "addCounterpartyOpenCorporatesUrl", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/open_corporates_url", - "Add Open Corporates URL to Counterparty", - "Add open corporates url to other bank account", - openCorporateUrlJSON, - successMessage, - List( - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow adding an open corporate url", - "URL cannot be added", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val addCounterpartyOpenCorporatesUrl : OBPEndpoint = { - //add open corporate url to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "open_corporates_url" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding an open corporate url", cc=callContext) { - otherBankAccount.metadata.get.addOpenCorporatesURL.isDefined - } - openCorpUrl <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[OpenCorporateUrlJSON] - } - (added, _) <- Future(Counterparties.counterparties.vend.addOpenCorporatesURL(other_account_id, openCorpUrl.open_corporates_URL)) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("open corporate url added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyOpenCorporatesUrl, - apiVersion, - "updateCounterpartyOpenCorporatesUrl", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/open_corporates_url", - "Update Open Corporates Url of Counterparty", - "Update open corporate url of other bank account", - openCorporateUrlJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow updating an open corporate url", - "URL cannot be updated", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyOpenCorporatesUrl : OBPEndpoint = { - //update open corporate url of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "open_corporates_url" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating an open corporate url", cc=callContext) { - otherBankAccount.metadata.get.addOpenCorporatesURL.isDefined - } - openCorpUrl <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[OpenCorporateUrlJSON] - } - (updated, _) <- Future(Counterparties.counterparties.vend.addOpenCorporatesURL(other_account_id, openCorpUrl.open_corporates_URL)) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("open corporate url updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyOpenCorporatesUrl, - apiVersion, - "deleteCounterpartyOpenCorporatesUrl", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/open_corporates_url", - "Delete Counterparty Open Corporates URL", - "Delete open corporate url of other bank account", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "the view does not allow metadata access", - "the view does not allow deleting an open corporate url", - "URL cannot be deleted", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val deleteCounterpartyOpenCorporatesUrl : OBPEndpoint = { - //delete open corporate url of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "open_corporates_url" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting an open corporate url", cc=callContext) { - otherBankAccount.metadata.get.addOpenCorporatesURL.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.addOpenCorporatesURL(other_account_id, "")) map { i => - (unboxFullOrFail(i, callContext, "URL cannot be deleted", 400), i) - } - if(deleted) - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - //TODO: get corporate location of counterparty? - - resourceDocs += ResourceDoc( - addCounterpartyCorporateLocation, - apiVersion, - "addCounterpartyCorporateLocation", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/corporate_location", - "Add Corporate Location to Counterparty", - "Add the geolocation of the counterparty's registered address", - corporateLocationJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "the view does not allow metadata access", - "the view does not allow adding a corporate location", - "Coordinates not possible", - "Corporate Location cannot be deleted", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val addCounterpartyCorporateLocation : OBPEndpoint = { - //add corporate location to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts" :: other_account_id :: "metadata" :: "corporate_location" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a corporate location", cc=callContext) { - otherBankAccount.metadata.get.addCorporateLocation.isDefined - } - corpLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[CorporateLocationJSON] - } - _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { - checkIfLocationPossible(corpLocationJson.corporate_location.latitude, corpLocationJson.corporate_location.longitude).isDefined - } - (added, _) <- Future( - Counterparties.counterparties.vend.addCorporateLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), corpLocationJson.corporate_location.longitude, corpLocationJson.corporate_location.latitude) - ) map { i => - (unboxFullOrFail(i, callContext, "Corporate Location cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("corporate location added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyCorporateLocation, - apiVersion, - "updateCounterpartyCorporateLocation", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/corporate_location", - "Update Counterparty Corporate Location", - "Update the geolocation of the counterparty's registered address", - corporateLocationJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow updating a corporate location", - "Coordinates not possible", - "Corporate Location cannot be updated", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyCorporateLocation : OBPEndpoint = { - //update corporate location of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "corporate_location" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a corporate location", cc=callContext) { - otherBankAccount.metadata.get.addCorporateLocation.isDefined - } - corpLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[CorporateLocationJSON] - } - _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { - checkIfLocationPossible(corpLocationJson.corporate_location.latitude, corpLocationJson.corporate_location.longitude).isDefined - } - (updated, _) <- Future(Counterparties.counterparties.vend.addCorporateLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), corpLocationJson.corporate_location.longitude, corpLocationJson.corporate_location.latitude)) map { i => - (unboxFullOrFail(i, callContext, "Corporate Location cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("corporate location updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyCorporateLocation, - apiVersion, - "deleteCounterpartyCorporateLocation", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/corporate_location", - "Delete Counterparty Corporate Location", - "Delete corporate location of other bank account. Delete the geolocation of the counterparty's registered address", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - "the view does not allow metadata access", - "Corporate Location cannot be deleted", - "Delete not completed", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val deleteCounterpartyCorporateLocation : OBPEndpoint = { - //delete corporate location of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "corporate_location" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a Corporate Location", cc=callContext) { - otherBankAccount.metadata.get.deleteCorporateLocation.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.deleteCorporateLocation(other_account_id)) map { i => - (unboxFullOrFail(i, callContext, "Corporate Location cannot be deleted", 400), i) - } - _ <- Helper.booleanToFuture(failMsg = "Delete not completed", cc=callContext) { - deleted - } - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - //TODO: get physical location of counterparty? - - resourceDocs += ResourceDoc( - addCounterpartyPhysicalLocation, - apiVersion, - "addCounterpartyPhysicalLocation", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/physical_location", - "Add physical location to other bank account", - "Add geocoordinates of the counterparty's main location", - physicalLocationJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow adding a physical location", - "Coordinates not possible", - "Physical Location cannot be added", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val addCounterpartyPhysicalLocation : OBPEndpoint = { - //add physical location to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts" :: other_account_id :: "metadata" :: "physical_location" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a physical location", cc=callContext) { - otherBankAccount.metadata.get.addPhysicalLocation.isDefined - } - physicalLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[PhysicalLocationJSON] - } - _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { - checkIfLocationPossible(physicalLocationJson.physical_location.latitude, physicalLocationJson.physical_location.longitude).isDefined - } - (added, _) <- Future( - Counterparties.counterparties.vend.addPhysicalLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), physicalLocationJson.physical_location.longitude, physicalLocationJson.physical_location.latitude) - ) map { i => - (unboxFullOrFail(i, callContext, "Physical Location cannot be added", 400), i) - } - if(added) - } yield { - (SuccessMessage("physical location added"), HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateCounterpartyPhysicalLocation, - apiVersion, - "updateCounterpartyPhysicalLocation", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/physical_location", - "Update Counterparty Physical Location", - "Update geocoordinates of the counterparty's main location", - physicalLocationJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - "the view does not allow metadata access", - "the view does not allow updating a physical location", - "Coordinates not possible", - "Physical Location cannot be updated", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val updateCounterpartyPhysicalLocation : OBPEndpoint = { - //update physical location to other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "physical_location" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a physical location", cc=callContext) { - otherBankAccount.metadata.get.addPhysicalLocation.isDefined - } - physicalLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { - json.extract[PhysicalLocationJSON] - } - _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { - checkIfLocationPossible(physicalLocationJson.physical_location.latitude, physicalLocationJson.physical_location.longitude).isDefined - } - (updated, _) <- Future(Counterparties.counterparties.vend.addPhysicalLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), physicalLocationJson.physical_location.longitude, physicalLocationJson.physical_location.latitude)) map { i => - (unboxFullOrFail(i, callContext, "Physical Location cannot be updated", 400), i) - } - if(updated) - } yield { - (SuccessMessage("physical location updated"), HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteCounterpartyPhysicalLocation, - apiVersion, - "deleteCounterpartyPhysicalLocation", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/physical_location", - "Delete Counterparty Physical Location", - "Delete physical location of other bank account", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - NoViewPermission, - "Physical Location cannot be deleted", - "Delete not completed", - UnknownError), - List(apiTagCounterpartyMetaData, apiTagCounterparty)) - - lazy val deleteCounterpartyPhysicalLocation : OBPEndpoint = { - //delete physical location of other bank account - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "physical_location" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (_, callContext) <- NewStyle.function.getBank(bankId, callContext) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) - _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { - otherBankAccount.metadata.isDefined - } - _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a Physical Location", cc=callContext) { - otherBankAccount.metadata.get.deletePhysicalLocation.isDefined - } - (deleted, _) <- Future(Counterparties.counterparties.vend.deletePhysicalLocation(other_account_id)) map { i => - (unboxFullOrFail(i, callContext, "Physical Location cannot be deleted", 400), i) - } - _ <- Helper.booleanToFuture(failMsg = s"Delete not completed", cc=callContext) { - deleted - } - } yield { - ("", HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getTransactionsForBankAccount, - apiVersion, - "getTransactionsForBankAccount", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions", - "Get Transactions for Account (Full)", - s"""Returns transactions list of the account specified by ACCOUNT_ID and [moderated](#1_2_1-getViewsForBankAccount) by the view (VIEW_ID). - | - |Authentication via OAuth is required if the view is not public. - | - |${urlParametersDocument(true, true)} - | - |""", - EmptyBody, - transactionsJSON, - List(BankAccountNotFound, UnknownError), - List(apiTagTransaction, apiTagAccount, apiTagPsd2, apiTagOldStyle)) - - - - - private def getTransactionsForBankAccountCached( - paramsBox: Box[List[OBPQueryParam]], - user: Box[User], - accountId: AccountId, - bankId: BankId, - viewId : ViewId - ): Box[JsonResponse] = { - /** - * Please note that "var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString)" - * is just a temporary value field with UUID values in order to prevent any ambiguity. - * The real value will be assigned by Macro during compile time at this line of a code: - * https://github.com/OpenBankProject/scala-macros/blob/master/macros/src/main/scala/com/tesobe/CacheKeyFromArgumentsMacro.scala#L49 - */ - var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) - CacheKeyFromArguments.buildCacheKey { - Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(apiMethods121GetTransactionsTTL millisecond) { - for { - params <- paramsBox - bankAccount <- BankAccountX(bankId, accountId) - (bank, callContext) <- BankX(bankId, None) ?~! BankNotFound - view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankAccount.bankId, bankAccount.accountId), user, None) - (transactions, callContext) <- bankAccount.getModeratedTransactions(bank, user, view, BankIdAccountId(bankId, accountId), None, params ) - } yield { - val json = JSONFactory.createTransactionsJSON(transactions) - successJsonResponse(Extraction.decompose(json)) - } - } - } - } - - lazy val getTransactionsForBankAccount : OBPEndpoint = { - //get transactions - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: Nil JsonGet req => { - val paramsBox: Box[List[OBPQueryParam]] = createQueriesByHttpParams(req.request.headers) - cc => getTransactionsForBankAccountCached( - paramsBox: Box[List[OBPQueryParam]], - cc.user: Box[User], - accountId: AccountId, - bankId: BankId, - viewId : ViewId - ) - } - } - - resourceDocs += ResourceDoc( - getTransactionByIdForBankAccount, - apiVersion, - "getTransactionByIdForBankAccount", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/transaction", - "Get Transaction by Id", - s"""Returns one transaction specified by TRANSACTION_ID of the account ACCOUNT_ID and [moderated](#1_2_1-getViewsForBankAccount) by the view (VIEW_ID). - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public. - | - | - |""", - EmptyBody, - transactionJSON, - List(BankAccountNotFound, UnknownError), - List(apiTagTransaction, apiTagPsd2, apiTagOldStyle)) - - lazy val getTransactionByIdForBankAccount : OBPEndpoint = { - //get transaction by id - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "transaction" :: Nil JsonGet req => { - cc => - for { - (account, callContext) <- BankAccountX(bankId, accountId, Some(cc)) ?~! BankAccountNotFound - view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), cc.user, None) - (moderatedTransaction, callContext) <- account.moderatedTransaction(transactionId, view, BankIdAccountId(bankId,accountId), cc.user, Some(cc)) - } yield { - val json = JSONFactory.createTransactionJSON(moderatedTransaction) - successJsonResponse(Extraction.decompose(json)) - } - } - } - - resourceDocs += ResourceDoc( - getTransactionNarrative, - apiVersion, - "getTransactionNarrative", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", - "Get a Transaction Narrative", - """Returns the account owner description of the transaction [moderated](#1_2_1-getViewsForBankAccount) by the view. - | - |Authentication via OAuth is required if the view is not public.""", - EmptyBody, - transactionNarrativeJSON, - List( - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val getTransactionNarrative : OBPEndpoint = { - //get narrative - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - narrative <- Future(metadata.ownerComment) map { - unboxFullOrFail(_, cc.callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - } yield { - val narrativeJson = JSONFactory.createTransactionNarrativeJSON(narrative) - (narrativeJson, HttpCode.`200`(cc.callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addTransactionNarrative, - apiVersion, - "addTransactionNarrative", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", - "Add a Transaction Narrative", - s"""Creates a description of the transaction TRANSACTION_ID. - | - |Note: Unlike other items of metadata, there is only one "narrative" per transaction accross all views. - |If you set narrative via a view e.g. view-x it will be seen via view-y (as long as view-y has permission to see the narrative). - | - |${userAuthenticationMessage(false)} - |Authentication is required if the view is not public. - |""", - transactionNarrativeJSON, - successMessage, - List( - InvalidJsonFormat, - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val addTransactionNarrative : OBPEndpoint = { - //add narrative - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - narrativeJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[TransactionNarrativeJSON] } - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - addNarrative <- Future(metadata.addOwnerComment) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_owner_comment. Current ViewId($viewId)") - } - } yield { - addNarrative(narrativeJson.narrative) - val successJson = SuccessMessage("narrative added") - (successJson, HttpCode.`201`(cc.callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateTransactionNarrative, - apiVersion, - "updateTransactionNarrative", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", - "Update a Transaction Narrative", - """Updates the description of the transaction TRANSACTION_ID. - | - |Authentication via OAuth is required if the view is not public.""", - transactionNarrativeJSON, - successMessage, - List(InvalidJsonFormat, - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val updateTransactionNarrative : OBPEndpoint = { - //update narrative - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - narrativeJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[TransactionNarrativeJSON] } - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - addNarrative <- Future(metadata.addOwnerComment) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_owner_comment. Current ViewId($viewId)") - } - } yield { - addNarrative(narrativeJson.narrative) - val successJson = SuccessMessage("narrative updated") - (successJson, HttpCode.`200`(cc.callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteTransactionNarrative, - apiVersion, - "deleteTransactionNarrative", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", - "Delete a Transaction Narrative", - """Deletes the description of the transaction TRANSACTION_ID. - | - |Authentication via OAuth is required if the view is not public.""", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - NoViewPermission, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val deleteTransactionNarrative : OBPEndpoint = { - //delete narrative - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - addNarrative <- Future(metadata.addOwnerComment) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - } yield { - addNarrative("") - val successJson = SuccessMessage("") - (successJson, HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getCommentsForViewOnTransaction, - apiVersion, - "getCommentsForViewOnTransaction", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/comments", - "Get Transaction Comments", - """Returns the transaction TRANSACTION_ID comments made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). - | - |Authentication via OAuth is required if the view is not public.""", - EmptyBody, - transactionCommentsJSON, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val getCommentsForViewOnTransaction : OBPEndpoint = { - //get comments - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "comments" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - comments <- Future(metadata.comments) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - } yield { - val commentsJson = JSONFactory.createTransactionCommentsJSON(comments) - (commentsJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addCommentForViewOnTransaction, - apiVersion, - "addCommentForViewOnTransaction", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/comments", - "Add a Transaction Comment", - """Posts a comment about a transaction TRANSACTION_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID. - | - |${authenticationRequiredMessage(false)} - | - |Authentication is required since the comment is linked with the user.""", - postTransactionCommentJSON, - transactionCommentJSON, - List( - AuthenticatedUserIsRequired, - InvalidJsonFormat, - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val addCommentForViewOnTransaction : OBPEndpoint = { - //add comment - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "comments" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - commentJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionCommentJSON] } - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - addCommentFunc <- Future(metadata.addComment) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - postedComment <- Future(addCommentFunc(user.userPrimaryKey, viewId, commentJson.value, now)) map { - unboxFullOrFail(_, callContext, s"Cannot add the comment ${commentJson.value}") - } - } yield { - val successJson = JSONFactory.createTransactionCommentJSON(postedComment) - (successJson, HttpCode.`201`(callContext)) - } - } - } - - // Not able to update a comment (delete and add another) - - resourceDocs += ResourceDoc( - deleteCommentForViewOnTransaction, - apiVersion, - "deleteCommentForViewOnTransaction", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/comments/COMMENT_ID", - "Delete a Transaction Comment", - """Delete the comment COMMENT_ID about the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). - | - |Authentication via OAuth is required. The user must either have owner privileges for this account, or must be the user that posted the comment.""", - EmptyBody, - EmptyBody, - List( - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - AuthenticatedUserIsRequired, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val deleteCommentForViewOnTransaction : OBPEndpoint = { - //delete comment - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "comments":: commentId :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(user), callContext) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - delete <- Future(metadata.deleteComment(commentId, Full(user), account, view, callContext)) map { - unboxFullOrFail(_, callContext, "") - } - } yield { - val successJson = SuccessMessage("") - (successJson, HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getTagsForViewOnTransaction, - apiVersion, - "getTagsForViewOnTransaction", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/tags", - "Get Transaction Tags", - """Returns the transaction TRANSACTION_ID tags made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). - Authentication via OAuth is required if the view is not public.""", - EmptyBody, - transactionTagJSON, - List( - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError - ), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val getTagsForViewOnTransaction : OBPEndpoint = { - //get tags - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "tags" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - tags <- Future(metadata.tags) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - } yield { - val tagsJson = JSONFactory.createTransactionTagsJSON(tags) - (tagsJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addTagForViewOnTransaction, - apiVersion, - "addTagForViewOnTransaction", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/tags", - "Add a Transaction Tag", - s"""Posts a tag about a transaction TRANSACTION_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID. - | - |${userAuthenticationMessage(true)} - | - |Authentication is required as the tag is linked with the user.""", - postTransactionTagJSON, - transactionTagJSON, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val addTagForViewOnTransaction : OBPEndpoint = { - //add a tag - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "tags" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - tagJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionTagJSON] } - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - addTagFunc <- Future(metadata.addTag) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - postedTag <- Future(addTagFunc(user.userPrimaryKey, viewId, tagJson.value, now)) map { - unboxFullOrFail(_, callContext, s"Cannot add the tag ${tagJson.value}") - } - } yield { - val successJson = JSONFactory.createTransactionTagJSON(postedTag) - (successJson, HttpCode.`201`(callContext)) - } - } - } - - // No update tag (delete and add another) - - resourceDocs += ResourceDoc( - deleteTagForViewOnTransaction, - apiVersion, - "deleteTagForViewOnTransaction", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/tags/TAG_ID", - "Delete a Transaction Tag", - """Deletes the tag TAG_ID about the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). - |Authentication via OAuth is required. The user must either have owner privileges for this account, - |or must be the user that posted the tag. - |""".stripMargin, - EmptyBody, - EmptyBody, - List(NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val deleteTagForViewOnTransaction : OBPEndpoint = { - //delete a tag - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "tags" :: tagId :: Nil JsonDelete _ => { - - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(user), callContext) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - (bankAccount, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - delete <- Future(metadata.deleteTag(tagId, Full(user), bankAccount, view, callContext)) map { - unboxFullOrFail(_, callContext, "") - } - } yield { - val successJson = SuccessMessage("") - (successJson, HttpCode.`204`(cc.callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getImagesForViewOnTransaction, - apiVersion, - "getImagesForViewOnTransaction", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/images", - "Get Transaction Images", - """Returns the transaction TRANSACTION_ID images made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). - Authentication via OAuth is required if the view is not public.""", - EmptyBody, - transactionImagesJSON, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val getImagesForViewOnTransaction : OBPEndpoint = { - //get images - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "images" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - images <- Future(metadata.images) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - } yield { - val imagesJson = JSONFactory.createTransactionImagesJSON(images) - (imagesJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addImageForViewOnTransaction, - apiVersion, - "addImageForViewOnTransaction", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/images", - "Add a Transaction Image", - s"""Posts an image about a transaction TRANSACTION_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID. - | - |${userAuthenticationMessage(true) } - | - |The image is linked with the user.""", - postTransactionImageJSON, - transactionImageJSON, - List( - InvalidJsonFormat, - BankAccountNotFound, - NoViewPermission, - ViewNotFound, - InvalidUrl, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction) - ) - - lazy val addImageForViewOnTransaction : OBPEndpoint = { - //add an image - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "images" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - imageJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionImageJSON] } - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(u), callContext) - addImageFunc <- Future(metadata.addImage) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - url <- NewStyle.function.tryons(s"$InvalidUrl Could not parse url string as a valid URL", 400, callContext) { new URL(imageJson.URL) } - postedImage <- Future(addImageFunc(u.userPrimaryKey, viewId, imageJson.label, now, url.toString)) map { - unboxFullOrFail(_, callContext, s"Cannot add the tag ${imageJson.label}") - } - } yield { - val successJson = JSONFactory.createTransactionImageJSON(postedImage) - (successJson, HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteImageForViewOnTransaction, - apiVersion, - "deleteImageForViewOnTransaction", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/images/IMAGE_ID", - "Delete a Transaction Image", - """Deletes the image IMAGE_ID about the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). - | - |Authentication via OAuth is required. The user must either have owner privileges for this account, or must be the user that posted the image.""", - EmptyBody, - EmptyBody, - List( - BankAccountNotFound, - NoViewPermission, - AuthenticatedUserIsRequired, - "You must be able to see images in order to delete them", - "Image not found for this transaction", - "Deleting images not permitted for this view", - "Deleting images not permitted for the current user", - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val deleteImageForViewOnTransaction : OBPEndpoint = { - //delete an image - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "images" :: imageId :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(user), callContext) - (account, _) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - delete <- Future(metadata.deleteImage(imageId, Full(user), account, view, callContext)) map { - unboxFullOrFail(_, callContext, "") - } - } yield { - val successJson = SuccessMessage("") - (successJson, HttpCode.`204`(cc.callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getWhereTagForViewOnTransaction, - apiVersion, - "getWhereTagForViewOnTransaction", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", - "Get a Transaction where Tag", - """Returns the "where" Geo tag added to the transaction TRANSACTION_ID made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). - |It represents the location where the transaction has been initiated. - | - |Authentication via OAuth is required if the view is not public.""", - EmptyBody, - transactionWhereJSON, - List(BankAccountNotFound, - NoViewPermission, - ViewNotFound, - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val getWhereTagForViewOnTransaction : OBPEndpoint = { - //get where tag - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - where <- Future(metadata.whereTag) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") - } - } yield { - val json = JSONFactory.createLocationJSON(where) - val whereJson = TransactionWhereJSON(json) - (whereJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - addWhereTagForViewOnTransaction, - apiVersion, - "addWhereTagForViewOnTransaction", - "POST", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", - "Add a Transaction where Tag", - s"""Creates a "where" Geo tag on a transaction TRANSACTION_ID in a [view](#1_2_1-getViewsForBankAccount). - | - |${userAuthenticationMessage(true)} - | - |The geo tag is linked with the user.""", - postTransactionWhereJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - ViewNotFound, - NoViewPermission, - "Coordinates not possible", - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val addWhereTagForViewOnTransaction : OBPEndpoint = { - //add where tag - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonPost json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - addWhereTag <- Future(metadata.addWhereTag) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_where_tag. Current ViewId($viewId)") - } - whereJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionWhereJSON] } - correctCoordinates <- Future(checkIfLocationPossible(whereJson.where.latitude, whereJson.where.longitude)) map { - unboxFullOrFail(_, callContext, "Coordinates not possible") - } - if(addWhereTag(user.userPrimaryKey, viewId, now, whereJson.where.longitude, whereJson.where.latitude)) - } yield { - val successJson = SuccessMessage("where tag added") - (successJson, HttpCode.`201`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - updateWhereTagForViewOnTransaction, - apiVersion, - "updateWhereTagForViewOnTransaction", - "PUT", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", - "Update a Transaction where Tag", - s"""Updates the "where" Geo tag on a transaction TRANSACTION_ID in a [view](#1_2_1-getViewsForBankAccount). - | - |${userAuthenticationMessage(true)} - | - |The geo tag is linked with the user.""", - postTransactionWhereJSON, - successMessage, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - InvalidJsonFormat, - ViewNotFound, - NoViewPermission, - "Coordinates not possible", - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val updateWhereTagForViewOnTransaction : OBPEndpoint = { - //update where tag - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonPut json -> _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(user), callContext) <- authenticatedAccess(cc) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) - addWhereTag <- Future(metadata.addWhereTag) map { - unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_where_tag. Current ViewId($viewId)") - } - whereJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionWhereJSON] } - correctCoordinates <- Future(checkIfLocationPossible(whereJson.where.latitude, whereJson.where.longitude)) map { - unboxFullOrFail(_, callContext, "Coordinates not possible") - } - if(addWhereTag(user.userPrimaryKey, viewId, now, whereJson.where.longitude, whereJson.where.latitude)) - } yield { - val successJson = SuccessMessage("where tag updated") - (successJson, HttpCode.`200`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - deleteWhereTagForViewOnTransaction, - apiVersion, - "deleteWhereTagForViewOnTransaction", - "DELETE", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", - "Delete a Transaction Tag", - s"""Deletes the where tag of the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). - | - |${userAuthenticationMessage(true)} - | - |The user must either have owner privileges for this account, or must be the user that posted the geo tag.""", - EmptyBody, - EmptyBody, - List( - AuthenticatedUserIsRequired, - BankAccountNotFound, - NoViewPermission, - AuthenticatedUserIsRequired, - ViewNotFound, - "there is no tag to delete", - "Delete not completed", - UnknownError), - List(apiTagTransactionMetaData, apiTagTransaction)) - - lazy val deleteWhereTagForViewOnTransaction : OBPEndpoint = { - //delete where tag - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonDelete _ => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (user, callContext) <- authenticatedAccess(cc) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), user, callContext) - metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) - delete <- Future(metadata.deleteWhereTag(viewId, user, account, view, callContext)) map { - unboxFullOrFail(_, callContext, "Delete not completed") - } - } yield { - val successJson = SuccessMessage("") - (successJson, HttpCode.`204`(callContext)) - } - } - } - - resourceDocs += ResourceDoc( - getOtherAccountForTransaction, - apiVersion, - "getOtherAccountForTransaction", - "GET", - "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/other_account", - "Get Other Account of Transaction", - """Get other account of a transaction. - |Returns details of the other party involved in the transaction, moderated by the [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). - Authentication via OAuth is required if the view is not public.""", - EmptyBody, - otherAccountJSON, - List(BankAccountNotFound, UnknownError), - List(apiTagTransaction, apiTagCounterparty)) - - lazy val getOtherAccountForTransaction : OBPEndpoint = { - //get other account of a transaction - case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions":: TransactionId(transactionId) :: "other_account" :: Nil JsonGet req => { - cc => implicit val ec = EndpointContext(Some(cc)) - for { - (Full(u), callContext) <- authenticatedAccess(cc) - (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) - view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) - (moderatedTransaction, callContext) <- account.moderatedTransactionFuture(transactionId, view, Full(u), callContext) map { - unboxFullOrFail(_, callContext, GetTransactionsException) - } - _ <- NewStyle.function.tryons(GetTransactionsException, 400, callContext) { - moderatedTransaction.otherBankAccount.isDefined - } - } yield { - val otherBankAccountJson = JSONFactory.createOtherBankAccount(moderatedTransaction.otherBankAccount.get) - (otherBankAccountJson, HttpCode.`200`(callContext)) - } - - } - } - - } -} - -object APIMethods121 { +trait APIMethods121 { self: RestHelper => } +object APIMethods121 extends RestHelper with APIMethods121 { + val Implementations1_2_1 = Http4s121.Implementations1_2_1 } From 54912029ad9d0e049bf4d87d53d48c4729330260 Mon Sep 17 00:00:00 2001 From: Hongwei Date: Thu, 21 May 2026 02:41:41 +0200 Subject: [PATCH 08/10] fix(test): regenerate frozen_type_meta_data snapshot after http4s endpoint rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2.1.0 STABLE endpoints were renamed during the http4s migration: - addCardsForBank → addCardForBank - answerTransactionRequestChallenge → per-type variants (Free_form, Sepa, Sandbox_tan, Counterparty) FrozenClassTest was comparing the old Lift-era names against the current http4s names and failing both the "increased" and "reduced" scenarios. Run FrozenClassUtil in the test environment to capture the current state. --- .../src/test/resources/frozen_type_meta_data | Bin 136067 -> 135100 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/obp-api/src/test/resources/frozen_type_meta_data b/obp-api/src/test/resources/frozen_type_meta_data index c62cefe820ef708dea40a6ec08bb4ad89ab55e65..db767b90f4f8e1a29fd885343914f546865aaa9c 100644 GIT binary patch delta 8298 zcmai3d0doL_vbvou*$wK0y5yPsD%rnpryGBsHGw}!dNKGAPg#s8k);%=62PinF_6H zX3}J1u2^ZVETw6=fT?9^E^n5&|GxK`q1V@XKfiyTXP bI-YF`JOX#K5*W>!Fk)O zM0TQ-nmOhd7T7&2Jo|=4_}%?#$5fMD zlLGx@<3xRLqoGi5Fv$fmCOf~E^`@Z(#_XajQ*UE#u0G3@V>HOQSmEUnLuuxC4=qt^ zG1_yx=ZL2c9N`tE%~wzFKE=V#&aS=5&IRPsvW)q9b-1I+E~qF!Tio&q6tlc;P&Z-p zo=xH6-`*3U=M0}8DOx1^hLKie_&%p;A=$PR8-0zqm>@qWL-g<)=-*Kee<~mT@-baL zdWj8wof40m?0m8c^g0t{`j1xSyjDISvKNliyQrW5^7fgUiiL7KO+LO8p8hStr>no@ zlj*`uE{P0WW}=BKyfqF zf%43Mg!UrZW$qGgAk7|0yqkGT)44?Z%pD^`NgPsQ&BLPJCrvLo7rH#UJAEk;!7~0?|hK(YSXn)zRJ3};>B@qV!k@TNI_gWh608AEf101-QTHJ zz3l)lt)Zo6uf%Ev%<6ky1(#z0;@t_wmQak8p?EQT30rGY=**WJIzzE@EP`MH$QYs?E)}c|PQl^;-attq9ca)Ckf)zVQR8lDKK10D`#fwIDODtbI zOx_~lr8+jY7)@P zXw22?484rm#nN9D={C^Tos14RVav=iY&()U6SuHuH3f zDLX>>+FEKNJhQbnfn4Q{#L{}9%RUN~x78n(_IBsxv$)Ngkrc&e&XL>loG1)7%ei2a zksq%iZ{Btor%5dH)Tq*ha#S7kUo>Gnu0s78d+mAAZDL1=nK#h{ay{b_mMAv~q^e@eAz`Aqu`buUo3$!qo{tE_SX!U|MWU~ctv9&(UJhNyjL1iqKyrU6i zi-M?uAHGB_xs#XTE0#>~5nf|lgx4EwAZ+3rXEd(Ts!K%E#r<%AR~C=9(Q*+L2~GK} z-59)A6ewJl%mK$Ymh{A~<4f*X)y7MAlRHA7kGQ|ISlO?J%xf1W4K_UE$ zFXGtft#R11XlqBA!uD-@xzUT0DpK5F&}r0sYPV-qU72>YF_aP-JIxV%9- z+hB0o&WX;_kc$fS1-#EoiQz&g_(t@urkEVLx0T4<6$RppcV#))1ajnC%^-zmyYVk48}?iHQfE0im)3UNS{i9LkVt@;WjK z&*X=`V&;*NAb0x6>)5zvD9wA?NUbqwLJID1=&=@9T6`=QDhW%uE9#Dy;`((}qcOUt zD$QoR+-4S_20V!G4@2}!twszo=Tyf^RV}T#ikB$)W=G@I55AZ#wtYJm6ueIi#E~*i zj731N80X71PUIlIJ0XMJeoL_MKPj2_I5`Gn-a45nJ>$W53$bJVDWeP0noG7Zt0+%w zD-RGK*J(tR&Qr8H-4BaRrycEKUA0H3qu6q0KK7MWb`yrP37Fe_c7Zj6w-RH{OGtC@ z`~(Qvp>CWcsmXdppEZ%||3J{6S?4Ay>sn*UwK_eFK@ImyjK)v)$!Bf2~NlOp)B~4|%4Ic2Q?o-k?nud;|5m#)E_ok|I;Qsk0nKjO+SB*b9$QnMc2h{T<4-_ z#J{eDLscJK8Hi0e)!&Q9C4u77FWvDK_3IbN7MFg_!j>1V&LZvd%YNeQ)wo9Ih`m<& zl(<}d8~1wtT3fJl|LrkmE7y}h+usE|AAP+Y=q$V*4`KITU*M)j44n`z?}wkll+>)Odc=@Nov79l+L^r6IMZ6}ecV^o z;K~q+rqGo=D91*`QS2`ZUimdi1|Es2{5er`1cVC&BT(aNDhL%SGysOp`|Jr}N5Y&4 z?&3hJY{8M;9VrGv915kbV&)|`u_@o3XFF0D)~38oeq2>UF8okSukeNd(yA6!BK8>r zIa@;^pbr=l4ZZL?PL%bur50j*t}_*a7GQgjxM2tsa8ADRBPH-Y7wTve#9c-0!Ygqo zpLV6apvrEPCBx2rcUlR^xU7jPQcV+@=3`A~fE8KBY!w9u3Eib|;KwFn=razy(1QYy zd&}jkgm-w*LI~g6lXN)Cd!CdI;))lIkRbygh9`N`X)NgAM&Vo^fVc8eUJIsTYOstCA%7W@>VFUC zHKEkbdQDmXR00^*hwzJG5UbX*HH-|vhnDaN+z*I#iKO}1Ss6(g;2#l1GoY7sQ6vi) z33@p{n`E+;sF%NJ1~yum6q4N#t(>#0bvfT+^5vn?)C&YfG!4fZHD!+Nr(qW@bq0fE zEv*O1|1z3;7-)z=14Dws{v3zOh(#<#O4_Iy3QZ=v2$9mypTCWzK3E&loYvq4n`*y& zaH1u$1#DNvg<0raAe)+u*0}ISOR9i~JzG(}6m?r0%5lNfgv8T29B@ZGjl(EhXth+| zwRfBHH(dyICHL$~33yHKN-x?>4*+yPg2k^JjeKc^yI*j!WAQSJUr6I;i2=9_8sj!&q~xMiHR z)|p&B7GUqtFp2jmO(wqJf|R$Sg~ovICLSh&Jw!gz=8j0(eLOwdPal^c=XV z%CYdnj9`>lfh=1$!wTUdw5=VdfqZ> zJjFX>=`sUt1g|r%Q80(!Cm+@u3DAO<8R6+#er!~g_FO&2)pJa{Q znD|8f#@G3qNpu#}KQ5r-P~nV1+5ybL@kOM^>#ZU(fG6trRItdHOa)j|JDId-?(m;e zDf$WZa=r($$Zt&<*(-=7TcC5&!e`WV4Nr8x#gAl)ZX1@;e7sQ3gi0Q z$dC&@Kp%$kGqd_l9d-?Lx6{;^H zLCdfiP-9hT; zT0-B*lJFMvjn5V9C|85P@mHJI_2rnP|H#?qo_7J@!$&b;MEl>mm?K_B^Xx;(nRRNP)`4Z zPJx%&9vW_@mY%>5nnKhA)@Gh+BwTK$P)&mxbomQ2a|enzossGOXmpCW2azC73sb06B{TuBxLf7QZ=^F9kD;`c)f zK!%p5>}bS=3vlTw2mp}mYBO*2^n&>M=hWQlEH~Z_;to6M8Qj76osK^F|??Ug4r%VrC6sSIulqh`vxw3Y{900t{kYfzAL8 zNofSI29|lSc@K2#%9r=hsQ)syQG4l2pr)q#sJ*;XRnNvsgl9GFw&g38NCT>fsKnOrPU83Ai&j}mEnj|#@CzE~TTj6RJffZK$MCfSh(0CU?I88X?A(L&Iw*O6 zO~p^P3P1cB=L_X?UpJ;+6xH5;g$VzDf^W7CZfavt(Hxe*f#VKSPrQJ%(3+9hAwafg z-^Y+RqM{GAEUsJU#@&xf=r3;NhV$q>u!TiODb!}RPU`5?is>xHjZqiMt z^pGElPU(-hO6iYi7JR0-AP_hg%D-LMZ6w8W{! zdoMkK?BXgfE{Ic4BA%(?EQmik35+h`dV5(tptNtsola3RS8L1Pxv?|Crc-no`#=1N z+M=Q4CZ?bD<}p`LzHB*7P5uGUsC7eLoi{I;OJ0qE)$@B=j`K0Zxq7S~SAm#ceMyCG=-G|N)PT#dPpi68 zf&3r+1k(=XfkMu$W(j3nN-#gVLCN?Hi<9_!%T4LomWG?u0ioXtto!{=e&CexI|J%jZ4@I~?tdF6bLCBVHF^m*c1AwHJX91eTRvR*2b{^_Pi(5Sboi6r zlVY8^LneG8^1UEcyYepe!?Eh_s?L#ek3IqAMi_>!DUY~M*|rmkguA}{+kKk)L@TJa z0j+q+%j**yP&|N_sJbqO$tM;@@bHI}{kK%!*u<9|hN`~pMcJcgdC`~Dnd=|Xy(jKl zv$Ct=#+rWQ;RzpiHzAxB>eRnet%(aU6)RBeuAHTeh7>9uKre%XNl8>`hwv*GX%O!v z{XO^JmJDYPf~^92R(uM)UJ2iWIu^(HC$z{$TID;y|M}lG&(53 z^grB^EsjdK6OL>@JawS(-XA6^OC9)OI=P5x)7^cQzgH)!$tGzOiFtE1iVh5_G|C$i zUhe;r;&_pZ0;dz19YPvASkV%&yJQs=nv8kqmrnZ3TH-qKTV6^4_i$BY%Nr3@4d3s% z;?MS4OQoywk#ri_wB|BT#Z5S$_ZAP&yK|+x;s~Xn^&P>N-IX7~_fQjM!V|XO!x>FJ> zmKZx4TkL|bnivZhgC((i&$+wUlK1;_@7{aQnKLuznP+Cs?p|h{zsh=3E|E&)Q4O06 zi-{ICS(z5i#gZ;n#X)L7)kHb{=8aw9F21x@56i8z@Ru-XgNfr{Zvx za>p@Qa;k-LRjWjWrPfNmXkhTN%2c`NEga1PD(BDAlu#{^W?e`Fw%F7sYGP<$>q*p1 zbhLXyZA7SjFolU^dmnXMDaJ=kx3A{kQE%b$S)#r}Ttbhu&ysX~^l|!ZWx>vJ%*W!8 z{c7qibPo4CBlQ*znTey)k`p_o>9P`adO4t`NOP=;MQ1qHrYOT^$67>n#RaFWPJKU6 zexb8T`3+*Xb2Vygxa4e4)Kc7WnGA0vxh9jJIPZFsv|_tkHL4-byLD0r$_45OfA=&v zvcTOm|B~43-ovA@{Io@0Jme)uUc!Z|N7Jz5dJEV1%)~f7w9MA&6EoA}GWE*$8gdYf zaE7@ZvokYc!N+5IW1xH=B`@d1WRJR7Yn_K_tvjOFW3^_p-l96D2xqUVhWVZyh^~n% zUY#i35a2zLC|E4>xkm=W4Bu^}8L7AMl|%jOc!@|aOG-8*RKtWFhE;w#Qty&$v@}%p zpGvgHup*!;Dck8~DABGab-4WMD`wSfL;JQBM)s&r6Kz<*1e$O~qnI@M$VGOb@BAq6)FC>6dtD*DOYb%~;-I1g!<4=skaNh1%D*VjwDc<9Jq942>bDjscVVPWAZHlOt| zY&=LLUZ#2(!rL}dVO3qbdsr^I{S?T)(Z0WpR&QY)FOkK;rQ{{{wXhTc9W)}gLkC-Y zQpf4CMki*9qCuXVeVAMwyJe;6`Zo^_HrZgf*}oMXY`zlA)1H*(9Y#IZ+_Jodd!O0j_F-` z9U>PEG)&J-OHVW*O64K;r@M=#Gu7;Sne0S|sH&u8muK)oR#Xd2S{s!~P$24rp9t;K z(!8RBNFP_ju&|GoTr2bzmb$o92|$&EsLF#+|46Ncb-zG3wM0iX#f0&JhB5uz;bf_i zXt}h7xYED2Qw|)`N1vIb`%IZ8oCdTqi&sk#USh_72Z}udx|6rC8942&IgZ@m8*&jx z2i}08YX)^UPjVKsd$@^B#jyrmG{B-&9>))-5+8`cMI42g+QYfXAhjS0cx#+c>!I4~Aii= z|9J4e`(!JQpLenC)~8p58KfD*XJW0_!vR8e`iVR_U@J8gMe*I?ZkP3;qH{t$$V^X& zGOK6{KL^qxQI>EVTd^zgsKngV5m%u}Y^qk|CpEzHrle9u;W}K#_w(%36?Id*M1$ zg-`g(;avoKh>H`XYaZ?Pfva4&@nop-)kJ%kx?ti=Xk2F!__9Jgn>~d0c7=^1s~`WPjPgbBQSGuT2F`y{Bi;I#ISGr=U_R0&>wj!eP%S~ z9-nzdtx-Zytee#pt38=D7_Zl@^5)hqEh(skst1#vI%z&+lvRYZ55*n)!wE>X3Z&p9@Ry<477r;Gw?ujZ%Exr=QWTHa-3fT zEsEz$zqDP@3fIvKQt;;1f?c>SUpO3_==28?X27Bdd`w%^A2@n#t@7tK!vQAC#j8yr z!Kd=5wz#gd_RUhrGNhS8mMXBRO?-BiJ}nh|x;e~E1myeMSB@B}M^wwLr@%{tkCQdE8jdxp@&w?49R%BRLrT|fP-jmyD$w8E?XpV25D<_zvUZj`X z2*b+dCJV)^ZyLa1yS_OE$ISRoswD*YNYU=X`P&ijXwJ90h#H8WcWGTBGt&~X+?M;l7koFgo=_4_aI zK5QLwa%O3!$t&FuXWtedYKJ7BL5`_t#HB7Zy*VOcsr1&Jo{QgZt%vn>( z&T5XhO@E8W#(EIroCgGjZEpYpBey5p$)L;5f@MhwGKaJO0J7l;_sEWQRxr|SM|BMB zy1SkjvO^24Chmy0G!vo~mj)nWUhjF15syB06ZS>*F``w`I5LlLmlDOsgQLab)IdY} zet(&`3lBQWG``}eVes{wBhfI2lHG*v$RLP0a%2Wz@MQ#j{$aF9w(Kk#9Sg;%q+==Y z-rA_=;?(gxCH)S@+w~{Kl+(!grW|wH zhPrTrv(!#})4REC*WoBa4Hme6rai8W&JKm3ug=Dh#G=*& zbJcl029G{31NztVvWiN$U{!^X?T?{2UwUaO-WTo-6~ivKHv7g-Jcp1^Z{7zEhQT<{*EtHV$ZJ# zFwo}##PYe{;$cjyyOVG&zv(Vc+znPDXW<9NiG#nlg8Uc1zcx{}hoJjoFlX%j78t+z z{xmy{Xv!ybcOWQ8`sQ2ozl5<7h=&~RzQq$ePE;q-JlwA}P`kz#}?{Q1Facw(QH z)LgQOG`!4<)TTN^D>gi9hgoIMmSNq3=Y8?}*7L{aWo^XIS^Y%Qzkh%;%_w&j;V+s} zvC*zMITLRfNA<;qmtD-R+tuEMC*_ls2zcdyJatD-;*CV$A0+@J-ExqM=9x3fa}@=FG`IWEM?!bgjz6t}=VETZoZR`v zSjyl6cdDg;C5OW-3B{igMNmz6hJ_Wye~7#+yw6rs7DOmytQ6dBONX#tL#bx9?aefC zn2%V~UW{yfomz7r9c&9P4dYYSskc~II+%a7C0RA!v!%I6*LijXyLg`+jdeBUT@*F( zX$eZLjf6DQPeg8U5IqOla;`nRSi!UH$rBS-+tYOTps54JVg6hP8Uh>saG?H@8Ia{T z&WR+rwKn9(r`@rexmGF-Cpc4Qyj|-|BQb7zNT948EJ*XJJ0X$RY;v1Go zvd6}2MePs|{{AsScI0zMZskSxc1qGW(G^$oqJdZ<+lxMhRad(fj;l3IuM!`j9{lrF7aUXPM&u(h_$XbJRO-He9g zErM~rLi%qC5Dgz_L8xW9aZ75ATiF)WY!7E>xS%C9HEV4r`_I-!%T^Q(fEi;xqR;IC zAQYcQ1cO?Jqg5A5#x0`@Wn;BpyAW7~^FN_gpqrncYI)Xo__27X9T(k4LW{Yt=CrQl zF0*H-th4K4XE*Jr#+Kcvi+MYgs7~%iUz>L$v^zD$3cBtz5i30CP8oQL=|Qr^3F+n~ zw*S=D=-!ivl)Z|JkC!JaV#Q$}F6#+hq9TBq|35Fga&|AO0jcwQLFyZ**|0~Xg7@%9 z?6vIfI`A)%R0q-|ABY=|=ZIlBEx9C$zHvp__@*r}cgwSfQBB_7oBS0bbCW4ui@6Sc z$Oyd-^`W)!DFP>eDjU-McRhJsKdOz-r;d^r-|a`amZ5r!hFrRoYMTxfnwbt2R9ar% zpL$>{YB(LlMW&*fT!sqH^Xm5jj@ z3Zd%;Q!cb?ID`UKmI%fGSu6PQ-=oM;ZSHWuQnFBy`^r0pk?+5B%kltX))6~y_nd6m zA%>VyH!bky@7o+{K)FSrP7w->>|%hKs29#b=DJL(h;%%Vix zzRDsU0w5%&jwmqNiL%#fPJcqq@6lg`o-#3Wzn*Hz=I_oZs`-wOIo2NOtKDd-1{H^n zrhE)79Zlb(z~-4_5tt_0F(SdC_V#A0@qj}GPaH49AAM$!X@`1E02#_AJDk@{pdyK? z`l8^7KhKy5*U9s)WVW6J9xmp%NrZmf7?KN5;Bjaktv4gM`eY>(drwxDfWLfrw}IMl zK)ymDL-L`HmW}z~ahbc_IAjVngov0aGGQ18PNl~7W~}qf+0^0vW?r6GartaQPsI<% z0{&rhz@L&Mb!j@*o`D;3=TM#Z8I{k^q1l+wD;ErWNmEp5vBKE6iKCg!1IPYRf3m3I4G*lODpTKJRyj4ocQvw@lfsl4TT& zNytsD(7(%+|25`1t;7)niX;&c=M`Y?KHtg7rn5xZl0s+`;gTO{_fCt-S_5qCx{{Fa zjWH`}j7&Ti|3f$@(DL^06pL|?lZdB&tCTp{wTdbaqwF~S52|a7UyWfHuy75H!fcnd zbU>p2+&cOVk9*e3x(qpZ1Jak4>z4y+vYru*X1ejHjiAV4N=r@ zQD?=ENHm>UD(9bEbu(2}SIA76!)-Pr^=o(u&4=8_E_p5O0tIn={>} zYCfG)ux8U+n0}3@QcQ>FQsE}Nu#6}K& zxA=i_@MY5vZwgm=I+$rrZzs1>o64AQ+6E*7%iF*#sKK{U6wG|Ijfx~@fzQwW0k4ib z5TqJT+o6!^t{w1}hO6(S==boHzmv{Vg>k?x5Ubf?t9N6@+xo|gwR>oUS*0KM0MFiB zv4_TD2+F*2s1a90YRNex_S0y*E!j_V9N(U&jL}=P5^p^OSH=aMfmuAs?yNKY~4#Il8y&ECfe3(daW}H;%qWwp3xZ3X!xnY5% zLyEiB90J4?Q+DI!iJxR80^(~bPvT`0kr(F2I}a=Mcj;l2y@2QuYJ%InBMR4Oj}n?1 z9(9!Nz{P|HSh-k%(P008=jbAg67WCNE`S&A=R5_{0xp#C<<;@ zih9|2@WV5-9NSQEma53uzjc!u%5$zJ|5AA<4aCrEN~h&)Is>cV>i2=jn}3lj|6os5 zdDeLp52mV539NbZA=K&ul7BI`yMU}`YOj}HAWMmgnO?m60#yf^uUsJXXguy0>?$zw z3(didX&31xZpoL>i)mSP8SRah+h2w!i}~Bj^aI#d9yDcLLCAUY^(&Nw51(A6TX09i zYqYKMh!f2Rzr3b&W@w}aNZ12+zP$D&^)x=bK`NX$@S_riV9bY%YIZC|1=7Ei8k+aS zmSeBd*P<+>Dev|}%@cDIEsEl?-ZD9K7IeM2DEG6Lc=K0P7H;wnOFjOy7@n<9jM3+$ zzwO1i=)b5AHC*wG+VT9^=975NeN8sp<(2~V=vy>esb)qcC5{GT*5JlAh}E7Skv+e< zrPvdEo7zc6%ebSoA*b)qkFaI#uW)0r(djob;3%07{!T;TW9>aej)s9=WTbmY65ewA zqH)W)uaw)j@5|^lhCHAUQ16@5AY0BaBR5NgWm}PPCWs>@B3Le#5eiR9p#$D&IJ8Q` zv9cTyq~V+8icakxp@dORZ&6hkNB%+IN`;;OBt3wbG2GXPL+nO!2Z}4GE0pnmqQuDb zC$t4ZKzUIZUhtF>Dpe{OjDJcRJay&3XQ&voyzCiDI>nJNTK>6^|BqaY0KyTJpt+5? zu!vIF=Wo1G_S}y{UXTx@bbq1rE!$tvU^A|8fH_>5{yydafhK*i)`4x($Vt)FH zzJXI0y{5o->MB{g;?SceRm^o!&BOV^YLyTDk6_|*QsEyYc2ud_{Es2ByyGb04i8ohqtS$*O-9Q7|8}QZ>YH=WFn-omv%) z-)+>YEHj0jRIBP^Tb`>`>p=j@Id^y*kbl)$RRiyF#Eu?F%Vet>Y1)nY%(ki!ygF(t zg>aaiD)ryAr)NRDRF4Y%p`FUx97Ad@_?j|#lD#Se!XDYH Date: Thu, 21 May 2026 13:44:36 +0200 Subject: [PATCH 09/10] refactor/revert the code and comment them --- .../scala/code/api/v2_2_0/APIMethods220.scala | 1361 +++++++++++++++++ 1 file changed, 1361 insertions(+) diff --git a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala index 6572cf49f1..f8f9514b56 100644 --- a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala +++ b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala @@ -7,3 +7,1364 @@ trait APIMethods220 { self: RestHelper => } object APIMethods220 extends RestHelper with APIMethods220 { val Implementations2_2_0 = Http4s220.Implementations2_2_0 } + +//package code.api.v2_2_0 +// +//import scala.language.reflectiveCalls +//import code.api.Constant._ +//import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ +//import code.api.util.APIUtil._ +//import code.api.util.ApiRole._ +//import code.api.util.ApiTag._ +//import code.api.util.ErrorMessages.{BankAccountNotFound, _} +//import code.api.util.FutureUtil.EndpointContext +//import code.api.util.NewStyle.HttpCode +//import code.api.util._ +//import code.api.util.newstyle.ViewNewStyle +//import code.api.v1_2_1.{CreateViewJsonV121, JSONFactory, UpdateViewJsonV121} +//import code.api.v2_1_0._ +//import code.api.v2_2_0.JSONFactory220.transformV220ToBranch +//import code.api.v3_1_0.PostPutProductJsonV310 +//import code.api.v4_0_0.AtmJsonV400 +//import code.bankconnectors._ +//import code.consumer.Consumers +//import code.entitlement.Entitlement +//import code.metadata.counterparties.{Counterparties, MappedCounterparty} +//import code.metrics.ConnectorMetricsProvider +//import code.model._ +//import code.model.dataAccess.BankAccountCreation +//import code.util.Helper +//import code.util.Helper._ +//import code.views.Views +//import code.views.system.ViewPermission +//import com.openbankproject.commons.ExecutionContext.Implicits.global +//import com.openbankproject.commons.model._ +//import com.openbankproject.commons.util.ApiVersion +//import net.liftweb.common.Full +//import net.liftweb.http.rest.RestHelper +//import net.liftweb.json.Extraction +//import net.liftweb.util.Helpers.tryo +//import net.liftweb.util.StringHelpers +// +//import java.util.Date +//import scala.collection.immutable.{List, Nil} +//import scala.collection.mutable.ArrayBuffer +//import scala.concurrent.Future +// +// +// +//trait APIMethods220 { +// //needs to be a RestHelper to get access to JsonGet, JsonPost, etc. +// self: RestHelper => +// +// val Implementations2_2_0 = new Object() { +// +// val resourceDocs = ArrayBuffer[ResourceDoc]() +// val apiRelations = ArrayBuffer[ApiRelation]() +// +// +// val implementedInApiVersion = ApiVersion.v2_2_0 +// +// val codeContext = CodeContext(resourceDocs, apiRelations) +// +// +// resourceDocs += ResourceDoc( +// root, +// implementedInApiVersion, +// "root", +// "GET", +// "/root", +// "Get API Info (root)", +// """Returns information about: +// | +// |* API version +// |* Hosted by information +// |* Git Commit""", +// EmptyBody, +// apiInfoJSON, +// List(UnknownError, MandatoryPropertyIsNotSet), +// apiTagApi :: Nil) +// +// lazy val root : OBPEndpoint = { +// case (Nil | "root" :: Nil) JsonGet _ => { +// cc => +// implicit val ec = EndpointContext(Some(cc)) +// for { +// _ <- Future(()) // Just start async call +// } yield { +// (JSONFactory.getApiInfoJSON(OBPAPI2_2_0.version, OBPAPI2_2_0.versionStatus), HttpCode.`200`(cc.callContext)) +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// getViewsForBankAccount, +// implementedInApiVersion, +// "getViewsForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views", +// "Get Views for Account", +// s"""#Views +// | +// | +// |Views in Open Bank Project provide a mechanism for fine grained access control and delegation to Accounts and Transactions. Account holders use the 'owner' view by default. +// |Delegated access is made through other views for example 'accountants', 'share-holders' or 'tagging-application'. Views can be created via the API and each view has a list of entitlements. +// | +// |Views on accounts and transactions filter the underlying data to redact certain fields for certain users. For instance the balance on an account may be hidden from the public. The way to know what is possible on a view is determined in the following JSON. +// | +// |**Data:** When a view moderates a set of data, some fields my contain the value `null` rather than the original value. This indicates either that the user is not allowed to see the original data or the field is empty. +// | +// |There is currently one exception to this rule; the 'holder' field in the JSON contains always a value which is either an alias or the real name - indicated by the 'is_alias' field. +// | +// |**Action:** When a user performs an action like trying to post a comment (with POST API call), if he is not allowed, the body response will contain an error message. +// | +// |**Metadata:** +// |Transaction metadata (like images, tags, comments, etc.) will appears *ONLY* on the view where they have been created e.g. comments posted to the public view only appear on the public view. +// | +// |The other account metadata fields (like image_URL, more_info, etc.) are unique through all the views. Example, if a user edits the 'more_info' field in the 'team' view, then the view 'authorities' will show the new value (if it is allowed to do it). +// | +// |# All +// |*Optional* +// | +// |Returns the list of the views created for account ACCOUNT_ID at BANK_ID. +// | +// |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", +// EmptyBody, +// viewsJSONV220, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// UnknownError +// ), +// List(apiTagView, apiTagAccount)) +// +// lazy val getViewsForBankAccount : OBPEndpoint = { +// //get the available views on an bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonGet _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// permission <- NewStyle.function.permission(bankId, accountId, u, callContext) +// anyViewContainsCanSeeAvailableViewsForBankAccountPermission = permission.views.map(_.allowed_actions.exists(_ == CAN_SEE_AVAILABLE_VIEWS_FOR_BANK_ACCOUNT)).find(true == _).getOrElse(false) +// _ <- Helper.booleanToFuture( +// s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${CAN_SEE_AVAILABLE_VIEWS_FOR_BANK_ACCOUNT}` permission on any your views", +// cc= callContext +// ){ +// anyViewContainsCanSeeAvailableViewsForBankAccountPermission +// } +// views <- Future(Views.views.vend.availableViewsForAccount(BankIdAccountId(account.bankId, account.accountId))) +// } yield { +// val viewsJSON = JSONFactory220.createViewsJSON(views) +// (viewsJSON, HttpCode.`200`(callContext)) +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// createViewForBankAccount, +// implementedInApiVersion, +// "createViewForBankAccount", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views", +// "Create View", +// s"""#Create a view on bank account +// | +// | ${userAuthenticationMessage(true)} and the user needs to have access to the owner view. +// | The 'alias' field in the JSON can take one of three values: +// | +// | * _public_: to use the public alias if there is one specified for the other account. +// | * _private_: to use the private alias if there is one specified for the other account. +// | +// | * _''(empty string)_: to use no alias; the view shows the real name of the other account. +// | +// | The 'hide_metadata_if_alias_used' field in the JSON can take boolean values. If it is set to `true` and there is an alias on the other account then the other accounts' metadata (like more_info, url, image_url, open_corporates_url, etc.) will be hidden. Otherwise the metadata will be shown. +// | +// | The 'allowed_actions' field is a list containing the name of the actions allowed on this view, all the actions contained will be set to `true` on the view creation, the rest will be set to `false`. +// | +// | You should use a leading _ (underscore) for the view name because other view names may become reserved by OBP internally +// | """, +// createViewJsonV121, +// viewJSONV220, +// List( +// AuthenticatedUserIsRequired, +// InvalidJsonFormat, +// BankAccountNotFound, +// UnknownError +// ), +// List(apiTagAccount, apiTagView, apiTagOldStyle)) +// +// lazy val createViewForBankAccount : OBPEndpoint = { +// //creates a view on an bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonPost json -> _ => { +// cc => +// for { +// createViewJsonV121 <- tryo{json.extract[CreateViewJsonV121]} ?~!InvalidJsonFormat +// //customer views are started ith `_`,eg _life, _work, and System views startWith letter, eg: owner +// _<- booleanToBox(isValidCustomViewName(createViewJsonV121.name), InvalidCustomViewFormat+s"Current view_name (${createViewJsonV121.name})") +// u <- cc.user ?~!AuthenticatedUserIsRequired +// account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound +// createViewJson = CreateViewJson( +// createViewJsonV121.name, +// createViewJsonV121.description, +// metadata_view = "", //this only used from V300 +// createViewJsonV121.is_public, +// createViewJsonV121.which_alias_to_use, +// createViewJsonV121.hide_metadata_if_alias_used, +// createViewJsonV121.allowed_actions +// ) +// permission <- Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) +// anyViewContainsCanCreateCustomViewPermission = permission.views.map(_.allowed_actions.exists(_ ==CAN_CREATE_CUSTOM_VIEW)).find(_ == true).getOrElse(false) +// +// _ <- booleanToBox( +// anyViewContainsCanCreateCustomViewPermission, +// s"${ErrorMessages.CreateCustomViewError} You need the `${CAN_CREATE_CUSTOM_VIEW}` permission on any your views" +// ) +// view <- Views.views.vend.createCustomView(BankIdAccountId(bankId, accountId), createViewJson) ?~ CreateCustomViewError +// } yield { +// val viewJSON = JSONFactory220.createViewJSON(view) +// successJsonResponse(Extraction.decompose(viewJSON), 201) +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// updateViewForBankAccount, +// implementedInApiVersion, +// "updateViewForBankAccount", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID", +// "Update View", +// s"""Update an existing view on a bank account +// | +// |${userAuthenticationMessage(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)""", +// updateViewJsonV121, +// viewJSONV220, +// List( +// InvalidJsonFormat, +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// UnknownError +// ), +// List(apiTagAccount, apiTagView, apiTagOldStyle) +// ) +// +// lazy val updateViewForBankAccount : OBPEndpoint = { +// //updates a view on a bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: ViewId(viewId) :: Nil JsonPut json -> _ => { +// cc => +// for { +// updateJsonV121 <- tryo{json.extract[UpdateViewJsonV121]} ?~!InvalidJsonFormat +// //customer views are started ith `_`,eg _life, _work, and System views startWith letter, eg: owner +// _ <- booleanToBox(viewId.value.startsWith("_"), InvalidCustomViewFormat+s"Current view_name (${viewId.value})") +// view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), cc.user, Some(cc)) +// _ <- booleanToBox(!view.isSystem, SystemViewsCanNotBeModified) +// u <- cc.user ?~!AuthenticatedUserIsRequired +// account <- BankAccountX(bankId, accountId) ?~!BankAccountNotFound +// updateViewJson = UpdateViewJSON( +// description = updateJsonV121.description, +// metadata_view = view.metadataView, //this only used from V300, here just copy from currentView . +// is_public = updateJsonV121.is_public, +// which_alias_to_use = updateJsonV121.which_alias_to_use, +// hide_metadata_if_alias_used = updateJsonV121.hide_metadata_if_alias_used, +// allowed_actions = updateJsonV121.allowed_actions +// ) +// +// permission <- Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) +// anyViewContainsCancanUpdateCustomViewPermission = permission.views.map(_.allowed_actions.exists(_ == CAN_UPDATE_CUSTOM_VIEW)).find(true == _).getOrElse(false) +// +// _ <- booleanToBox( +// anyViewContainsCancanUpdateCustomViewPermission, +// s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_UPDATE_CUSTOM_VIEW)}` permission on any your views" +// ) +// updatedView <- Views.views.vend.updateCustomView(BankIdAccountId(bankId, accountId), viewId, updateViewJson) ?~ CreateCustomViewError +// } yield { +// val viewJSON = JSONFactory220.createViewJSON(updatedView) +// successJsonResponse(Extraction.decompose(viewJSON), 200) +// } +// } +// } +// +// // Not used yet. +// val getFxIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getFxIsPublic", false) +// +// +// resourceDocs += ResourceDoc( +// getCurrentFxRate, +// implementedInApiVersion, +// "getCurrentFxRate", +// "GET", +// "/banks/BANK_ID/fx/FROM_CURRENCY_CODE/TO_CURRENCY_CODE", +// "Get Current FxRate", +// """Get the latest FX rate specified by BANK_ID, FROM_CURRENCY_CODE and TO_CURRENCY_CODE +// | +// |OBP may try different sources of FX rate information depending on the Connector in operation. +// | +// |For example we want to convert EUR => USD: +// | +// |OBP will: +// |1st try - Connector (database, core banking system or external FX service) +// |2nd try part 1 - fallbackexchangerates/eur.json +// |2nd try part 2 - fallbackexchangerates/usd.json (the inverse rate is used) +// |3rd try - Hardcoded map of FX rates. +// | +// |![FX Flow](https://user-images.githubusercontent.com/485218/60005085-1eded600-966e-11e9-96fb-798b102d9ad0.png) +// | +// |**Public Access:** This endpoint can be made publicly accessible (no authentication required) by setting the property `apiOptions.getCurrentFxRateIsPublic=true` in the props file. +// | +// """.stripMargin, +// EmptyBody, +// fXRateJSON, +// List(InvalidISOCurrencyCode,AuthenticatedUserIsRequired,FXCurrencyCodeCombinationsNotSupported, UnknownError), +// List(apiTagFx)) +// +// val getCurrentFxRateIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getCurrentFxRateIsPublic", false) +// +// lazy val getCurrentFxRate: OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "fx" :: fromCurrencyCode :: toCurrencyCode :: Nil JsonGet _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (_, callContext) <- getCurrentFxRateIsPublic match { +// case false => authenticatedAccess(cc) +// case true => anonymousAccess(cc) +// } +// _ <- Helper.booleanToFuture(failMsg = ConsumerHasMissingRoles + CanReadFx, cc=callContext) { +// checkScope(bankId.value, getConsumerPrimaryKey(callContext), ApiRole.canReadFx) +// } +// fromCurrencyCodeUpperCase = fromCurrencyCode.toUpperCase +// toCurrencyCodeUpperCase = toCurrencyCode.toUpperCase +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// _ <- NewStyle.function.isValidCurrencyISOCode(fromCurrencyCodeUpperCase, callContext) +// _ <- NewStyle.function.isValidCurrencyISOCode(toCurrencyCodeUpperCase, callContext) +// fxRate <- NewStyle.function.getExchangeRate(bankId, fromCurrencyCodeUpperCase, toCurrencyCodeUpperCase, callContext) +// } yield { +// val viewJSON = JSONFactory220.createFXRateJSON(fxRate) +// (viewJSON, HttpCode.`200`(callContext)) +// } +// +// } +// } +// +// resourceDocs += ResourceDoc( +// getExplicitCounterpartiesForAccount, +// implementedInApiVersion, +// "getExplicitCounterpartiesForAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties", +// "Get Counterparties (Explicit)", +// s"""This endpoints gets the explicit Counterparties on an Account / View. +// | +// |For a general introduction to Counterparties in OBP, see ${Glossary.getGlossaryItemLink("Counterparties")} +// | +// |${userAuthenticationMessage(true)} +// |""".stripMargin, +// EmptyBody, +// counterpartiesJsonV220, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// ViewNotFound, +// NoViewPermission, +// UserNoPermissionAccessView, +// UnknownError +// ), +// List(apiTagCounterparty, apiTagPSD2PIS, apiTagAccount, apiTagPsd2)) +// +// lazy val getExplicitCounterpartiesForAccount : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "counterparties" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), Some(u), callContext) +// _ <- Helper.booleanToFuture( +// s"${ErrorMessages.NoViewPermission} You need the `${(CAN_GET_COUNTERPARTY)}` permission on the View(${viewId.value} )", +// cc = callContext +// ) { +// ViewPermission.findViewPermissions(view).exists(_.permission.get == CAN_GET_COUNTERPARTY) +// } +// (counterparties, callContext) <- NewStyle.function.getCounterparties(bankId,accountId,viewId, callContext) +// //Here we need create the metadata for all the explicit counterparties. maybe show them in json response. +// //Note: actually we need update all the counterparty metadata when they from adapter. Some counterparties may be the first time to api, there is no metadata. +// _ <- Helper.booleanToFuture(CreateOrUpdateCounterpartyMetadataError, 400, cc=callContext) { +// { +// for { +// counterparty <- counterparties +// } yield { +// Counterparties.counterparties.vend.getOrCreateMetadata(bankId, accountId, counterparty.counterpartyId, counterparty.name) match { +// case Full(_) => true +// case _ => false +// } +// } +// }.forall(_ == true) +// } +// } yield { +// val counterpartiesJson = JSONFactory220.createCounterpartiesJSON(counterparties) +// (counterpartiesJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// getExplicitCounterpartyById, +// implementedInApiVersion, +// "getExplicitCounterpartyById", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties/COUNTERPARTY_ID", +// "Get Counterparty by Counterparty Id (Explicit)", +// s"""Information returned about the Counterparty specified by COUNTERPARTY_ID: +// | +// |${userAuthenticationMessage(true)} +// |""".stripMargin, +// EmptyBody, +// counterpartyWithMetadataJson, +// List(AuthenticatedUserIsRequired, BankNotFound, UnknownError), +// List(apiTagCounterparty, apiTagPSD2PIS, apiTagCounterpartyMetaData, apiTagPsd2) +// ) +// +// lazy val getExplicitCounterpartyById : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "counterparties" :: CounterpartyId(counterpartyId) :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), Some(u), callContext) +// +// _ <- Helper.booleanToFuture( +// s"${ErrorMessages.NoViewPermission} You need the `${(CAN_GET_COUNTERPARTY)}` permission on the View(${viewId.value} )", +// cc = callContext +// ) { +// ViewPermission.findViewPermissions(view).exists(_.permission.get == CAN_GET_COUNTERPARTY) +// } +// +// counterpartyMetadata <- NewStyle.function.getMetadata(bankId, accountId, counterpartyId.value, callContext) +// (counterparty, callContext) <- NewStyle.function.getCounterpartyTrait(bankId, accountId, counterpartyId.value, callContext) +// } yield { +// val counterpartyJson = JSONFactory220.createCounterpartyWithMetadataJSON(counterparty,counterpartyMetadata) +// (counterpartyJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getMessageDocs, +// implementedInApiVersion, +// "getMessageDocs", +// "GET", +// "/message-docs/CONNECTOR", +// "Get Message Docs", +// """These message docs provide example messages sent by OBP to the (RabbitMq) message queue for processing by the Core Banking / Payment system Adapter - together with an example expected response and possible error codes. +// | Integrators can use these messages to build Adapters that provide core banking services to OBP. +// | +// | Note: API Explorer provides a Message Docs page where these messages are displayed. +// | +// | `CONNECTOR`: rest_vMar2019, stored_procedure_vDec2019 ... +// """.stripMargin, +// EmptyBody, +// messageDocsJson, +// List(InvalidConnector, UnknownError), +// List(apiTagMessageDoc, apiTagDocumentation, apiTagApi) +// ) +// +// lazy val getMessageDocs: OBPEndpoint = { +// case "message-docs" :: connector :: Nil JsonGet _ => { +// cc => { +// implicit val ec = EndpointContext(Some(cc)) +// for { +// connectorObject <- Future(tryo{Connector.getConnectorInstance(connector)}) map { i => +// val msg = s"$InvalidConnector Current Input is $connector. It should be eg: rest_vMar2019..." +// unboxFullOrFail(i, cc.callContext, msg) +// } +// } yield { +// val json = JSONFactory220.createMessageDocsJson(connectorObject.messageDocs.toList) +// (json, HttpCode.`200`(cc.callContext)) +// } +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// createBank, +// implementedInApiVersion, +// "createBank", +// "POST", +// "/banks", +// "Create Bank", +// s"""Create a new bank (Authenticated access). +// |${userAuthenticationMessage(true) } +// |""", +// bankJSONV220, +// bankJSONV220, +// List( +// InvalidJsonFormat, +// AuthenticatedUserIsRequired, +// InsufficientAuthorisationToCreateBank, +// UnknownError +// ), +// List(apiTagBank, apiTagOldStyle), +// Some(List(canCreateBank)) +// ) +// +// lazy val createBank: OBPEndpoint = { +// case "banks" :: Nil JsonPost json -> _ => { +// cc => +// for { +// bank <- tryo{ json.extract[BankJSONV220] } ?~! ErrorMessages.InvalidJsonFormat +// _ <- Helper.booleanToBox( +// bank.id.length > 5,s"$InvalidJsonFormat Min length of BANK_ID should be 5 characters.") +// +// checkShortStringValue = APIUtil.checkShortString(bank.id) +// +// _ <- Helper.booleanToBox(checkShortStringValue == SILENCE_IS_GOLDEN, s"$checkShortStringValue.") +// +// _ <- Helper.booleanToBox( +// !`checkIfContains::::` (bank.id), s"$InvalidJsonFormat BANK_ID can not contain `::::` characters") +// u <- cc.user ?~!ErrorMessages.AuthenticatedUserIsRequired +// consumer <- cc.consumer ?~! ErrorMessages.InvalidConsumerCredentials +// _ <- NewStyle.function.hasEntitlementAndScope("", u.userId, consumer.id.get.toString, canCreateBank, cc.callContext) +// success <- Connector.connector.vend.createOrUpdateBank( +// bank.id, +// bank.full_name, +// bank.short_name, +// bank.logo_url, +// bank.website_url, +// bank.swift_bic, +// bank.national_identifier, +// bank.bank_routing.scheme, +// bank.bank_routing.address, +// Some(cc) +// ) +// entitlements <- Entitlement.entitlement.vend.getEntitlementsByUserId(u.userId) +// +// entitlementsByBank = entitlements.filter(_.bankId==bank.id) +// _ <- entitlementsByBank.filter(_.roleName == CanCreateEntitlementAtOneBank.toString()).size > 0 match { +// case true => +// // Already has entitlement +// Full(()) +// case false => +// Full(Entitlement.entitlement.vend.addEntitlement(bank.id, u.userId, CanCreateEntitlementAtOneBank.toString())) +// } +// _ <- entitlementsByBank.filter(_.roleName == CanReadDynamicResourceDocsAtOneBank.toString()).size > 0 match { +// case true => +// // Already has entitlement +// Full(()) +// case false => +// Full(Entitlement.entitlement.vend.addEntitlement(bank.id, u.userId, CanReadDynamicResourceDocsAtOneBank.toString())) +// } +// } yield { +// val json = JSONFactory220.createBankJSON(success) +// createdJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// +// +// +// // Create Branch +// val createBranchEntitlementsRequiredForSpecificBank = CanCreateBranch :: Nil +// val createBranchEntitlementsRequiredForAnyBank = CanCreateBranchAtAnyBank :: Nil +// +// resourceDocs += ResourceDoc( +// createBranch, +// implementedInApiVersion, +// "createBranch", +// "POST", +// "/banks/BANK_ID/branches", +// "Create Branch", +// s"""Create Branch for the Bank. +// | +// |${userAuthenticationMessage(true) } +// | +// |""", +// branchJsonV220, +// branchJsonV220, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// InsufficientAuthorisationToCreateBranch, +// UnknownError +// ), +// List(apiTagBranch, apiTagOpenData), +// Some(List(canCreateBranch,canCreateBranchAtAnyBank)) +// ) +// +// lazy val createBranch: OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "branches" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (bank, callContext) <- NewStyle.function.getBank(bankId, callContext) +// _ <- Future( +// NewStyle.function.hasAllEntitlements(bank.bankId.value, u.userId, canCreateBranch::Nil, canCreateBranchAtAnyBank::Nil, cc.callContext) +// ) +// branchJsonV220 <- NewStyle.function.tryons(failMsg = InvalidJsonFormat + " BranchJsonV300", 400, callContext) { +// json.extract[BranchJsonV220] +// } +// _ <- Helper.booleanToFuture(failMsg = "BANK_ID has to be the same in the URL and Body", 400, callContext) { +// branchJsonV220.bank_id == bank.bankId.value +// } +// branch <- NewStyle.function.tryons(CouldNotTransformJsonToInternalModel + " Branch", 400, cc.callContext) { +// transformV220ToBranch(branchJsonV220).head +// } +// (success, callContext) <- NewStyle.function.createOrUpdateBranch(branch, callContext) +// } yield { +// (JSONFactory220.createBranchJson(success), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// createAtm, +// implementedInApiVersion, +// "createAtm", +// "POST", +// "/banks/BANK_ID/atms", +// "Create ATM", +// s"""Create ATM for the Bank. +// | +// |${userAuthenticationMessage(true) } +// | +// |""", +// atmJsonV220, +// atmJsonV220, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// UserHasMissingRoles, +// UnknownError +// ), +// List(apiTagATM), +// Some(List(canCreateAtm,canCreateAtmAtAnyBank)) +// ) +// +// +// +// lazy val createAtm: OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "atms" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// atmJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the ${classOf[AtmJsonV400]}", 400, callContext) { +// json.extract[AtmJsonV220] +// } +// _ <- NewStyle.function.hasAtLeastOneEntitlement(failMsg = createAtmEntitlementsRequiredText)(bankId.value, u.userId, createAtmEntitlements, callContext) +// _ <- Helper.booleanToFuture(s"$InvalidJsonValue BANK_ID has to be the same in the URL and Body", 400, callContext){atmJsonV400.bank_id == bankId.value} +// atm <- NewStyle.function.tryons(ErrorMessages.CouldNotTransformJsonToInternalModel + " Atm", 400, callContext) { +// JSONFactory220.transformToAtmFromV220(atmJson).head +// } +// (atm, callContext) <- NewStyle.function.createOrUpdateAtm(atm, callContext) +// } yield { +// (JSONFactory220.createAtmJson(atm), HttpCode.`201`(callContext)) +// } +// } +// } +// +// +// +// val createProductEntitlementsRequiredForSpecificBank = canCreateProduct :: Nil +// val createProductEntitlementsRequiredForAnyBank = canCreateProductAtAnyBank :: Nil +// +// resourceDocs += ResourceDoc( +// createProduct, +// implementedInApiVersion, +// "createProduct", +// "PUT", +// "/banks/BANK_ID/products", +// "Create Product", +// s"""Create or Update Product for the Bank. +// | +// |${userAuthenticationMessage(true) } +// | +// |""", +// productJsonV220, +// productJsonV220, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// UserHasMissingRoles, +// UnknownError +// ), +// List(apiTagProduct), +// Some(List(canCreateProduct, canCreateProductAtAnyBank)) +// ) +// +// +// +// lazy val createProduct: OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "products" :: Nil JsonPut json -> _ => { +// cc => +// implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// _ <- NewStyle.function.hasAtLeastOneEntitlement(failMsg = createProductEntitlementsRequiredText)(bankId.value, u.userId, createProductEntitlements, callContext) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// failMsg = s"$InvalidJsonFormat The Json body should be the $PostPutProductJsonV310 " +// product <- NewStyle.function.tryons(failMsg, 400, callContext) { +// json.extract[ProductJsonV220] +// } +// (success, callContext) <- NewStyle.function.createOrUpdateProduct( +// bankId = bankId.value, +// code = product.code, +// parentProductCode = None, +// name = product.name, +// category = product.category, +// family = product.family, +// superFamily = product.super_family, +// moreInfoUrl = product.more_info_url, +// termsAndConditionsUrl = null, +// details = product.details, +// description = product.description, +// metaLicenceId = product.meta.license.id, +// metaLicenceName = product.meta.license.name, +// callContext +// ) +// } yield { +// (JSONFactory220.createProductJson(success), HttpCode.`201`(callContext)) +// } +// } +// } +// +// +// +// val createFxEntitlementsRequiredForSpecificBank = canCreateFxRate :: Nil +// val createFxEntitlementsRequiredForAnyBank = canCreateFxRateAtAnyBank :: Nil +// +// resourceDocs += ResourceDoc( +// createFx, +// implementedInApiVersion, +// "createFx", +// "PUT", +// "/banks/BANK_ID/fx", +// "Create Fx", +// s"""Create or Update Fx for the Bank. +// | +// |Example: +// | +// |“from_currency_code”:“EUR”, +// |“to_currency_code”:“USD”, +// |“conversion_value”: 1.136305, +// |“inverse_conversion_value”: 1 / 1.136305 = 0.8800454103431737, +// | +// | Thus 1 Euro = 1.136305 US Dollar +// | and +// | 1 US Dollar = 0.8800 Euro +// | +// | +// |${userAuthenticationMessage(true) } +// | +// |""", +// fxJsonV220, +// fxJsonV220, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// UserHasMissingRoles, +// UnknownError +// ), +// List(apiTagFx), +// Some(List(canCreateFxRate, canCreateFxRateAtAnyBank)) +// ) +// +// +// +// lazy val createFx: OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "fx" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (bank, callContext) <- NewStyle.function.getBank(bankId, callContext) +// _ <- Future { +// NewStyle.function.hasAllEntitlements( +// bank.bankId.value, +// u.userId, +// createFxEntitlementsRequiredForSpecificBank, +// createFxEntitlementsRequiredForAnyBank, +// callContext +// ) +// } +// fx <- NewStyle.function.tryons(ErrorMessages.InvalidJsonFormat, 400, callContext) { +// json.extract[FXRateJsonV220] +// } +// _ <- NewStyle.function.isValidCurrencyISOCode(fx.from_currency_code, callContext) +// _ <- NewStyle.function.isValidCurrencyISOCode(fx.to_currency_code, callContext) +// (fxRate, callContext)<- NewStyle.function.createOrUpdateFXRate( +// bankId = fx.bank_id, +// fromCurrencyCode = fx.from_currency_code, +// toCurrencyCode = fx.to_currency_code, +// conversionValue = fx.conversion_value, +// inverseConversionValue = fx.inverse_conversion_value, +// effectiveDate = fx.effective_date, +// callContext +// ) +// } yield { +// val viewJSON = JSONFactory220.createFXRateJSON(fxRate) +// (viewJSON, HttpCode.`201`(callContext)) +// } +// } +// } +// +// +// +// +// +// +// resourceDocs += ResourceDoc( +// createAccount, +// implementedInApiVersion, +// "createAccount", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID", +// "Create Account", +// """Create Account at bank specified by BANK_ID with Id specified by ACCOUNT_ID. +// | +// | +// |The User can create an Account for themself or an Account for another User if they have CanCreateAccount role. +// | +// |If USER_ID is not specified the account will be owned by the logged in User. +// | +// |The type field should be a product_code from Product. +// | +// |Note: The Amount must be zero.""".stripMargin, +// createAccountJSONV220, +// createAccountJSONV220, +// List( +// InvalidJsonFormat, +// BankNotFound, +// AuthenticatedUserIsRequired, +// InvalidUserId, +// InvalidAccountIdFormat, +// InvalidBankIdFormat, +// UserNotFoundById, +// UserHasMissingRoles, +// InvalidAccountBalanceAmount, +// InvalidAccountInitialBalance, +// InitialBalanceMustBeZero, +// InvalidAccountBalanceCurrency, +// AccountIdAlreadyExists, +// UnknownError +// ), +// List(apiTagAccount,apiTagOnboarding), +// Some(List(canCreateAccount)) +// ) +// +// +// lazy val createAccount : OBPEndpoint = { +// // Create a new account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: Nil JsonPut json -> _ => { +// cc =>{ +// implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// failMsg = s"$InvalidJsonFormat The Json body should be the $CreateAccountJSONV220 " +// createAccountJson <- NewStyle.function.tryons(failMsg, 400, callContext) { +// json.extract[CreateAccountJSONV220] +// } +// +// loggedInUserId = u.userId +// userIdAccountOwner = if (createAccountJson.user_id.nonEmpty) createAccountJson.user_id else loggedInUserId +// _ <- Helper.booleanToFuture(InvalidAccountIdFormat, cc=callContext){ +// isValidID(accountId.value) +// } +// _ <- Helper.booleanToFuture(InvalidBankIdFormat, cc=callContext){ +// isValidID(accountId.value) +// } +// +// (postedOrLoggedInUser,callContext) <- NewStyle.function.findByUserId(userIdAccountOwner, callContext) +// +// // User can create account for self or an account for another user if they have CanCreateAccount role +// _ <- Helper.booleanToFuture(InvalidAccountIdFormat, cc=callContext){ +// isValidID(accountId.value) +// } +// +// _ <- if(userIdAccountOwner == loggedInUserId) Future.successful(Full(Unit)) +// else NewStyle.function.hasEntitlement(bankId.value, loggedInUserId, canCreateAccount, callContext, s"${UserHasMissingRoles} $canCreateAccount or create account for self") +// +// initialBalanceAsString = createAccountJson.balance.amount +// accountType = createAccountJson.`type` +// accountLabel = createAccountJson.label +// initialBalanceAsNumber <- NewStyle.function.tryons(InvalidAccountInitialBalance, 400, callContext) { +// BigDecimal(initialBalanceAsString) +// } +// +// _ <- Helper.booleanToFuture(InitialBalanceMustBeZero, cc=callContext){0 == initialBalanceAsNumber} +// +// _ <- Helper.booleanToFuture(InvalidISOCurrencyCode, cc=callContext){isValidCurrencyISOCode(createAccountJson.balance.currency)} +// +// +// currency = createAccountJson.balance.currency +// +// (_, callContext ) <- NewStyle.function.getBank(bankId, callContext) +// +// (bankAccount,callContext) <- NewStyle.function.createBankAccount( +// bankId, +// accountId, +// accountType, +// accountLabel, +// currency, +// initialBalanceAsNumber, +// postedOrLoggedInUser.name, +// createAccountJson.branch_id, +// List(AccountRouting(createAccountJson.account_routing.scheme, createAccountJson.account_routing.address)), +// callContext +// ) +// //1 Create or Update the `Owner` for the new account +// //2 Add permission to the user +// //3 Set the user as the account holder +// _ <- BankAccountCreation.setAccountHolderAndRefreshUserAccountAccess(bankId, accountId, postedOrLoggedInUser, callContext) +// } yield { +// (JSONFactory220.createAccountJSON(userIdAccountOwner, bankAccount), HttpCode.`200`(callContext)) +// +// } +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// config, +// implementedInApiVersion, +// "config", +// "GET", +// "/config", +// "Get API Configuration", +// """Returns information about: +// | +// |* API Config +// |* Akka ports +// |* Elastic search ports +// |* Cached function """, +// EmptyBody, +// configurationJSON, +// List( +// AuthenticatedUserIsRequired, +// UserHasMissingRoles, +// UnknownError +// ), +// apiTagApi :: Nil, +// Some(List(canGetConfig))) +// +// lazy val config: OBPEndpoint = { +// case "config" :: Nil JsonGet _ => +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// _ <- NewStyle.function.hasEntitlement("", u.userId, ApiRole.canGetConfig, callContext) +// } yield { +// (JSONFactory220.getConfigInfoJSON(), callContext) +// } +// } +// +// +// +// resourceDocs += ResourceDoc( +// getConnectorMetrics, +// implementedInApiVersion, +// "getConnectorMetrics", +// "GET", +// "/management/connector/metrics", +// "Get Connector Metrics", +// s"""Get the all metrics +// | +// |require CanGetConnectorMetrics role +// | +// |Filters Part 1.*filtering* (no wilde cards etc.) parameters to GET /management/connector/metrics +// | +// |Should be able to filter on the following metrics fields +// | +// |eg: /management/connector/metrics?from_date=$DateWithMsExampleString&to_date=$DateWithMsExampleString&limit=50&offset=2 +// | +// |1 from_date (defaults to one week before current date): eg:from_date=$DateWithMsExampleString +// | +// |2 to_date (defaults to current date) eg:to_date=$DateWithMsExampleString +// | +// |3 limit (for pagination: defaults to 1000) eg:limit=2000 +// | +// |4 offset (for pagination: zero index, defaults to 0) eg: offset=10 +// | +// |eg: /management/connector/metrics?from_date=$DateWithMsExampleString&to_date=$DateWithMsExampleString&limit=100&offset=300 +// | +// |Other filters: +// | +// |5 connector_name (if null ignore) +// | +// |6 function_name (if null ignore) +// | +// |7 correlation_id (if null ignore) +// | +// """.stripMargin, +// EmptyBody, +// connectorMetricsJson, +// List( +// InvalidDateFormat, +// UnknownError +// ), +// List(apiTagMetric, apiTagApi), +// Some(List(canGetConnectorMetrics))) +// +// lazy val getConnectorMetrics : OBPEndpoint = { +// case "management" :: "connector" :: "metrics" :: Nil JsonGet _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// _ <- NewStyle.function.hasEntitlement("", u.userId, ApiRole.canGetConnectorMetrics, callContext) +// httpParams <- NewStyle.function.extractHttpParamsFromUrl(cc.url) +// (obpQueryParams, callContext) <- createQueriesByHttpParamsFuture(httpParams, callContext) +// metrics <- Future(ConnectorMetricsProvider.metrics.vend.getAllConnectorMetrics(obpQueryParams)) +// } yield { +// (JSONFactory220.createConnectorMetricsJson(metrics), HttpCode.`200`(callContext)) +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// createConsumer, +// implementedInApiVersion, +// "createConsumer", +// "POST", +// "/management/consumers", +// "Post a Consumer", +// s"""Create a Consumer (Authenticated access). +// | +// |""", +// ConsumerPostJSON( +// "Test", +// "Test", +// "Description", +// "some@email.com", +// "redirecturl", +// "createdby", +// true, +// new Date(), +// """-----BEGIN CERTIFICATE----- +// |client_certificate_content +// |-----END CERTIFICATE-----""".stripMargin +// ), +// ConsumerPostJSON( +// "Some app name", +// "App type", +// "Description", +// "some.email@example.com", +// "Some redirect url", +// "Created by UUID", +// true, +// new Date(), +// """-----BEGIN CERTIFICATE----- +// |client_certificate_content +// |-----END CERTIFICATE-----""".stripMargin +// ), +// List( +// AuthenticatedUserIsRequired, +// UserHasMissingRoles, +// InvalidJsonFormat, +// UnknownError +// ), +// List(apiTagConsumer, apiTagOldStyle), +// Some(List(canCreateConsumer))) +// +// +// lazy val createConsumer: OBPEndpoint = { +// case "management" :: "consumers" :: Nil JsonPost json -> _ => { +// cc => +// for { +// u <- cc.user ?~! AuthenticatedUserIsRequired +// _ <- NewStyle.function.ownEntitlement("", u.userId, ApiRole.canCreateConsumer, cc.callContext) +// postedJson <- tryo {json.extract[ConsumerPostJSON]} ?~! InvalidJsonFormat +// consumer <- Consumers.consumers.vend.createConsumer(Some(generateUUID()), +// Some(generateUUID()), +// Some(postedJson.enabled), +// Some(postedJson.app_name), +// None, +// Some(postedJson.description), +// Some(postedJson.developer_email), +// Some(postedJson.redirect_url), +// Some(u.userId), +// Some(postedJson.clientCertificate), +// None, +// None, +// ) +// } yield { +// // Format the data as json +// val json = JSONFactory220.createConsumerJSON(consumer) +// // Return +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// createCounterparty, +// implementedInApiVersion, +// "createCounterparty", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/counterparties", +// "Create Counterparty (Explicit)", +// s"""Create Counterparty (Explicit) for an Account. +// | +// |In OBP, there are two types of Counterparty. +// | +// |* Explicit Counterparties (those here) which we create explicitly and are used in COUNTERPARTY Transaction Requests +// | +// |* Implicit Counterparties (AKA Other Accounts) which are generated automatically from the other sides of Transactions. +// | +// |Explicit Counterparties are created for the account / view +// |They are how the user of the view (e.g. account owner) refers to the other side of the transaction +// | +// |name : the human readable name (e.g. Piano teacher, Miss Nipa) +// | +// |description : the human readable name (e.g. Piano teacher, Miss Nipa) +// | +// |bank_routing_scheme : eg: bankId or bankCode or any other strings +// | +// |bank_routing_address : eg: `gh.29.uk`, must be valid sandbox bankIds +// | +// |account_routing_scheme : eg: AccountId or AccountNumber or any other strings +// | +// |account_routing_address : eg: `1d65db7c-a7b2-4839-af41-95`, must be valid accountIds +// | +// |other_account_secondary_routing_scheme : eg: IBan or any other strings +// | +// |other_account_secondary_routing_address : if it is an IBAN, it should be unique for each counterparty. +// | +// |other_branch_routing_scheme : eg: branchId or any other strings or you can leave it empty, not useful in sandbox mode. +// | +// |other_branch_routing_address : eg: `branch-id-123` or you can leave it empty, not useful in sandbox mode. +// | +// |is_beneficiary : must be set to `true` in order to send payments to this counterparty +// | +// |bespoke: It supports a list of key-value, you can add it to the counterparty. +// | +// |bespoke.key : any info-key you want to add to this counterparty +// | +// |bespoke.value : any info-value you want to add to this counterparty +// | +// |The view specified by VIEW_ID must have the canAddCounterparty permission +// | +// |A minimal example for TransactionRequestType == COUNTERPARTY +// | { +// | "name": "Tesobe1", +// | "description": "Good Company", +// | "other_bank_routing_scheme": "OBP", +// | "other_bank_routing_address": "gh.29.uk", +// | "other_account_routing_scheme": "OBP", +// | "other_account_routing_address": "8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0", +// | "is_beneficiary": true, +// | "other_account_secondary_routing_scheme": "", +// | "other_account_secondary_routing_address": "", +// | "other_branch_routing_scheme": "", +// | "other_branch_routing_address": "", +// | "bespoke": [] +// |} +// | +// | +// |A minimal example for TransactionRequestType == SEPA +// | +// | { +// | "name": "Tesobe2", +// | "description": "Good Company", +// | "other_bank_routing_scheme": "OBP", +// | "other_bank_routing_address": "gh.29.uk", +// | "other_account_routing_scheme": "OBP", +// | "other_account_routing_address": "8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0", +// | "other_account_secondary_routing_scheme": "IBAN", +// | "other_account_secondary_routing_address": "DE89 3704 0044 0532 0130 00", +// | "is_beneficiary": true, +// | "other_branch_routing_scheme": "", +// | "other_branch_routing_address": "", +// | "bespoke": [] +// |} +// | +// |${userAuthenticationMessage(true)} +// | +// |""".stripMargin, +// postCounterpartyJSON, +// counterpartyWithMetadataJson, +// List( +// AuthenticatedUserIsRequired, +// InvalidAccountIdFormat, +// InvalidBankIdFormat, +// BankNotFound, +// AccountNotFound, +// InvalidJsonFormat, +// ViewNotFound, +// CounterpartyAlreadyExists, +// UnknownError +// ), +// List(apiTagCounterparty, apiTagAccount)) +// +// +// lazy val createCounterparty: OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "counterparties" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// _ <- Helper.booleanToFuture(InvalidAccountIdFormat, cc=callContext) {isValidID(accountId.value)} +// _ <- Helper.booleanToFuture(InvalidBankIdFormat, cc=callContext) {isValidID(bankId.value)} +// (bank, callContext ) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// postJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PostCounterpartyJSON", 400, cc.callContext) { +// json.extract[PostCounterpartyJSON] +// } +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// _ <- Helper.booleanToFuture( +// s"${ErrorMessages.NoViewPermission} You need the `${(CAN_ADD_COUNTERPARTY)}` permission on the View(${viewId.value} )", +// cc = callContext +// ) { +// ViewPermission.findViewPermissions(view).exists(_.permission.get == CAN_ADD_COUNTERPARTY) +// } +// (counterparty, callContext) <- Connector.connector.vend.checkCounterpartyExists(postJson.name, bankId.value, accountId.value, viewId.value, callContext) +// +// _ <- Helper.booleanToFuture(CounterpartyAlreadyExists.replace("value for BANK_ID or ACCOUNT_ID or VIEW_ID or NAME.", +// s"COUNTERPARTY_NAME(${postJson.name}) for the BANK_ID(${bankId.value}) and ACCOUNT_ID(${accountId.value}) and VIEW_ID($viewId)"), cc=callContext){ +// counterparty.isEmpty +// } +// _ <- booleanToFuture(s"$InvalidValueLength. The maximum length of `description` field is ${MappedCounterparty.mDescription.maxLen}", cc=callContext){ +// postJson.description.length <= 36 +// } +// +// //If other_account_routing_scheme=="OBP" or other_account_secondary_routing_address=="OBP" we will check if it is a real obp bank account. +// (_, callContext)<- if (postJson.other_bank_routing_scheme.equalsIgnoreCase("OBP") && postJson.other_account_routing_scheme.equalsIgnoreCase("OBP")){ +// for{ +// (_, callContext) <- NewStyle.function.getBank(BankId(postJson.other_bank_routing_address), Some(cc)) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(BankId(postJson.other_bank_routing_address), AccountId(postJson.other_account_routing_address), callContext) +// +// } yield { +// (account, callContext) +// } +// } else if (postJson.other_bank_routing_scheme.equalsIgnoreCase("OBP") && postJson.other_account_secondary_routing_scheme.equalsIgnoreCase("OBP")){ +// for{ +// (_, callContext) <- NewStyle.function.getBank(BankId(postJson.other_bank_routing_address), Some(cc)) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(BankId(postJson.other_bank_routing_address), AccountId(postJson.other_account_secondary_routing_address), callContext) +// +// } yield { +// (account, callContext) +// } +// }else if (postJson.other_bank_routing_scheme.equalsIgnoreCase("ACCOUNT_NUMBER")|| postJson.other_bank_routing_scheme.equalsIgnoreCase("ACCOUNT_NO")) { +// for { +// bankIdOption <- Future.successful(if (postJson.other_bank_routing_address.isEmpty) None else Some(postJson.other_bank_routing_address)) +// (account, callContext) <- NewStyle.function.getBankAccountByNumber( +// bankIdOption.map(BankId(_)), +// postJson.other_bank_routing_address, +// callContext) +// } yield { +// (account, callContext) +// } +// }else +// Future{(Full(()), Some(cc))} +// +// +// otherAccountRoutingSchemeOBPFormat = if(postJson.other_account_routing_scheme.equalsIgnoreCase("AccountNo")) "ACCOUNT_NUMBER" else StringHelpers.snakify(postJson.other_account_routing_scheme).toUpperCase +// +// +// (counterparty, callContext) <- NewStyle.function.createCounterparty( +// name=postJson.name, +// description=postJson.description, +// currency = "", +// createdByUserId=u.userId, +// thisBankId=bankId.value, +// thisAccountId=accountId.value, +// thisViewId = viewId.value, +// otherAccountRoutingScheme=otherAccountRoutingSchemeOBPFormat, +// otherAccountRoutingAddress=postJson.other_account_routing_address, +// otherAccountSecondaryRoutingScheme=postJson.other_account_secondary_routing_scheme, +// otherAccountSecondaryRoutingAddress=postJson.other_account_secondary_routing_address, +// otherBankRoutingScheme=postJson.other_bank_routing_scheme, +// otherBankRoutingAddress=postJson.other_bank_routing_address, +// otherBranchRoutingScheme=postJson.other_branch_routing_scheme, +// otherBranchRoutingAddress=postJson.other_branch_routing_address, +// isBeneficiary=postJson.is_beneficiary, +// bespoke=postJson.bespoke.map(bespoke =>CounterpartyBespoke(bespoke.key,bespoke.value)) +// , callContext) +// +// (counterpartyMetadata, callContext) <- NewStyle.function.getOrCreateMetadata(bankId, accountId, counterparty.counterpartyId, postJson.name, callContext) +// +// } yield { +// (JSONFactory220.createCounterpartyWithMetadataJSON(counterparty,counterpartyMetadata), HttpCode.`201`(callContext)) +// } +// } +// } +// +// +// /* +// resourceDocs += ResourceDoc( +// getCustomerViewsForAccount, +// apiVersion, +// "getCustomerViews", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID/customer-views", +// "Get Customers that have access to a View", +// s"""Returns the Customers (and the Users linked to the Customer) that have access to the view: +// | +// |* Customer: legal_name, customer_number, customer_id +// |* User: username, user_id, email +// |* View: view_id +// | +// |${authenticationRequiredMessage(true)}""".stripMargin, +// EmptyBody, +// customerViewsJsonV220, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// AccountNotFound, +// ViewNotFound +// ), +// List(apiTagAccount, apiTagCustomer, apiTagView) +// ) +// +// lazy val getCustomerViewsForAccount : OBPEndpoint = { +// //get account by id +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "customer-views" :: Nil JsonGet req => { +// cc => +// for { +// (bank, callContext) <- Bank(bankId, Some(cc)) ?~ BankNotFound +// account <- BankAccount(bank.bankId, accountId) ?~ ErrorMessages.AccountNotFound +// view <- Views.views.vend.view(viewId, BankIdAccountId(account.bankId, account.accountId)) +// availableViews <- Full(account.permittedViews(user)) +// canUserAccessView <- tryo(availableViews.find(_ == viewId)) ?~! UserNoPermissionAccessView +// moderatedAccount <- account.moderatedBankAccount(view, user) +// } yield { +// val viewsAvailable = availableViews.map(JSONFactory300.createViewJSON).sortBy(_.short_name) +// val moderatedAccountJson = createBankAccountJSON(moderatedAccount, viewsAvailable) +// successJsonResponse(Extraction.decompose(moderatedAccountJson)) +// } +// } +// } +// +// */ +// +// +// +// /* +// lazy val getCustomerViewsForAccount : OBPEndpoint = { +// case "management" :: "connector" :: "metrics" :: Nil JsonGet _ => { +// cc =>{ +// for { +// u <- user ?~! ErrorMessages.AuthenticatedUserIsRequired +// _ <- booleanToBox(hasEntitlement("", u.userId, ApiRole.CanGetConnectorMetrics), s"$CanGetConnectorMetrics entitlement required") +// +// } yield { +// val json = {} +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// } +// +// */ +// +// /* +// +// +// +// +// */ +// +// } +//} \ No newline at end of file From 6795c3f53627d8b1bbf775478e20d7a732cd9ac5 Mon Sep 17 00:00:00 2001 From: Hongwei Date: Fri, 22 May 2026 10:18:13 +0200 Subject: [PATCH 10/10] refactor/revert the code and comment them --- .../scala/code/api/v1_2_1/APIMethods121.scala | 3219 +++++++++++++++++ .../scala/code/api/v1_3_0/APIMethods130.scala | 122 + .../scala/code/api/v1_4_0/APIMethods140.scala | 557 +++ 3 files changed, 3898 insertions(+) diff --git a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala index 7d36e7fd9c..cc0dfbf6fd 100644 --- a/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala +++ b/obp-api/src/main/scala/code/api/v1_2_1/APIMethods121.scala @@ -6,3 +6,3222 @@ trait APIMethods121 { self: RestHelper => } object APIMethods121 extends RestHelper with APIMethods121 { val Implementations1_2_1 = Http4s121.Implementations1_2_1 } + +//package code.api.v1_2_1 +// +//import code.api.Constant._ +//import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ +//import code.api.cache.Caching +//import code.api.util.APIUtil._ +//import code.api.util.ApiTag._ +//import code.api.util.ErrorMessages._ +//import code.api.util.FutureUtil.EndpointContext +//import code.api.util.NewStyle.HttpCode +//import code.api.util._ +//import code.api.util.newstyle.ViewNewStyle +//import code.bankconnectors._ +//import code.metadata.counterparties.Counterparties +//import code.model.{BankAccountX, BankX, ModeratedTransactionMetadata, UserX, toBankAccountExtended, toBankExtended} +//import code.util.Helper +//import code.util.Helper.booleanToBox +//import code.views.Views +//import com.openbankproject.commons.ExecutionContext.Implicits.global +//import com.openbankproject.commons.model._ +//import com.openbankproject.commons.util.ApiVersion +//import com.tesobe.CacheKeyFromArguments +//import net.liftweb.common._ +//import net.liftweb.http.JsonResponse +//import net.liftweb.http.rest.RestHelper +//import net.liftweb.json.Extraction +//import net.liftweb.json.JsonAST.JValue +//import net.liftweb.util.Helpers._ +// +//import java.net.URL +//import java.util.UUID.randomUUID +//import scala.collection.mutable.ArrayBuffer +//import scala.concurrent.Future +//import scala.concurrent.duration._ +//import scala.language.postfixOps +// +//trait APIMethods121 { +// //needs to be a RestHelper to get access to JsonGet, JsonPost, etc. +// self: RestHelper => +// +// val apiMethods121GetTransactionsTTL = APIUtil.getPropsValue("api.cache.ttl.seconds.APIMethods121.getTransactions", "0").toInt * 1000 // Miliseconds +// +// // helper methods begin here +// +// private def privateBankAccountsListToJson(bankAccounts: List[BankAccount], privateViewsUserCanAccess: List[View]): JValue = { +// val accJson : List[AccountJSON] = bankAccounts.map( account => { +// val viewsAvailable : List[ViewJSONV121] = +// (privateViewsUserCanAccess +// .filter(v =>v.bankId==account.bankId && v.accountId ==account.accountId && v.isPrivate)//filter the view for this account. +// .map(JSONFactory.createViewJSON(_)) +// .distinct) ++ +// (privateViewsUserCanAccess +// .filter(v =>v.isSystem && v.isPrivate)//plus the system views. +// .map(JSONFactory.createViewJSON(_)) +// .distinct) +// JSONFactory.createAccountJSON(account,viewsAvailable) +// }) +// +// val accounts = new AccountsJSON(accJson) +// Extraction.decompose(accounts) +// } +// +// private def publicBankAccountsListToJson(bankAccounts: List[BankAccount], publicViews: List[View]): JValue = { +// val accJson : List[AccountJSON] = bankAccounts.map( account => { +// val viewsAvailable : List[ViewJSONV121] = +// publicViews +// .filter(v =>v.bankId==account.bankId && v.accountId ==account.accountId && v.isPublic) +// .map(v => JSONFactory.createViewJSON(v)) +// .distinct +// JSONFactory.createAccountJSON(account,viewsAvailable) +// }) +// +// val accounts = new AccountsJSON(accJson) +// Extraction.decompose(accounts) +// } +// +// def checkIfLocationPossible(lat:Double,lon:Double) : Box[Unit] = { +// if(scala.math.abs(lat) <= 90 & scala.math.abs(lon) <= 180) +// Full(()) +// else +// Failure("Coordinates not possible") +// } +// +// private def moderatedTransactionMetadata(bankId : BankId, accountId : AccountId, viewId : ViewId, transactionID : TransactionId, user : Box[User], callContext: Option[CallContext]) : Box[ModeratedTransactionMetadata] ={ +// for { +// (account, callContext) <- BankAccountX(bankId, accountId, callContext) ?~! BankAccountNotFound +// view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), user, callContext) +// (moderatedTransaction, callContext) <- account.moderatedTransaction(transactionID, view, BankIdAccountId(bankId,accountId), user, callContext) +// metadata <- Box(moderatedTransaction.metadata) ?~ { s"$NoViewPermission can_see_transaction_metadata. Current ViewId($viewId)" } +// } yield metadata +// } +// private def moderatedTransactionMetadataFuture(bankId : BankId, accountId : AccountId, viewId : ViewId, transactionID : TransactionId, user : Box[User], callContext: Option[CallContext]): Future[ModeratedTransactionMetadata] = { +// for { +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view: View <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), user, callContext) +// (moderatedTransaction, callContext) <- account.moderatedTransactionFuture(transactionID, view, user, callContext) map { +// unboxFullOrFail(_, callContext, GetTransactionsException) +// } +// metadata <- Future(moderatedTransaction.metadata) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_transaction_metadata. Current ViewId($viewId)") +// } +// } yield metadata +// } +// +// // helper methods end here +// +// val Implementations1_2_1 = new Object(){ +// +// val resourceDocs = ArrayBuffer[ResourceDoc]() +// val apiVersion = ApiVersion.v1_2_1 // was String "1_2_1" +// val apiVersionStatus : String = "STABLE" +// +// resourceDocs += ResourceDoc( +// root, +// apiVersion, +// "root", +// "GET", +// "/root", +// "Get API Info (root)", +// """Returns information about: +// | +// |* API version +// |* Hosted by information +// |* Git Commit""", +// EmptyBody, +// apiInfoJSON, +// List(UnknownError, MandatoryPropertyIsNotSet), +// apiTagApi :: Nil) +// +// lazy val root : OBPEndpoint = { +// case (Nil | "root" :: Nil) JsonGet _ => { +// cc => +// implicit val ec = EndpointContext(Some(cc)) +// for { +// _ <- Future(()) // Just start async call +// } yield { +// (JSONFactory.getApiInfoJSON(apiVersion,apiVersionStatus), HttpCode.`200`(cc.callContext)) +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// getBanks, +// apiVersion, +// "getBanks", +// "GET", +// "/banks", +// "Get Banks", +// """Get banks on this API instance +// |Returns a list of banks supported on this server: +// | +// |* ID used as parameter in URLs +// |* Short and full name of bank +// |* Logo URL +// |* Website""", +// EmptyBody, +// banksJSON, +// List(UnknownError), +// apiTagBank :: apiTagPsd2 :: apiTagOldStyle :: Nil) +// +// lazy val getBanks : OBPEndpoint = { +// //get banks +// case "banks" :: Nil JsonGet req => { +// cc => +// def banksToJson(banksList: List[Bank]): JValue = { +// val banksJSON: List[BankJSON] = banksList.map(b => { +// JSONFactory.createBankJSON(b) +// }) +// val banks = new BanksJSON(banksJSON) +// Extraction.decompose(banks) +// } +// for((banks, callContext)<- Connector.connector.vend.getBanksLegacy(Some(cc))) +// yield(successJsonResponse(banksToJson(banks))) +// } +// } +// +// +// resourceDocs += ResourceDoc( +// bankById, +// apiVersion, +// "bankById", +// "GET", +// "/banks/BANK_ID", +// "Get Bank", +// """Get the bank specified by BANK_ID +// |Returns information about a single bank specified by BANK_ID including: +// | +// |* Short and full name of bank +// |* Logo URL +// |* Website""", +// EmptyBody, +// bankJSON, +// List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), +// apiTagBank :: apiTagPsd2 :: apiTagOldStyle :: Nil) +// +// +// lazy val bankById : OBPEndpoint = { +// //get bank by id +// case "banks" :: BankId(bankId) :: Nil JsonGet req => { +// cc => +// def bankToJson(bank : Bank) : JValue = { +// val bankJSON = JSONFactory.createBankJSON(bank) +// Extraction.decompose(bankJSON) +// } +// for((bank, callContext)<- BankX(bankId, Some(cc)) ?~! BankNotFound) +// yield successJsonResponse(bankToJson(bank)) +// } +// } +// +// +// resourceDocs += ResourceDoc( +// getPrivateAccountsAllBanks, +// apiVersion, +// "getPrivateAccountsAllBanks", +// "GET", +// "/accounts", +// "Get accounts at all banks (Private, inc views)", +// s"""Returns the list of accounts at that the user has access to at all banks. +// |For each account the API returns the account ID and the available views. +// | +// |${userAuthenticationMessage(true)} +// |""".stripMargin, +// EmptyBody, +// accountJSON, +// List(AuthenticatedUserIsRequired, UnknownError), +// apiTagAccount :: apiTagPsd2 :: apiTagOldStyle :: Nil) +// +// //TODO double check with `lazy val privateAccountsAllBanks :`, they are the same now. +// lazy val getPrivateAccountsAllBanks : OBPEndpoint = { +// //get accounts for all banks (private + public) +// case "accounts" :: Nil JsonGet req => { +// cc => +// for { +// u <- cc.user ?~ AuthenticatedUserIsRequired +// (privateViewsUserCanAccess, privateAccountAccess) <- Full(Views.views.vend.privateViewsUserCanAccess(u)) +// availablePrivateAccounts <- Full(BankAccountX.privateAccounts(privateAccountAccess)) +// } yield { +// successJsonResponse(privateBankAccountsListToJson(availablePrivateAccounts, privateViewsUserCanAccess)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// privateAccountsAllBanks, +// apiVersion, +// "privateAccountsAllBanks", +// "GET", +// "/accounts/private", +// "Get private accounts at all banks (Authenticated access)", +// """Returns the list of private accounts the user has access to at all banks. +// |For each account the API returns the ID and the available views. +// | +// |Authentication via OAuth is required. +// | +// |""".stripMargin, +// EmptyBody, +// accountJSON, +// List(AuthenticatedUserIsRequired, UnknownError), +// apiTagAccount :: apiTagPsd2 :: apiTagOldStyle :: Nil) +// +// lazy val privateAccountsAllBanks : OBPEndpoint = { +// //get private accounts for all banks +// case "accounts" :: "private" :: Nil JsonGet req => { +// cc => +// for { +// u <- cc.user ?~ AuthenticatedUserIsRequired +// (privateViewsUserCanAccess, privateAccountAccess) <- Full(Views.views.vend.privateViewsUserCanAccess(u)) +// privateAccounts <- Full(BankAccountX.privateAccounts(privateAccountAccess)) +// } yield { +// successJsonResponse(privateBankAccountsListToJson(privateAccounts, privateViewsUserCanAccess)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// publicAccountsAllBanks, +// apiVersion, +// "publicAccountsAllBanks", +// "GET", +// "/accounts/public", +// "Get public accounts at all banks (Anonymous access)", +// """ +// |Returns the list of private accounts the user has access to at all banks. +// |For each account the API returns the ID and the available views. +// |Authentication via OAuth is required. +// | +// |""".stripMargin, +// EmptyBody, +// accountJSON, +// List(UnknownError), +// apiTagAccount :: apiTagOldStyle :: Nil) +// +// lazy val publicAccountsAllBanks : OBPEndpoint = { +// //get public accounts for all banks +// case "accounts" :: "public" :: Nil JsonGet req => { +// cc => +// for{ +// (publicViews, publicAccountAccess) <- Full(Views.views.vend.publicViews) +// publicAccounts <- Full(BankAccountX.publicAccounts(publicAccountAccess)) +// publicAccountsJson <- Full(publicBankAccountsListToJson(publicAccounts, publicViews)) +// } yield{ +// successJsonResponse(publicAccountsJson) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getPrivateAccountsAtOneBank, +// apiVersion, +// "getPrivateAccountsAtOneBank", +// "GET", +// "/banks/BANK_ID/accounts", +// "Get accounts at bank (Private)", +// s"""Returns the list of accounts at BANK_ID that the user has access to. +// |For each account the API returns the account ID and the available views. +// | +// |${userAuthenticationMessage(true)} +// | +// """, +// EmptyBody, +// accountJSON, +// List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), +// apiTagAccount :: apiTagOldStyle :: Nil) +// +// lazy val getPrivateAccountsAtOneBank : OBPEndpoint = { +// //get accounts for a single bank (private + public) +// case "banks" :: BankId(bankId) :: "accounts" :: Nil JsonGet req => { +// cc => +// for{ +// u <- cc.user ?~! ErrorMessages.AuthenticatedUserIsRequired +// (bank, callContext) <- BankX(bankId, Some(cc)) ?~! BankNotFound +// } yield { +// val (privateViewsUserCanAccessAtOneBank, privateAccountAccess) = Views.views.vend.privateViewsUserCanAccessAtBank(u, bankId) +// val availablePrivateAccounts = bank.privateAccounts(privateAccountAccess) +// successJsonResponse(privateBankAccountsListToJson(availablePrivateAccounts, privateViewsUserCanAccessAtOneBank)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// privateAccountsAtOneBank, +// apiVersion, +// "privateAccountsAtOneBank", +// "GET", +// "/banks/BANK_ID/accounts/private", +// "Get private accounts at one bank", +// s"""Returns the list of private accounts at BANK_ID that the user has access to. +// |For each account the API returns the ID and the available views. +// | +// |${userAuthenticationMessage(true)} +// | +// |""".stripMargin, +// EmptyBody, +// accountJSON, +// List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), +// List(apiTagAccount, apiTagPsd2, apiTagOldStyle)) +// +// lazy val privateAccountsAtOneBank : OBPEndpoint = { +// //get private accounts for a single bank +// case "banks" :: BankId(bankId) :: "accounts" :: "private" :: Nil JsonGet req => { +// cc => +// for { +// u <- cc.user ?~ AuthenticatedUserIsRequired +// (bank, callContext) <- BankX(bankId, Some(cc)) ?~! BankNotFound +// } yield { +// val (privateViewsUserCanAccessAtOneBank, privateAccountAccess) = Views.views.vend.privateViewsUserCanAccessAtBank(u, bankId) +// val availablePrivateAccounts = bank.privateAccounts(privateAccountAccess) +// successJsonResponse(privateBankAccountsListToJson(availablePrivateAccounts, privateViewsUserCanAccessAtOneBank)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// publicAccountsAtOneBank, +// apiVersion, +// "publicAccountsAtOneBank", +// "GET", +// "/banks/BANK_ID/accounts/public", +// "Get public accounts at one bank (Anonymous access)", +// """Returns a list of the public accounts at BANK_ID. For each account the API returns the ID and the available views. +// | +// |Authentication via OAuth is not required. +// | +// |""".stripMargin, +// EmptyBody, +// accountJSON, +// List(AuthenticatedUserIsRequired, UnknownError, BankNotFound), +// apiTagAccountPublic :: apiTagAccount :: apiTagPublicData :: apiTagOldStyle :: Nil) +// +// lazy val publicAccountsAtOneBank : OBPEndpoint = { +// //get public accounts for a single bank +// case "banks" :: BankId(bankId) :: "accounts" :: "public" :: Nil JsonGet req => { +// cc => +// for { +// (bank, callContext) <- BankX(bankId, Some(cc)) ?~! BankNotFound +// (publicViewsForBank, publicAccountAccess) <- Full(Views.views.vend.publicViewsForBank(bank.bankId)) +// publicAccounts<- Full(bank.publicAccounts(publicAccountAccess)) +// } yield { +// val publicAccountsJson = publicBankAccountsListToJson(publicAccounts, publicViewsForBank) +// successJsonResponse(publicAccountsJson) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// accountById, +// apiVersion, +// "accountById", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/account", +// "Get account by id", +// s"""Information returned about an account specified by ACCOUNT_ID as moderated by the view (VIEW_ID): +// | +// |* Number +// |* Owners +// |* Type +// |* Balance +// |* IBAN +// |* Available views +// | +// |More details about the data moderation by the view [here](#1_2_1-getViewsForBankAccount). +// | +// |${userAuthenticationMessage(false)} +// | +// |Authentication is required if the 'is_public' field in view (VIEW_ID) is not set to `true`. +// | +// |""".stripMargin, +// EmptyBody, +// moderatedAccountJSON, +// List(AuthenticatedUserIsRequired, UnknownError, BankAccountNotFound), +// apiTagAccount :: apiTagOldStyle :: Nil) +// +// lazy val accountById : OBPEndpoint = { +// //get account by id +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "account" :: Nil JsonGet req => { +// cc => +// for { +// u <- cc.user ?~ AuthenticatedUserIsRequired +// (account, callContext) <- BankAccountX(bankId, accountId, Some(cc)) ?~! BankAccountNotFound +// availableviews <- Full(Views.views.vend.privateViewsUserCanAccessForAccount(u, BankIdAccountId(account.bankId, account.accountId))) +// view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), Some(u), callContext) +// moderatedAccount <- account.moderatedBankAccount(view, BankIdAccountId(bankId, accountId), cc.user, callContext) +// } yield { +// val viewsAvailable = availableviews.map(JSONFactory.createViewJSON) +// val moderatedAccountJson = JSONFactory.createBankAccountJSON(moderatedAccount, viewsAvailable) +// successJsonResponse(Extraction.decompose(moderatedAccountJson)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateAccountLabel, +// apiVersion, +// "updateAccountLabel", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID", +// "Update Account Label", +// s"""Update the label for the account. The label is how the account is known to the account owner e.g. 'My savings account' +// | +// | +// |${userAuthenticationMessage(true)} +// | +// """.stripMargin, +// updateAccountJSON, +// successMessage, +// List(InvalidJsonFormat, AuthenticatedUserIsRequired, UnknownError, BankAccountNotFound, "user does not have access to owner view on account"), +// List(apiTagAccount) +// ) +// +// lazy val updateAccountLabel : OBPEndpoint = { +// //change account label +// // TODO Remove BANK_ID AND ACCOUNT_ID from the body? (duplicated in URL) +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// json <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[UpdateAccountJSON] } +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// permission <- NewStyle.function.permission(account.bankId, account.accountId, u, callContext) +// anyViewContainsCanUpdateBankAccountLabelPermission = permission.views.map(_.allowed_actions.exists(_ == CAN_UPDATE_BANK_ACCOUNT_LABEL)).find(true == _).getOrElse(false) +// _ <- Helper.booleanToFuture( +// s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_UPDATE_BANK_ACCOUNT_LABEL)}` permission on any your views", +// cc = callContext +// ) { +// anyViewContainsCanUpdateBankAccountLabelPermission +// } +// (success, callContext) <- +// Connector.connector.vend.updateAccountLabel(bankId, accountId, json.label, callContext) map { i => +// (unboxFullOrFail(i._1, i._2, +// s"$UpdateBankAccountLabelError Current BankId is $bankId and Current AccountId is $accountId", 404), i._2) +// } +// } yield { +// (successMessage, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getViewsForBankAccount, +// apiVersion, +// "getViewsForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views", +// "Get Views for Account", +// s"""#Views +// | +// | +// |Views in Open Bank Project provide a mechanism for fine grained access control and delegation to Accounts and Transactions. Account holders use the 'owner' view by default. Delegated access is made through other views for example 'accountants', 'share-holders' or 'tagging-application'. Views can be created via the API and each view has a list of entitlements. +// | +// |Views on accounts and transactions filter the underlying data to redact certain fields for certain users. For instance the balance on an account may be hidden from the public. The way to know what is possible on a view is determined in the following JSON. +// | +// |**Data:** When a view moderates a set of data, some fields my contain the value `null` rather than the original value. This indicates either that the user is not allowed to see the original data or the field is empty. +// | +// |There is currently one exception to this rule; the 'holder' field in the JSON contains always a value which is either an alias or the real name - indicated by the 'is_alias' field. +// | +// |**Action:** When a user performs an action like trying to post a comment (with POST API call), if he is not allowed, the body response will contain an error message. +// | +// |**Metadata:** +// |Transaction metadata (like images, tags, comments, etc.) will appears *ONLY* on the view where they have been created e.g. comments posted to the public view only appear on the public view. +// | +// |The other account metadata fields (like image_URL, more_info, etc.) are unique through all the views. Example, if a user edits the 'more_info' field in the 'team' view, then the view 'authorities' will show the new value (if it is allowed to do it). +// | +// |# All +// |*Optional* +// | +// |Returns the list of the views created for account ACCOUNT_ID at BANK_ID. +// | +// |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", +// EmptyBody, +// viewsJSONV121, +// List(AuthenticatedUserIsRequired, BankAccountNotFound, UnknownError, "user does not have owner access"), +// List(apiTagView, apiTagAccount, apiTagOldStyle)) +// +// lazy val getViewsForBankAccount : OBPEndpoint = { +// //get the available views on an bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonGet req => { +// cc => +// for { +// u <- cc.user ?~ AuthenticatedUserIsRequired +// bankAccount <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound +// permission <- Views.views.vend.permission(BankIdAccountId(bankAccount.bankId, bankAccount.accountId), u) +// anyViewContainsCanSeeAvailableViewsForBankAccountPermission = permission.views.map(_.allowed_actions.exists(_ == CAN_SEE_AVAILABLE_VIEWS_FOR_BANK_ACCOUNT)).find(_.==(true)).getOrElse(false) +// _ <- Helper.booleanToBox( +// anyViewContainsCanSeeAvailableViewsForBankAccountPermission, +// s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_SEE_AVAILABLE_VIEWS_FOR_BANK_ACCOUNT)}` permission on any your views" +// ) +// views <- Full(Views.views.vend.availableViewsForAccount(BankIdAccountId(bankAccount.bankId, bankAccount.accountId))) +// } yield { +// val viewsJSON = JSONFactory.createViewsJSON(views) +// successJsonResponse(Extraction.decompose(viewsJSON)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// createViewForBankAccount, +// apiVersion, +// "createViewForBankAccount", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views", +// "Create View", +// s"""#Create a view on bank account +// | +// | ${userAuthenticationMessage(true)} and the user needs to have access to the owner view. +// | The 'alias' field in the JSON can take one of three values: +// | +// | * _public_: to use the public alias if there is one specified for the other account. +// | * _private_: to use the private alias if there is one specified for the other account. +// | +// | * _''(empty string)_: to use no alias; the view shows the real name of the other account. +// | +// | The 'hide_metadata_if_alias_used' field in the JSON can take boolean values. If it is set to `true` and there is an alias on the other account then the other accounts' metadata (like more_info, url, image_url, open_corporates_url, etc.) will be hidden. Otherwise the metadata will be shown. +// | +// | The 'allowed_actions' field is a list containing the name of the actions allowed on this view, all the actions contained will be set to `true` on the view creation, the rest will be set to `false`.""", +// createViewJsonV121, +// viewJSONV121, +// List( +// AuthenticatedUserIsRequired, +// InvalidJsonFormat, +// BankAccountNotFound, +// UnknownError, +// "user does not have owner access" +// ), +// List(apiTagAccount, apiTagView, apiTagOldStyle) +// ) +// +// lazy val createViewForBankAccount : OBPEndpoint = { +// //creates a view on an bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "views" :: Nil JsonPost json -> _ => { +// cc => +// for { +// u <- cc.user ?~ AuthenticatedUserIsRequired +// createViewJsonV121 <- tryo{json.extract[CreateViewJsonV121]} ?~ InvalidJsonFormat +// //customer views are started ith `_`,eg _life, _work, and System views startWith letter, eg: owner +// _<- booleanToBox(isValidCustomViewName(createViewJsonV121.name), InvalidCustomViewFormat+s"Current view_name (${createViewJsonV121.name})") +// account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound +// createViewJson = CreateViewJson( +// createViewJsonV121.name, +// createViewJsonV121.description, +// metadata_view = "", //this only used from V300 +// createViewJsonV121.is_public, +// createViewJsonV121.which_alias_to_use, +// createViewJsonV121.hide_metadata_if_alias_used, +// createViewJsonV121.allowed_actions +// ) +// anyViewContainsCanCreateCustomViewPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) +// .map(_.views.map(_.allowed_actions.exists(_ == CAN_CREATE_CUSTOM_VIEW))).getOrElse(Nil).find(_.==(true)).getOrElse(false) +// _ <- booleanToBox( +// anyViewContainsCanCreateCustomViewPermission, +// s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_CREATE_CUSTOM_VIEW)}` permission on any your views" +// ) +// view <- Views.views.vend.createCustomView(BankIdAccountId(bankId,accountId), createViewJson)?~ CreateCustomViewError +// } yield { +// val viewJSON = JSONFactory.createViewJSON(view) +// successJsonResponse(Extraction.decompose(viewJSON), 201) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateViewForBankAccount, +// apiVersion, +// "updateViewForBankAccount", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID", +// "Update View", +// s"""Update an existing view on a bank account +// | +// |${userAuthenticationMessage(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)""", +// updateViewJsonV121, +// viewJSONV121, +// List( +// InvalidJsonFormat, +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// ViewNotFound, +// UnknownError, +// "user does not have owner access" +// ), +// List(apiTagAccount, apiTagView, apiTagOldStyle) +// ) +// +// //TODO. remove and replace it with V510. +// lazy val updateViewForBankAccount: OBPEndpoint = { +// //updates a view on a bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId +// ) :: "views" :: ViewId(viewId) :: Nil JsonPut json -> _ => { +// cc => +// for { +// updateJsonV121 <- tryo{ json.extract[UpdateViewJsonV121] } ?~ InvalidJsonFormat +// account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound +// u <- cc.user ?~ AuthenticatedUserIsRequired +// //customer views are started ith `_`,eg _life, _work, and System views startWith letter, eg: owner +// _ <- booleanToBox(viewId.value.startsWith("_"), InvalidCustomViewFormat +s"Current view_id (${viewId.value})") +// view <- Views.views.vend.customView(viewId, BankIdAccountId(bankId, accountId)) ?~! ViewNotFound +// _ <- booleanToBox(!view.isSystem, SystemViewsCanNotBeModified) +// updateViewJson = UpdateViewJSON( +// description = updateJsonV121.description, +// metadata_view = view.metadataView, //this only used from V300, here just copy from currentView . +// is_public = updateJsonV121.is_public, +// which_alias_to_use = updateJsonV121.which_alias_to_use, +// hide_metadata_if_alias_used = updateJsonV121.hide_metadata_if_alias_used, +// allowed_actions = updateJsonV121.allowed_actions +// ) +// anyViewContainsCanUpdateCustomViewPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) +// .map(_.views.map(_.allowed_actions.exists(_ == CAN_UPDATE_CUSTOM_VIEW))).getOrElse(Nil).find(_.==(true)).getOrElse(false) +// _ <- booleanToBox( +// anyViewContainsCanUpdateCustomViewPermission, +// s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_UPDATE_CUSTOM_VIEW)}` permission on any your views" +// ) +// updatedView <- Views.views.vend.updateCustomView(BankIdAccountId(bankId, accountId),viewId, updateViewJson) ?~ CreateCustomViewError +// } yield { +// val viewJSON = JSONFactory.createViewJSON(updatedView) +// successJsonResponse(Extraction.decompose(viewJSON), 200) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteViewForBankAccount, +// apiVersion, +// "deleteViewForBankAccount", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/views/VIEW_ID", +// "Delete Custom View", +// "Deletes the custom view specified by VIEW_ID on the bank account specified by ACCOUNT_ID at bank BANK_ID", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// UnknownError, +// "user does not have owner access" +// ), +// List(apiTagView, apiTagAccount) +// ) +// +// lazy val deleteViewForBankAccount: OBPEndpoint = { +// //deletes a view on an bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId +// ) :: "views" :: ViewId(viewId) :: Nil JsonDelete req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) +// // custom views start with `_` eg _play, _work, and System views start with a letter, eg: owner +// _ <- Helper.booleanToFuture(InvalidCustomViewFormat+s"Current view_name (${viewId.value})", cc=callContext) { viewId.value.startsWith("_") } +// _ <- ViewNewStyle.customView(viewId, BankIdAccountId(bankId, accountId), callContext) +// +// anyViewContainsCanDeleteCustomViewPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) +// .map(_.views.map(_.allowed_actions.exists(_ == CAN_DELETE_CUSTOM_VIEW))).getOrElse(Nil).find(_.==(true)).getOrElse(false) +// _ <- Helper.booleanToFuture( +// s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_DELETE_CUSTOM_VIEW)}` permission on any your views", +// cc = callContext +// ) { +// anyViewContainsCanDeleteCustomViewPermission +// } +// +// deleted <- ViewNewStyle.removeCustomView(viewId, BankIdAccountId(bankId, accountId),callContext) +// } yield { +// (Full(deleted), HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getPermissionsForBankAccount, +// apiVersion, +// "getPermissionsForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions", +// "Get access", +// s"""Returns the list of the permissions at BANK_ID for account ACCOUNT_ID, with each time a pair composed of the user and the views that he has access to. +// | +// |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", +// EmptyBody, +// permissionsJSON, +// List(AuthenticatedUserIsRequired, UnknownError), +// List(apiTagView, apiTagAccount, apiTagEntitlement, apiTagOldStyle) +// ) +// +// lazy val getPermissionsForBankAccount: OBPEndpoint = { +// //get access +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: Nil JsonGet req => { +// cc => +// for { +// u <- cc.user ?~ AuthenticatedUserIsRequired +// account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound +// anyViewContainsCanSeeViewsWithPermissionsForAllUsersPermission = Views.views.vend.permission(BankIdAccountId(account.bankId, account.accountId), u) +// .map(_.views.map(_.allowed_actions.exists(_ == CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ALL_USERS))).getOrElse(Nil).find(_.==(true)).getOrElse(false) +// _ <- booleanToBox( +// anyViewContainsCanSeeViewsWithPermissionsForAllUsersPermission, +// s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ALL_USERS)}` permission on any your views" +// ) +// permissions = Views.views.vend.permissions(BankIdAccountId(bankId, accountId)) +// } yield { +// val permissionsJSON = JSONFactory.createPermissionsJSON(permissions) +// successJsonResponse(Extraction.decompose(permissionsJSON)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getPermissionForUserForBankAccount, +// apiVersion, +// "getPermissionForUserForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER_ID/USER_ID", +// "Get access for specific user", +// s"""Returns the list of the views at BANK_ID for account ACCOUNT_ID that a USER_ID at their provider PROVIDER_ID has access to. +// |All url parameters must be [%-encoded](http://en.wikipedia.org/wiki/Percent-encoding), which is often especially relevant for USER_ID and PROVIDER_ID. +// | +// |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", +// EmptyBody, +// viewsJSONV121, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// UnknownError, +// "user does not have access to owner view on account" +// ), +// List(apiTagAccount, apiTagView, apiTagEntitlement, apiTagOldStyle) +// ) +// +// +// lazy val getPermissionForUserForBankAccount: OBPEndpoint = { +// //get access for specific user +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: Nil JsonGet req => { +// cc => +// for { +// loggedInUser <- cc.user ?~ AuthenticatedUserIsRequired +// account <- BankAccountX(bankId, accountId) ?~! BankAccountNotFound +// loggedInUserPermissionBox = Views.views.vend.permission(BankIdAccountId(bankId, accountId), loggedInUser) +// anyViewContainsCanSeeViewsWithPermissionsForOneUserPermission = loggedInUserPermissionBox.map(_.views.map(_.allowed_actions.exists(_ == CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ONE_USER))) +// .getOrElse(Nil).find(_.==(true)).getOrElse(false) +// _ <- booleanToBox( +// anyViewContainsCanSeeViewsWithPermissionsForOneUserPermission, +// s"${ErrorMessages.CreateCustomViewError} You need the `${(CAN_SEE_VIEWS_WITH_PERMISSIONS_FOR_ONE_USER)}` permission on any your views" +// ) +// userFromURL <- UserX.findByProviderId(provider, providerId) ?~! UserNotFoundByProviderAndProvideId +// permission <- Views.views.vend.permission(BankIdAccountId(bankId, accountId), userFromURL) +// } yield { +// val views = JSONFactory.createViewsJSON(permission.views) +// successJsonResponse(Extraction.decompose(views)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addPermissionForUserForBankAccountForMultipleViews, +// apiVersion, +// "addPermissionForUserForBankAccountForMultipleViews", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views", +// "Grant User access to a list of views", +// s"""Grants the user identified by PROVIDER_ID at their provider PROVIDER access to a list of views at BANK_ID for account ACCOUNT_ID. +// | +// |All url parameters must be [%-encoded](http://en.wikipedia.org/wiki/Percent-encoding), which is often especially relevant for PROVIDER_ID and PROVIDER. +// | +// |${userAuthenticationMessage(true)} +// | +// |The User needs to have access to the owner view.""", +// viewIdsJson, +// viewsJSONV121, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// UnknownError, +// "wrong format JSON", +// "could not save the privilege", +// "user does not have access to owner view on account" +// ), +// List(apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired)) +// +// lazy val addPermissionForUserForBankAccountForMultipleViews : OBPEndpoint = { +// //add access for specific user to a list of views +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) +// failMsg = "wrong format JSON" +// viewIds <- NewStyle.function.tryons(failMsg, 400, callContext) { json.extract[ViewIdsJson] } +// (addedViews, callContext) <- ViewNewStyle.grantAccessToMultipleViews( +// account, u, +// viewIds.views.map(viewIdString => BankIdAccountIdViewId(bankId, accountId,ViewId(viewIdString))), +// provider, +// providerId, +// callContext +// ) +// } yield { +// (JSONFactory.createViewsJSON(addedViews), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addPermissionForUserForBankAccountForOneView, +// apiVersion, +// "addPermissionForUserForBankAccountForOneView", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views/VIEW_ID", +// "Grant User access to View", +// s"""Grants the User identified by PROVIDER_ID at PROVIDER access to the view VIEW_ID at BANK_ID for account ACCOUNT_ID. +// | +// |All url parameters must be [%-encoded](http://en.wikipedia.org/wiki/Percent-encoding), which is often especially relevant for PROVIDER and PROVIDER_ID. +// | +// |${userAuthenticationMessage(true)} and the user needs to have access to the owner view. +// | +// |Granting access to a public view will return an error message, as the user already has access.""", +// EmptyBody, // No Json body required +// viewJSONV121, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// UnknownError, +// UserLacksPermissionCanGrantAccessToViewForTargetAccount, +// "could not save the privilege", +// "user does not have access to owner view on account" +// ), +// List(apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired)) +// +// lazy val addPermissionForUserForBankAccountForOneView : OBPEndpoint = { +// //add access for specific user to a specific view +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: ViewId(viewId) :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) +// (addedView, callContext) <- ViewNewStyle.grantAccessToView(account, u, BankIdAccountIdViewId(bankId, accountId, viewId), provider, providerId, callContext) +// } yield { +// val viewJson = JSONFactory.createViewJSON(addedView) +// (viewJson, HttpCode.`201`(callContext)) +// } +// } +// } +// +// +// val generalRevokeAccessToViewText : String = +// """ +// |The User is identified by PROVIDER_ID at their PROVIDER. +// | +// |The Account is specified by BANK_ID and ACCOUNT_ID. +// | +// |The View is specified by VIEW_ID. +// | +// | +// |PROVIDER (may be a URL so) must be URL Encoded. +// | +// |PROVIDER_ID is normally equivalent to USERNAME. However, see Get User by ID or GET Current User for Provider information. +// | +// |Attempting to revoke access to a public view will return an error message. +// | +// |An Account Owner cannot revoke access to an Owner View unless at least one other User has Owner View access. +// | +// """.stripMargin +// +// +// resourceDocs += ResourceDoc( +// removePermissionForUserForBankAccountForOneView, +// apiVersion, +// "removePermissionForUserForBankAccountForOneView", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views/VIEW_ID", +// "Revoke access to one View", +// s"""Revokes access to a View on an Account for a certain User. +// | +// |$generalRevokeAccessToViewText +// | +// |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "could not save the privilege", +// "user does not have access to owner view on account", +// UnknownError +// ), +// List(apiTagView, apiTagAccount, apiTagUser, apiTagEntitlement, apiTagOwnerRequired)) +// +// lazy val removePermissionForUserForBankAccountForOneView : OBPEndpoint = { +// //delete access for specific user to one view +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: ViewId(viewId) :: Nil JsonDelete req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) +// _ <- ViewNewStyle.revokeAccessToView(account, u, BankIdAccountIdViewId(bankId, accountId, viewId), provider, providerId, callContext) +// } yield { +// (Full(""), HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// removePermissionForUserForBankAccountForAllViews, +// apiVersion, +// "removePermissionForUserForBankAccountForAllViews", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/permissions/PROVIDER/PROVIDER_ID/views", +// "Revoke access to all Views on Account", +// s""""Revokes access to all Views on an Account for a certain User. +// | +// |$generalRevokeAccessToViewText +// | +// |${userAuthenticationMessage(true)} and the user needs to have access to the owner view.""", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// UnknownError, +// "user does not have access to owner view on account" +// ), +// List(apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired)) +// +// lazy val removePermissionForUserForBankAccountForAllViews : OBPEndpoint = { +// //delete access for specific user to all the views +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: "permissions" :: provider :: providerId :: "views" :: Nil JsonDelete req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) +// _ <- NewStyle.function.revokeAllAccountAccess(account, u, provider, providerId, callContext) +// } yield { +// (Full(""), HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getOtherAccountsForBankAccount, +// apiVersion, +// "getOtherAccountsForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts", +// "Get Other Accounts of one Account", +// s"""Returns data about all the other accounts that have shared at least one transaction with the ACCOUNT_ID at BANK_ID. +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view VIEW_ID is not public.""", +// EmptyBody, +// otherAccountsJSON, +// List( +// BankAccountNotFound, +// UnknownError +// ), +// List(apiTagCounterparty, apiTagAccount, apiTagPsd2, apiTagOldStyle)) +// +// lazy val getOtherAccountsForBankAccount : OBPEndpoint = { +// //get other accounts for one account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, Some(cc)) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), cc.user, callContext) +// (otherBankAccounts, callContext) <- NewStyle.function.moderatedOtherBankAccounts(account, view, cc.user, callContext) +// } yield { +// (JSONFactory.createOtherBankAccountsJSON(otherBankAccounts), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getOtherAccountByIdForBankAccount, +// apiVersion, +// "getOtherAccountByIdForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID", +// "Get Other Account by Id", +// s"""Returns data about the Other Account that has shared at least one transaction with ACCOUNT_ID at BANK_ID. +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public.""", +// EmptyBody, +// otherAccountJSON, +// List(BankAccountNotFound, UnknownError), +// List(apiTagCounterparty, apiTagAccount)) +// +// lazy val getOtherAccountByIdForBankAccount : OBPEndpoint = { +// //get one other account by id +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (u, callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), u, callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, u, callContext) +// } yield { +// val otherBankAccountJson = JSONFactory.createOtherBankAccount(otherBankAccount) +// (otherBankAccountJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getOtherAccountMetadata, +// apiVersion, +// "getOtherAccountMetadata", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata", +// "Get Other Account Metadata", +// """Get metadata of one other account. +// |Returns only the metadata about one other bank account (OTHER_ACCOUNT_ID) that had shared at least one transaction with ACCOUNT_ID at BANK_ID. +// | +// |Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// otherAccountMetadataJSON, +// List(AuthenticatedUserIsRequired, UnknownError, "the view does not allow metadata access"), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val getOtherAccountMetadata : OBPEndpoint = { +// //get metadata of one other account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// } yield { +// val metadataJson = JSONFactory.createOtherAccountMetaDataJSON(otherBankAccount.metadata.get) +// (metadataJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getCounterpartyPublicAlias, +// apiVersion, +// "getCounterpartyPublicAlias", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", +// "Get public alias of other bank account", +// s"""Returns the public alias of the other account OTHER_ACCOUNT_ID. +// |${userAuthenticationMessage(false)} +// |${userAuthenticationMessage(true)} if the view is not public.""", +// EmptyBody, +// aliasJSON, +// List( +// BankAccountNotFound, +// UnknownError, +// "the view does not allow metadata access", +// "the view does not allow public alias access" +// ), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val getCounterpartyPublicAlias : OBPEndpoint = { +// //get public alias of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a public alias", cc=callContext) { +// otherBankAccount.metadata.get.publicAlias.isDefined +// } +// } yield { +// val aliasJson = JSONFactory.createAliasJSON(otherBankAccount.metadata.get.publicAlias.get) +// (aliasJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addCounterpartyPublicAlias, +// apiVersion, +// "addCounterpartyPublicAlias", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", +// "Add public alias to other bank account", +// s"""Creates the public alias for the other account OTHER_ACCOUNT_ID. +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public. +// | +// |Note: Public aliases are automatically generated for new 'other accounts / counterparties', so this call should only be used if +// |the public alias was deleted. +// | +// |The VIEW_ID parameter should be a view the caller is permitted to access to and that has permission to create public aliases.""", +// aliasJSON, +// successMessage, +// List( +// BankAccountNotFound, +// InvalidJsonFormat, +// UnknownError, +// "the view does not allow metadata access", +// "the view does not allow adding a public alias", +// "Alias cannot be added", +// "public alias added" +// ), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val addCounterpartyPublicAlias : OBPEndpoint = { +// //add public alias to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a public alias", cc=callContext) { +// otherBankAccount.metadata.get.addPublicAlias.isDefined +// } +// aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[AliasJSON] +// } +// (added, _) <- Future(Counterparties.counterparties.vend.addPublicAlias(other_account_id, aliasJson.alias)) map { i => +// (unboxFullOrFail(i, callContext, "Alias cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("public alias added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyPublicAlias, +// apiVersion, +// "updateCounterpartyPublicAlias", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", +// "Update public alias of other bank account", +// s"""Updates the public alias of the other account / counterparty OTHER_ACCOUNT_ID. +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public.""", +// aliasJSON, +// successMessage, +// List( +// BankAccountNotFound, +// InvalidJsonFormat, +// AuthenticatedUserIsRequired, +// "the view does not allow metadata access", +// "the view does not allow updating the public alias", +// "Alias cannot be updated", +// UnknownError +// ), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyPublicAlias : OBPEndpoint = { +// //update public alias of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a public alias", cc=callContext) { +// otherBankAccount.metadata.get.addPublicAlias.isDefined +// } +// aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[AliasJSON] +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addPublicAlias(other_account_id, aliasJson.alias)) map { i => +// (unboxFullOrFail(i, callContext, "Alias cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("public alias updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyPublicAlias, +// apiVersion, +// "deleteCounterpartyPublicAlias", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/public_alias", +// "Delete Counterparty Public Alias", +// s"""Deletes the public alias of the other account OTHER_ACCOUNT_ID. +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public.""", +// EmptyBody, +// EmptyBody, +// List( +// BankAccountNotFound, +// "the view does not allow metadata access", +// "the view does not allow deleting the public alias", +// "Alias cannot be deleted", +// UnknownError +// ), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val deleteCounterpartyPublicAlias : OBPEndpoint = { +// //delete public alias of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "public_alias" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a public alias", cc=callContext) { +// otherBankAccount.metadata.get.addPublicAlias.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.addPublicAlias(other_account_id, "")) map { i => +// (unboxFullOrFail(i, callContext, "Alias cannot be deleted", 400), i) +// } +// if(deleted) +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getOtherAccountPrivateAlias, +// apiVersion, +// "getOtherAccountPrivateAlias", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", +// "Get Other Account Private Alias", +// s"""Returns the private alias of the other account OTHER_ACCOUNT_ID. +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public.""", +// EmptyBody, +// aliasJSON, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "the view does not allow metadata access", +// "the view does not allow private alias access", +// UnknownError +// ), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val getOtherAccountPrivateAlias : OBPEndpoint = { +// //get private alias of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a private alias", cc=callContext) { +// otherBankAccount.metadata.get.privateAlias.isDefined +// } +// } yield { +// val aliasJson = JSONFactory.createAliasJSON(otherBankAccount.metadata.get.privateAlias.get) +// (aliasJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addOtherAccountPrivateAlias, +// apiVersion, +// "addOtherAccountPrivateAlias", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", +// "Create Other Account Private Alias", +// s"""Creates a private alias for the other account OTHER_ACCOUNT_ID. +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public.""", +// aliasJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow adding a private alias", +// "Alias cannot be added", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val addOtherAccountPrivateAlias : OBPEndpoint = { +// //add private alias to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a private alias", cc=callContext) { +// otherBankAccount.metadata.get.addPrivateAlias.isDefined +// } +// aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[AliasJSON] +// } +// (added, _) <- Future(Counterparties.counterparties.vend.addPrivateAlias(other_account_id, aliasJson.alias)) map { i => +// (unboxFullOrFail(i, callContext, "Alias cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("private alias added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyPrivateAlias, +// apiVersion, +// "updateCounterpartyPrivateAlias", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", +// "Update Counterparty Private Alias", +// s"""Updates the private alias of the counterparty (AKA other account) OTHER_ACCOUNT_ID. +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public.""", +// aliasJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow updating the private alias", +// "Alias cannot be updated", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyPrivateAlias : OBPEndpoint = { +// //update private alias of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a private alias", cc=callContext) { +// otherBankAccount.metadata.get.addPrivateAlias.isDefined +// } +// aliasJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[AliasJSON] +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addPrivateAlias(other_account_id, aliasJson.alias)) map { i => +// (unboxFullOrFail(i, callContext, "Alias cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("private alias updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyPrivateAlias, +// apiVersion, +// "deleteCounterpartyPrivateAlias", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/private_alias", +// "Delete Counterparty Private Alias", +// s"""Deletes the private alias of the other account OTHER_ACCOUNT_ID. +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public.""", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "the view does not allow metadata access", +// "the view does not allow deleting the private alias", +// "Alias cannot be deleted", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val deleteCounterpartyPrivateAlias : OBPEndpoint = { +// //delete private alias of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "private_alias" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a private alias", cc=callContext) { +// otherBankAccount.metadata.get.addPrivateAlias.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.addPrivateAlias(other_account_id, "")) map { i => +// (unboxFullOrFail(i, callContext, "Alias cannot be deleted", 400), i) +// } +// if(deleted) +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// //TODO: get more info of counterparty? +// +// resourceDocs += ResourceDoc( +// addCounterpartyMoreInfo, +// apiVersion, +// "addCounterpartyMoreInfo", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/more_info", +// "Add Counterparty More Info", +// "Add a description of the counter party from the perpestive of the account e.g. My dentist", +// moreInfoJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// NoViewPermission, +// "the view " + viewIdSwagger + "does not allow adding more info", +// "More Info cannot be added", +// UnknownError +// ), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val addCounterpartyMoreInfo : OBPEndpoint = { +// //add more info to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "more_info" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding more info", cc=callContext) { +// otherBankAccount.metadata.get.addMoreInfo.isDefined +// } +// moreInfoJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[MoreInfoJSON] +// } +// (added, _) <- Future(Counterparties.counterparties.vend.addMoreInfo(other_account_id, moreInfoJson.more_info)) map { i => +// (unboxFullOrFail(i, callContext, "More Info cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("more info added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyMoreInfo, +// apiVersion, +// "updateCounterpartyMoreInfo", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/more_info", +// "Update Counterparty More Info", +// "Update the more info description of the counter party from the perpestive of the account e.g. My dentist", +// moreInfoJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow updating more info", +// "More Info cannot be updated", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyMoreInfo : OBPEndpoint = { +// //update more info of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "more_info" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating more info", cc=callContext) { +// otherBankAccount.metadata.get.addMoreInfo.isDefined +// } +// moreInfoJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[MoreInfoJSON] +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addMoreInfo(other_account_id, moreInfoJson.more_info)) map { i => +// (unboxFullOrFail(i, callContext, "More Info cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("more info updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyMoreInfo, +// apiVersion, +// "deleteCounterpartyMoreInfo", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/more_info", +// "Delete more info of other bank account", +// "", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "the view does not allow metadata access", +// "the view does not allow deleting more info", +// "More Info cannot be deleted", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val deleteCounterpartyMoreInfo : OBPEndpoint = { +// //delete more info of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "more_info" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting more info", cc=callContext) { +// otherBankAccount.metadata.get.addMoreInfo.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.addMoreInfo(other_account_id, "")) map { i => +// (unboxFullOrFail(i, callContext, "More Info cannot be deleted", 400), i) +// } +// if(deleted) +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// //TODO: get url of counterparty? +// +// resourceDocs += ResourceDoc( +// addCounterpartyUrl, +// apiVersion, +// "addCounterpartyUrl", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/url", +// "Add url to other bank account", +// "A url which represents the counterparty (home page url etc.)", +// urlJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow adding a url", +// "URL cannot be added", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// +// lazy val addCounterpartyUrl : OBPEndpoint = { +// //add url to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "url" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a url", cc=callContext) { +// otherBankAccount.metadata.get.addURL.isDefined +// } +// urlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[UrlJSON] +// } +// (added, _) <- Future(Counterparties.counterparties.vend.addURL(other_account_id, urlJson.URL)) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("url added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyUrl, +// apiVersion, +// "updateCounterpartyUrl", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/url", +// "Update url of other bank account", +// "A url which represents the counterparty (home page url etc.)", +// urlJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// NoViewPermission, +// ViewNotFound, +// "URL cannot be updated", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyUrl : OBPEndpoint = { +// //update url of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "url" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a url", cc=callContext) { +// otherBankAccount.metadata.get.addURL.isDefined +// } +// urlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[UrlJSON] +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addURL(other_account_id, urlJson.URL)) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("url updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyUrl, +// apiVersion, +// "deleteCounterpartyUrl", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/url", +// "Delete url of other bank account", +// "", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "the view does not allow metadata access", +// "the view does not allow deleting a url", +// "URL cannot be deleted", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val deleteCounterpartyUrl : OBPEndpoint = { +// //delete url of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "url" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a url", cc=callContext) { +// otherBankAccount.metadata.get.addURL.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.addURL(other_account_id, "")) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be deleted", 400), i) +// } +// if(deleted) +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// //TODO: get image url of counterparty? +// +// resourceDocs += ResourceDoc( +// addCounterpartyImageUrl, +// apiVersion, +// "addCounterpartyImageUrl", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/image_url", +// "Add image url to other bank account", +// "Add a url that points to the logo of the counterparty", +// imageUrlJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow adding an image url", +// "URL cannot be added", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val addCounterpartyImageUrl : OBPEndpoint = { +// //add image url to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "image_url" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding an image url", cc=callContext) { +// otherBankAccount.metadata.get.addImageURL.isDefined +// } +// imageUrlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[ImageUrlJSON] +// } +// (added, _) <- Future(Counterparties.counterparties.vend.addImageURL(other_account_id, imageUrlJson.image_URL)) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("image url added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyImageUrl, +// apiVersion, +// "updateCounterpartyImageUrl", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/image_url", +// "Update Counterparty Image Url", +// "Update the url that points to the logo of the counterparty", +// imageUrlJSON, +// successMessage, +// List( +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow updating an image url", +// "URL cannot be updated", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyImageUrl : OBPEndpoint = { +// //update image url of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "image_url" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating an image url", cc=callContext) { +// otherBankAccount.metadata.get.addImageURL.isDefined +// } +// imageUrlJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[ImageUrlJSON] +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addImageURL(other_account_id, imageUrlJson.image_URL)) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("image url updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyImageUrl, +// apiVersion, +// "deleteCounterpartyImageUrl", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/image_url", +// "Delete Counterparty Image URL", +// "Delete image url of other bank account", +// EmptyBody, +// EmptyBody, +// List(UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) // Tag general then specific for consistent sorting +// +// lazy val deleteCounterpartyImageUrl : OBPEndpoint = { +// //delete image url of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "image_url" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting an image url", cc=callContext) { +// otherBankAccount.metadata.get.addImageURL.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.addImageURL(other_account_id, "")) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be deleted", 400), i) +// } +// if(deleted) +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// //TODO: get open corporates url of counterparty? +// +// resourceDocs += ResourceDoc( +// addCounterpartyOpenCorporatesUrl, +// apiVersion, +// "addCounterpartyOpenCorporatesUrl", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/open_corporates_url", +// "Add Open Corporates URL to Counterparty", +// "Add open corporates url to other bank account", +// openCorporateUrlJSON, +// successMessage, +// List( +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow adding an open corporate url", +// "URL cannot be added", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val addCounterpartyOpenCorporatesUrl : OBPEndpoint = { +// //add open corporate url to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "open_corporates_url" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding an open corporate url", cc=callContext) { +// otherBankAccount.metadata.get.addOpenCorporatesURL.isDefined +// } +// openCorpUrl <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[OpenCorporateUrlJSON] +// } +// (added, _) <- Future(Counterparties.counterparties.vend.addOpenCorporatesURL(other_account_id, openCorpUrl.open_corporates_URL)) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("open corporate url added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyOpenCorporatesUrl, +// apiVersion, +// "updateCounterpartyOpenCorporatesUrl", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/open_corporates_url", +// "Update Open Corporates Url of Counterparty", +// "Update open corporate url of other bank account", +// openCorporateUrlJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow updating an open corporate url", +// "URL cannot be updated", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyOpenCorporatesUrl : OBPEndpoint = { +// //update open corporate url of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "open_corporates_url" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating an open corporate url", cc=callContext) { +// otherBankAccount.metadata.get.addOpenCorporatesURL.isDefined +// } +// openCorpUrl <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[OpenCorporateUrlJSON] +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addOpenCorporatesURL(other_account_id, openCorpUrl.open_corporates_URL)) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("open corporate url updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyOpenCorporatesUrl, +// apiVersion, +// "deleteCounterpartyOpenCorporatesUrl", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/open_corporates_url", +// "Delete Counterparty Open Corporates URL", +// "Delete open corporate url of other bank account", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "the view does not allow metadata access", +// "the view does not allow deleting an open corporate url", +// "URL cannot be deleted", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val deleteCounterpartyOpenCorporatesUrl : OBPEndpoint = { +// //delete open corporate url of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "open_corporates_url" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting an open corporate url", cc=callContext) { +// otherBankAccount.metadata.get.addOpenCorporatesURL.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.addOpenCorporatesURL(other_account_id, "")) map { i => +// (unboxFullOrFail(i, callContext, "URL cannot be deleted", 400), i) +// } +// if(deleted) +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// //TODO: get corporate location of counterparty? +// +// resourceDocs += ResourceDoc( +// addCounterpartyCorporateLocation, +// apiVersion, +// "addCounterpartyCorporateLocation", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/corporate_location", +// "Add Corporate Location to Counterparty", +// "Add the geolocation of the counterparty's registered address", +// corporateLocationJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "the view does not allow metadata access", +// "the view does not allow adding a corporate location", +// "Coordinates not possible", +// "Corporate Location cannot be deleted", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val addCounterpartyCorporateLocation : OBPEndpoint = { +// //add corporate location to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts" :: other_account_id :: "metadata" :: "corporate_location" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a corporate location", cc=callContext) { +// otherBankAccount.metadata.get.addCorporateLocation.isDefined +// } +// corpLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[CorporateLocationJSON] +// } +// _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { +// checkIfLocationPossible(corpLocationJson.corporate_location.latitude, corpLocationJson.corporate_location.longitude).isDefined +// } +// (added, _) <- Future( +// Counterparties.counterparties.vend.addCorporateLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), corpLocationJson.corporate_location.longitude, corpLocationJson.corporate_location.latitude) +// ) map { i => +// (unboxFullOrFail(i, callContext, "Corporate Location cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("corporate location added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyCorporateLocation, +// apiVersion, +// "updateCounterpartyCorporateLocation", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/corporate_location", +// "Update Counterparty Corporate Location", +// "Update the geolocation of the counterparty's registered address", +// corporateLocationJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow updating a corporate location", +// "Coordinates not possible", +// "Corporate Location cannot be updated", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyCorporateLocation : OBPEndpoint = { +// //update corporate location of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "corporate_location" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a corporate location", cc=callContext) { +// otherBankAccount.metadata.get.addCorporateLocation.isDefined +// } +// corpLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[CorporateLocationJSON] +// } +// _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { +// checkIfLocationPossible(corpLocationJson.corporate_location.latitude, corpLocationJson.corporate_location.longitude).isDefined +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addCorporateLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), corpLocationJson.corporate_location.longitude, corpLocationJson.corporate_location.latitude)) map { i => +// (unboxFullOrFail(i, callContext, "Corporate Location cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("corporate location updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyCorporateLocation, +// apiVersion, +// "deleteCounterpartyCorporateLocation", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/corporate_location", +// "Delete Counterparty Corporate Location", +// "Delete corporate location of other bank account. Delete the geolocation of the counterparty's registered address", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// "the view does not allow metadata access", +// "Corporate Location cannot be deleted", +// "Delete not completed", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val deleteCounterpartyCorporateLocation : OBPEndpoint = { +// //delete corporate location of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "corporate_location" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a Corporate Location", cc=callContext) { +// otherBankAccount.metadata.get.deleteCorporateLocation.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.deleteCorporateLocation(other_account_id)) map { i => +// (unboxFullOrFail(i, callContext, "Corporate Location cannot be deleted", 400), i) +// } +// _ <- Helper.booleanToFuture(failMsg = "Delete not completed", cc=callContext) { +// deleted +// } +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// //TODO: get physical location of counterparty? +// +// resourceDocs += ResourceDoc( +// addCounterpartyPhysicalLocation, +// apiVersion, +// "addCounterpartyPhysicalLocation", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/physical_location", +// "Add physical location to other bank account", +// "Add geocoordinates of the counterparty's main location", +// physicalLocationJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow adding a physical location", +// "Coordinates not possible", +// "Physical Location cannot be added", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val addCounterpartyPhysicalLocation : OBPEndpoint = { +// //add physical location to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts" :: other_account_id :: "metadata" :: "physical_location" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow adding a physical location", cc=callContext) { +// otherBankAccount.metadata.get.addPhysicalLocation.isDefined +// } +// physicalLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[PhysicalLocationJSON] +// } +// _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { +// checkIfLocationPossible(physicalLocationJson.physical_location.latitude, physicalLocationJson.physical_location.longitude).isDefined +// } +// (added, _) <- Future( +// Counterparties.counterparties.vend.addPhysicalLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), physicalLocationJson.physical_location.longitude, physicalLocationJson.physical_location.latitude) +// ) map { i => +// (unboxFullOrFail(i, callContext, "Physical Location cannot be added", 400), i) +// } +// if(added) +// } yield { +// (SuccessMessage("physical location added"), HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateCounterpartyPhysicalLocation, +// apiVersion, +// "updateCounterpartyPhysicalLocation", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/physical_location", +// "Update Counterparty Physical Location", +// "Update geocoordinates of the counterparty's main location", +// physicalLocationJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// "the view does not allow metadata access", +// "the view does not allow updating a physical location", +// "Coordinates not possible", +// "Physical Location cannot be updated", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val updateCounterpartyPhysicalLocation : OBPEndpoint = { +// //update physical location to other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "physical_location" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow updating a physical location", cc=callContext) { +// otherBankAccount.metadata.get.addPhysicalLocation.isDefined +// } +// physicalLocationJson <- NewStyle.function.tryons(failMsg = InvalidJsonFormat, 400, callContext) { +// json.extract[PhysicalLocationJSON] +// } +// _ <- Helper.booleanToFuture(failMsg = "Coordinates not possible", 400, callContext) { +// checkIfLocationPossible(physicalLocationJson.physical_location.latitude, physicalLocationJson.physical_location.longitude).isDefined +// } +// (updated, _) <- Future(Counterparties.counterparties.vend.addPhysicalLocation(other_account_id, u.userPrimaryKey, (now:TimeSpan), physicalLocationJson.physical_location.longitude, physicalLocationJson.physical_location.latitude)) map { i => +// (unboxFullOrFail(i, callContext, "Physical Location cannot be updated", 400), i) +// } +// if(updated) +// } yield { +// (SuccessMessage("physical location updated"), HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteCounterpartyPhysicalLocation, +// apiVersion, +// "deleteCounterpartyPhysicalLocation", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/other_accounts/OTHER_ACCOUNT_ID/metadata/physical_location", +// "Delete Counterparty Physical Location", +// "Delete physical location of other bank account", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// NoViewPermission, +// "Physical Location cannot be deleted", +// "Delete not completed", +// UnknownError), +// List(apiTagCounterpartyMetaData, apiTagCounterparty)) +// +// lazy val deleteCounterpartyPhysicalLocation : OBPEndpoint = { +// //delete physical location of other bank account +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "other_accounts":: other_account_id :: "metadata" :: "physical_location" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (otherBankAccount, callContext) <- NewStyle.function.moderatedOtherBankAccount(account, other_account_id, view, Full(u), callContext) +// _ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_see_other_account_metadata. Current ViewId($viewId)", cc=callContext) { +// otherBankAccount.metadata.isDefined +// } +// _ <- Helper.booleanToFuture(failMsg = "the view " + viewId + "does not allow deleting a Physical Location", cc=callContext) { +// otherBankAccount.metadata.get.deletePhysicalLocation.isDefined +// } +// (deleted, _) <- Future(Counterparties.counterparties.vend.deletePhysicalLocation(other_account_id)) map { i => +// (unboxFullOrFail(i, callContext, "Physical Location cannot be deleted", 400), i) +// } +// _ <- Helper.booleanToFuture(failMsg = s"Delete not completed", cc=callContext) { +// deleted +// } +// } yield { +// ("", HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getTransactionsForBankAccount, +// apiVersion, +// "getTransactionsForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions", +// "Get Transactions for Account (Full)", +// s"""Returns transactions list of the account specified by ACCOUNT_ID and [moderated](#1_2_1-getViewsForBankAccount) by the view (VIEW_ID). +// | +// |Authentication via OAuth is required if the view is not public. +// | +// |${urlParametersDocument(true, true)} +// | +// |""", +// EmptyBody, +// transactionsJSON, +// List(BankAccountNotFound, UnknownError), +// List(apiTagTransaction, apiTagAccount, apiTagPsd2, apiTagOldStyle)) +// +// +// +// +// private def getTransactionsForBankAccountCached( +// paramsBox: Box[List[OBPQueryParam]], +// user: Box[User], +// accountId: AccountId, +// bankId: BankId, +// viewId : ViewId +// ): Box[JsonResponse] = { +// /** +// * Please note that "var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString)" +// * is just a temporary value field with UUID values in order to prevent any ambiguity. +// * The real value will be assigned by Macro during compile time at this line of a code: +// * https://github.com/OpenBankProject/scala-macros/blob/master/macros/src/main/scala/com/tesobe/CacheKeyFromArgumentsMacro.scala#L49 +// */ +// var cacheKey = (randomUUID().toString, randomUUID().toString, randomUUID().toString) +// CacheKeyFromArguments.buildCacheKey { +// Caching.memoizeSyncWithProvider(Some(cacheKey.toString()))(apiMethods121GetTransactionsTTL millisecond) { +// for { +// params <- paramsBox +// bankAccount <- BankAccountX(bankId, accountId) +// (bank, callContext) <- BankX(bankId, None) ?~! BankNotFound +// view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankAccount.bankId, bankAccount.accountId), user, None) +// (transactions, callContext) <- bankAccount.getModeratedTransactions(bank, user, view, BankIdAccountId(bankId, accountId), None, params ) +// } yield { +// val json = JSONFactory.createTransactionsJSON(transactions) +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// } +// +// lazy val getTransactionsForBankAccount : OBPEndpoint = { +// //get transactions +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: Nil JsonGet req => { +// val paramsBox: Box[List[OBPQueryParam]] = createQueriesByHttpParams(req.request.headers) +// cc => getTransactionsForBankAccountCached( +// paramsBox: Box[List[OBPQueryParam]], +// cc.user: Box[User], +// accountId: AccountId, +// bankId: BankId, +// viewId : ViewId +// ) +// } +// } +// +// resourceDocs += ResourceDoc( +// getTransactionByIdForBankAccount, +// apiVersion, +// "getTransactionByIdForBankAccount", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/transaction", +// "Get Transaction by Id", +// s"""Returns one transaction specified by TRANSACTION_ID of the account ACCOUNT_ID and [moderated](#1_2_1-getViewsForBankAccount) by the view (VIEW_ID). +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public. +// | +// | +// |""", +// EmptyBody, +// transactionJSON, +// List(BankAccountNotFound, UnknownError), +// List(apiTagTransaction, apiTagPsd2, apiTagOldStyle)) +// +// lazy val getTransactionByIdForBankAccount : OBPEndpoint = { +// //get transaction by id +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "transaction" :: Nil JsonGet req => { +// cc => +// for { +// (account, callContext) <- BankAccountX(bankId, accountId, Some(cc)) ?~! BankAccountNotFound +// view <- APIUtil.checkViewAccessAndReturnView(viewId, BankIdAccountId(account.bankId, account.accountId), cc.user, None) +// (moderatedTransaction, callContext) <- account.moderatedTransaction(transactionId, view, BankIdAccountId(bankId,accountId), cc.user, Some(cc)) +// } yield { +// val json = JSONFactory.createTransactionJSON(moderatedTransaction) +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getTransactionNarrative, +// apiVersion, +// "getTransactionNarrative", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", +// "Get a Transaction Narrative", +// """Returns the account owner description of the transaction [moderated](#1_2_1-getViewsForBankAccount) by the view. +// | +// |Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// transactionNarrativeJSON, +// List( +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val getTransactionNarrative : OBPEndpoint = { +// //get narrative +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// narrative <- Future(metadata.ownerComment) map { +// unboxFullOrFail(_, cc.callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// val narrativeJson = JSONFactory.createTransactionNarrativeJSON(narrative) +// (narrativeJson, HttpCode.`200`(cc.callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addTransactionNarrative, +// apiVersion, +// "addTransactionNarrative", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", +// "Add a Transaction Narrative", +// s"""Creates a description of the transaction TRANSACTION_ID. +// | +// |Note: Unlike other items of metadata, there is only one "narrative" per transaction accross all views. +// |If you set narrative via a view e.g. view-x it will be seen via view-y (as long as view-y has permission to see the narrative). +// | +// |${userAuthenticationMessage(false)} +// |Authentication is required if the view is not public. +// |""", +// transactionNarrativeJSON, +// successMessage, +// List( +// InvalidJsonFormat, +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val addTransactionNarrative : OBPEndpoint = { +// //add narrative +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// narrativeJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[TransactionNarrativeJSON] } +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// addNarrative <- Future(metadata.addOwnerComment) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// addNarrative(narrativeJson.narrative) +// val successJson = SuccessMessage("narrative added") +// (successJson, HttpCode.`201`(cc.callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateTransactionNarrative, +// apiVersion, +// "updateTransactionNarrative", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", +// "Update a Transaction Narrative", +// """Updates the description of the transaction TRANSACTION_ID. +// | +// |Authentication via OAuth is required if the view is not public.""", +// transactionNarrativeJSON, +// successMessage, +// List(InvalidJsonFormat, +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val updateTransactionNarrative : OBPEndpoint = { +// //update narrative +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// narrativeJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[TransactionNarrativeJSON] } +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// addNarrative <- Future(metadata.addOwnerComment) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// addNarrative(narrativeJson.narrative) +// val successJson = SuccessMessage("narrative updated") +// (successJson, HttpCode.`200`(cc.callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteTransactionNarrative, +// apiVersion, +// "deleteTransactionNarrative", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/narrative", +// "Delete a Transaction Narrative", +// """Deletes the description of the transaction TRANSACTION_ID. +// | +// |Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// NoViewPermission, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val deleteTransactionNarrative : OBPEndpoint = { +// //delete narrative +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "narrative" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// addNarrative <- Future(metadata.addOwnerComment) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// addNarrative("") +// val successJson = SuccessMessage("") +// (successJson, HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getCommentsForViewOnTransaction, +// apiVersion, +// "getCommentsForViewOnTransaction", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/comments", +// "Get Transaction Comments", +// """Returns the transaction TRANSACTION_ID comments made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). +// | +// |Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// transactionCommentsJSON, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val getCommentsForViewOnTransaction : OBPEndpoint = { +// //get comments +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "comments" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// comments <- Future(metadata.comments) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// val commentsJson = JSONFactory.createTransactionCommentsJSON(comments) +// (commentsJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addCommentForViewOnTransaction, +// apiVersion, +// "addCommentForViewOnTransaction", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/comments", +// "Add a Transaction Comment", +// """Posts a comment about a transaction TRANSACTION_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID. +// | +// |${authenticationRequiredMessage(false)} +// | +// |Authentication is required since the comment is linked with the user.""", +// postTransactionCommentJSON, +// transactionCommentJSON, +// List( +// AuthenticatedUserIsRequired, +// InvalidJsonFormat, +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val addCommentForViewOnTransaction : OBPEndpoint = { +// //add comment +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "comments" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// commentJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionCommentJSON] } +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// addCommentFunc <- Future(metadata.addComment) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// postedComment <- Future(addCommentFunc(user.userPrimaryKey, viewId, commentJson.value, now)) map { +// unboxFullOrFail(_, callContext, s"Cannot add the comment ${commentJson.value}") +// } +// } yield { +// val successJson = JSONFactory.createTransactionCommentJSON(postedComment) +// (successJson, HttpCode.`201`(callContext)) +// } +// } +// } +// +// // Not able to update a comment (delete and add another) +// +// resourceDocs += ResourceDoc( +// deleteCommentForViewOnTransaction, +// apiVersion, +// "deleteCommentForViewOnTransaction", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/comments/COMMENT_ID", +// "Delete a Transaction Comment", +// """Delete the comment COMMENT_ID about the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). +// | +// |Authentication via OAuth is required. The user must either have owner privileges for this account, or must be the user that posted the comment.""", +// EmptyBody, +// EmptyBody, +// List( +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// AuthenticatedUserIsRequired, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val deleteCommentForViewOnTransaction : OBPEndpoint = { +// //delete comment +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "comments":: commentId :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(user), callContext) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// delete <- Future(metadata.deleteComment(commentId, Full(user), account, view, callContext)) map { +// unboxFullOrFail(_, callContext, "") +// } +// } yield { +// val successJson = SuccessMessage("") +// (successJson, HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getTagsForViewOnTransaction, +// apiVersion, +// "getTagsForViewOnTransaction", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/tags", +// "Get Transaction Tags", +// """Returns the transaction TRANSACTION_ID tags made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). +// Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// transactionTagJSON, +// List( +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError +// ), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val getTagsForViewOnTransaction : OBPEndpoint = { +// //get tags +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "tags" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// tags <- Future(metadata.tags) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// val tagsJson = JSONFactory.createTransactionTagsJSON(tags) +// (tagsJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addTagForViewOnTransaction, +// apiVersion, +// "addTagForViewOnTransaction", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/tags", +// "Add a Transaction Tag", +// s"""Posts a tag about a transaction TRANSACTION_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID. +// | +// |${userAuthenticationMessage(true)} +// | +// |Authentication is required as the tag is linked with the user.""", +// postTransactionTagJSON, +// transactionTagJSON, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val addTagForViewOnTransaction : OBPEndpoint = { +// //add a tag +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "tags" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// tagJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionTagJSON] } +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// addTagFunc <- Future(metadata.addTag) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// postedTag <- Future(addTagFunc(user.userPrimaryKey, viewId, tagJson.value, now)) map { +// unboxFullOrFail(_, callContext, s"Cannot add the tag ${tagJson.value}") +// } +// } yield { +// val successJson = JSONFactory.createTransactionTagJSON(postedTag) +// (successJson, HttpCode.`201`(callContext)) +// } +// } +// } +// +// // No update tag (delete and add another) +// +// resourceDocs += ResourceDoc( +// deleteTagForViewOnTransaction, +// apiVersion, +// "deleteTagForViewOnTransaction", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/tags/TAG_ID", +// "Delete a Transaction Tag", +// """Deletes the tag TAG_ID about the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). +// |Authentication via OAuth is required. The user must either have owner privileges for this account, +// |or must be the user that posted the tag. +// |""".stripMargin, +// EmptyBody, +// EmptyBody, +// List(NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val deleteTagForViewOnTransaction : OBPEndpoint = { +// //delete a tag +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "tags" :: tagId :: Nil JsonDelete _ => { +// +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(user), callContext) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// (bankAccount, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// delete <- Future(metadata.deleteTag(tagId, Full(user), bankAccount, view, callContext)) map { +// unboxFullOrFail(_, callContext, "") +// } +// } yield { +// val successJson = SuccessMessage("") +// (successJson, HttpCode.`204`(cc.callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getImagesForViewOnTransaction, +// apiVersion, +// "getImagesForViewOnTransaction", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/images", +// "Get Transaction Images", +// """Returns the transaction TRANSACTION_ID images made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). +// Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// transactionImagesJSON, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val getImagesForViewOnTransaction : OBPEndpoint = { +// //get images +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "images" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// images <- Future(metadata.images) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// val imagesJson = JSONFactory.createTransactionImagesJSON(images) +// (imagesJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addImageForViewOnTransaction, +// apiVersion, +// "addImageForViewOnTransaction", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/images", +// "Add a Transaction Image", +// s"""Posts an image about a transaction TRANSACTION_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID. +// | +// |${userAuthenticationMessage(true) } +// | +// |The image is linked with the user.""", +// postTransactionImageJSON, +// transactionImageJSON, +// List( +// InvalidJsonFormat, +// BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// InvalidUrl, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction) +// ) +// +// lazy val addImageForViewOnTransaction : OBPEndpoint = { +// //add an image +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "images" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// imageJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionImageJSON] } +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(u), callContext) +// addImageFunc <- Future(metadata.addImage) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// url <- NewStyle.function.tryons(s"$InvalidUrl Could not parse url string as a valid URL", 400, callContext) { new URL(imageJson.URL) } +// postedImage <- Future(addImageFunc(u.userPrimaryKey, viewId, imageJson.label, now, url.toString)) map { +// unboxFullOrFail(_, callContext, s"Cannot add the tag ${imageJson.label}") +// } +// } yield { +// val successJson = JSONFactory.createTransactionImageJSON(postedImage) +// (successJson, HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteImageForViewOnTransaction, +// apiVersion, +// "deleteImageForViewOnTransaction", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/images/IMAGE_ID", +// "Delete a Transaction Image", +// """Deletes the image IMAGE_ID about the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). +// | +// |Authentication via OAuth is required. The user must either have owner privileges for this account, or must be the user that posted the image.""", +// EmptyBody, +// EmptyBody, +// List( +// BankAccountNotFound, +// NoViewPermission, +// AuthenticatedUserIsRequired, +// "You must be able to see images in order to delete them", +// "Image not found for this transaction", +// "Deleting images not permitted for this view", +// "Deleting images not permitted for the current user", +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val deleteImageForViewOnTransaction : OBPEndpoint = { +// //delete an image +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "images" :: imageId :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(user), callContext) +// (account, _) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// delete <- Future(metadata.deleteImage(imageId, Full(user), account, view, callContext)) map { +// unboxFullOrFail(_, callContext, "") +// } +// } yield { +// val successJson = SuccessMessage("") +// (successJson, HttpCode.`204`(cc.callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getWhereTagForViewOnTransaction, +// apiVersion, +// "getWhereTagForViewOnTransaction", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", +// "Get a Transaction where Tag", +// """Returns the "where" Geo tag added to the transaction TRANSACTION_ID made on a [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). +// |It represents the location where the transaction has been initiated. +// | +// |Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// transactionWhereJSON, +// List(BankAccountNotFound, +// NoViewPermission, +// ViewNotFound, +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val getWhereTagForViewOnTransaction : OBPEndpoint = { +// //get where tag +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// where <- Future(metadata.whereTag) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_see_owner_comment. Current ViewId($viewId)") +// } +// } yield { +// val json = JSONFactory.createLocationJSON(where) +// val whereJson = TransactionWhereJSON(json) +// (whereJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addWhereTagForViewOnTransaction, +// apiVersion, +// "addWhereTagForViewOnTransaction", +// "POST", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", +// "Add a Transaction where Tag", +// s"""Creates a "where" Geo tag on a transaction TRANSACTION_ID in a [view](#1_2_1-getViewsForBankAccount). +// | +// |${userAuthenticationMessage(true)} +// | +// |The geo tag is linked with the user.""", +// postTransactionWhereJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// ViewNotFound, +// NoViewPermission, +// "Coordinates not possible", +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val addWhereTagForViewOnTransaction : OBPEndpoint = { +// //add where tag +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonPost json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// addWhereTag <- Future(metadata.addWhereTag) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_where_tag. Current ViewId($viewId)") +// } +// whereJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionWhereJSON] } +// correctCoordinates <- Future(checkIfLocationPossible(whereJson.where.latitude, whereJson.where.longitude)) map { +// unboxFullOrFail(_, callContext, "Coordinates not possible") +// } +// if(addWhereTag(user.userPrimaryKey, viewId, now, whereJson.where.longitude, whereJson.where.latitude)) +// } yield { +// val successJson = SuccessMessage("where tag added") +// (successJson, HttpCode.`201`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// updateWhereTagForViewOnTransaction, +// apiVersion, +// "updateWhereTagForViewOnTransaction", +// "PUT", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", +// "Update a Transaction where Tag", +// s"""Updates the "where" Geo tag on a transaction TRANSACTION_ID in a [view](#1_2_1-getViewsForBankAccount). +// | +// |${userAuthenticationMessage(true)} +// | +// |The geo tag is linked with the user.""", +// postTransactionWhereJSON, +// successMessage, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// InvalidJsonFormat, +// ViewNotFound, +// NoViewPermission, +// "Coordinates not possible", +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val updateWhereTagForViewOnTransaction : OBPEndpoint = { +// //update where tag +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonPut json -> _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, Full(user), callContext) +// addWhereTag <- Future(metadata.addWhereTag) map { +// unboxFullOrFail(_, callContext, s"$NoViewPermission can_add_where_tag. Current ViewId($viewId)") +// } +// whereJson <- NewStyle.function.tryons(InvalidJsonFormat, 400, callContext) { json.extract[PostTransactionWhereJSON] } +// correctCoordinates <- Future(checkIfLocationPossible(whereJson.where.latitude, whereJson.where.longitude)) map { +// unboxFullOrFail(_, callContext, "Coordinates not possible") +// } +// if(addWhereTag(user.userPrimaryKey, viewId, now, whereJson.where.longitude, whereJson.where.latitude)) +// } yield { +// val successJson = SuccessMessage("where tag updated") +// (successJson, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// deleteWhereTagForViewOnTransaction, +// apiVersion, +// "deleteWhereTagForViewOnTransaction", +// "DELETE", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/metadata/where", +// "Delete a Transaction Tag", +// s"""Deletes the where tag of the transaction TRANSACTION_ID made on [view](#1_2_1-getViewsForBankAccount). +// | +// |${userAuthenticationMessage(true)} +// | +// |The user must either have owner privileges for this account, or must be the user that posted the geo tag.""", +// EmptyBody, +// EmptyBody, +// List( +// AuthenticatedUserIsRequired, +// BankAccountNotFound, +// NoViewPermission, +// AuthenticatedUserIsRequired, +// ViewNotFound, +// "there is no tag to delete", +// "Delete not completed", +// UnknownError), +// List(apiTagTransactionMetaData, apiTagTransaction)) +// +// lazy val deleteWhereTagForViewOnTransaction : OBPEndpoint = { +// //delete where tag +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions" :: TransactionId(transactionId) :: "metadata" :: "where" :: Nil JsonDelete _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (user, callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), user, callContext) +// metadata <- moderatedTransactionMetadataFuture(bankId, accountId, viewId, transactionId, user, callContext) +// delete <- Future(metadata.deleteWhereTag(viewId, user, account, view, callContext)) map { +// unboxFullOrFail(_, callContext, "Delete not completed") +// } +// } yield { +// val successJson = SuccessMessage("") +// (successJson, HttpCode.`204`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getOtherAccountForTransaction, +// apiVersion, +// "getOtherAccountForTransaction", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transactions/TRANSACTION_ID/other_account", +// "Get Other Account of Transaction", +// """Get other account of a transaction. +// |Returns details of the other party involved in the transaction, moderated by the [view](#1_2_1-getViewsForBankAccount) (VIEW_ID). +// Authentication via OAuth is required if the view is not public.""", +// EmptyBody, +// otherAccountJSON, +// List(BankAccountNotFound, UnknownError), +// List(apiTagTransaction, apiTagCounterparty)) +// +// lazy val getOtherAccountForTransaction : OBPEndpoint = { +// //get other account of a transaction +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transactions":: TransactionId(transactionId) :: "other_account" :: Nil JsonGet req => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (account, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(bankId, accountId), Some(u), callContext) +// (moderatedTransaction, callContext) <- account.moderatedTransactionFuture(transactionId, view, Full(u), callContext) map { +// unboxFullOrFail(_, callContext, GetTransactionsException) +// } +// _ <- NewStyle.function.tryons(GetTransactionsException, 400, callContext) { +// moderatedTransaction.otherBankAccount.isDefined +// } +// } yield { +// val otherBankAccountJson = JSONFactory.createOtherBankAccount(moderatedTransaction.otherBankAccount.get) +// (otherBankAccountJson, HttpCode.`200`(callContext)) +// } +// +// } +// } +// +// } +//} +// +//object APIMethods121 { +//} diff --git a/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala b/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala index 3ccd0ec214..d4418bb940 100644 --- a/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala +++ b/obp-api/src/main/scala/code/api/v1_3_0/APIMethods130.scala @@ -3,3 +3,125 @@ package code.api.v1_3_0 import net.liftweb.http.rest.RestHelper trait APIMethods130 { self: RestHelper => } + +// +//package code.api.v1_3_0 +// +//import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ +//import code.api.util.APIUtil._ +//import code.api.util.ApiTag._ +//import code.api.util.ErrorMessages._ +//import code.api.util.FutureUtil.EndpointContext +//import code.api.util.NewStyle.HttpCode +//import code.api.util.ApiRole._ +//import code.api.util.{ApiRole, NewStyle} +//import code.api.v1_2_1.JSONFactory +//import com.openbankproject.commons.ExecutionContext.Implicits.global +//import com.openbankproject.commons.model.BankId +//import com.openbankproject.commons.util.ApiVersion +//import net.liftweb.common.Full +//import net.liftweb.http.rest.RestHelper +// +//import scala.collection.mutable.ArrayBuffer +//import scala.concurrent.Future +// +//trait APIMethods130 { +// //needs to be a RestHelper to get access to JsonGet, JsonPost, etc. +// self: RestHelper => +// +// val Implementations1_3_0 = new Object(){ +// +// val resourceDocs = ArrayBuffer[ResourceDoc]() +// val apiVersion = ApiVersion.v1_3_0 // was String "1_3_0" +// +// +// resourceDocs += ResourceDoc( +// root, +// apiVersion, +// "root", +// "GET", +// "/root", +// "Get API Info (root)", +// """Returns information about: +// | +// |* API version +// |* Hosted by information +// |* Git Commit""", +// EmptyBody, +// apiInfoJSON, +// List(UnknownError, MandatoryPropertyIsNotSet), +// apiTagApi :: Nil) +// +// lazy val root : OBPEndpoint = { +// case (Nil | "root" :: Nil) JsonGet _ => { +// cc => +// implicit val ec = EndpointContext(Some(cc)) +// for { +// _ <- Future(()) // Just start async call +// } yield { +// (JSONFactory.getApiInfoJSON(OBPAPI1_3_0.version, OBPAPI1_3_0.versionStatus), HttpCode.`200`(cc.callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getCards, +// apiVersion, +// "getCards", +// "GET", +// "/cards", +// "Get cards for the current user", +// "Returns data about all the physical cards a user has been issued. These could be debit cards, credit cards, etc.", +// EmptyBody, +// physicalCardsJSON, +// List(AuthenticatedUserIsRequired, UnknownError), +// List(apiTagCard)) +// +// lazy val getCards : OBPEndpoint = { +// case "cards" :: Nil JsonGet _ => { +// cc => { +// implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (cards,callContext) <- NewStyle.function.getPhysicalCardsForUser(u, callContext) +// } yield { +// (JSONFactory1_3_0.createPhysicalCardsJSON(cards, u), HttpCode.`200`(callContext)) +// } +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// getCardsForBank, +// apiVersion, +// "getCardsForBank", +// "GET", +// "/banks/BANK_ID/cards", +// "Get cards for the specified bank", +// "", +// EmptyBody, +// physicalCardsJSON, +// List(AuthenticatedUserIsRequired,BankNotFound, UnknownError), +// List(apiTagCard), +// Some(List(canGetCardsForBank))) +// +// lazy val getCardsForBank : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "cards" :: Nil JsonGet _ => { +// cc => { +// implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// httpParams <- NewStyle.function.extractHttpParamsFromUrl(cc.url) +// (obpQueryParams, callContext) <- createQueriesByHttpParamsFuture(httpParams, callContext) +// _ <- NewStyle.function.hasEntitlement(bankId.value, u.userId, ApiRole.canGetCardsForBank, callContext) +// (bank, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (cards, callContext) <- NewStyle.function.getPhysicalCardsForBank(bank, u, obpQueryParams, callContext) +// } yield { +// (JSONFactory1_3_0.createPhysicalCardsJSON(cards, u), HttpCode.`200`(callContext)) +// } +// } +// } +// } +// } +//} diff --git a/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala b/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala index 3ab8787c66..f356ac1839 100644 --- a/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala +++ b/obp-api/src/main/scala/code/api/v1_4_0/APIMethods140.scala @@ -6,3 +6,560 @@ trait APIMethods140 { self: RestHelper => } object APIMethods140 extends RestHelper with APIMethods140 { val Implementations1_4_0 = Http4s140.Implementations1_4_0 } +// +//package code.api.v1_4_0 +// +//import scala.language.reflectiveCalls +//import code.api.Constant._ +//import code.api.util.ApiRole._ +//import code.api.util.ApiTag._ +//import code.api.util.FutureUtil.EndpointContext +//import code.api.util.NewStyle.HttpCode +//import code.api.util._ +//import code.api.util.newstyle.ViewNewStyle +//import code.api.v1_2_1.JSONFactory +//import code.api.v1_4_0.JSONFactory1_4_0._ +//import code.api.v2_0_0.CreateCustomerJson +//import code.atms.Atms +//import code.bankconnectors.Connector +//import code.branches.Branches +//import code.customer.CustomerX +//import code.usercustomerlinks.UserCustomerLink +//import code.util.Helper +//import code.views.system.ViewPermission +//import com.github.dwickern.macros.NameOf.nameOf +//import com.openbankproject.commons.model._ +//import com.openbankproject.commons.util.ApiVersion +//import net.liftweb.common.{Box, Full} +//import net.liftweb.http.rest.RestHelper +//import net.liftweb.json.Extraction +//import net.liftweb.json.JsonAST.JValue +//import net.liftweb.util.Helpers.tryo +//import net.liftweb.util.Props +// +//import scala.collection.immutable.{List, Nil} +//import scala.concurrent.Future +// +//// JObject creation +//import code.api.APIFailure +//import code.api.v1_2_1.{APIInfoJSON, APIMethods121, HostedBy} +//import code.api.v1_3_0.APIMethods130 +// +//import scala.collection.mutable.ArrayBuffer +////import code.api.v2_0_0.{OBPAPI2_0_0, APIMethods200} +// +//// So we can include resource docs from future versions +////import code.api.v1_4_0.JSONFactory1_4_0._ +//import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._ +//import code.api.util.APIUtil._ +//import code.api.util.ErrorMessages +//import code.api.util.ErrorMessages._ +//import code.customer.CustomerMessages +//import code.model._ +//import code.products.Products +//import code.util.Helper._ +//import com.openbankproject.commons.ExecutionContext.Implicits.global +// +//trait APIMethods140 extends MdcLoggable with APIMethods130 with APIMethods121{ +// //needs to be a RestHelper to get access to JsonGet, JsonPost, etc. +// // We add previous APIMethods so we have access to the Resource Docs +// self: RestHelper => +// +// val Implementations1_4_0 = new Object() { +// +// val resourceDocs = ArrayBuffer[ResourceDoc]() +// val apiVersion = ApiVersion.v1_4_0 // was noV i.e. "1_4_0" +// val apiVersionStatus : String = "STABLE" +// +// +// resourceDocs += ResourceDoc( +// root, +// apiVersion, +// "root", +// "GET", +// "/root", +// "Get API Info (root)", +// """Returns information about: +// | +// |* API version +// |* Hosted by information +// |* Git Commit""", +// EmptyBody, +// apiInfoJSON, +// List(UnknownError, MandatoryPropertyIsNotSet), +// apiTagApi :: Nil) +// +// lazy val root : OBPEndpoint = { +// case (Nil | "root" :: Nil) JsonGet _ => { +// cc => +// implicit val ec = EndpointContext(Some(cc)) +// for { +// _ <- Future(()) // Just start async call +// } yield { +// (JSONFactory.getApiInfoJSON(OBPAPI1_4_0.version, OBPAPI1_4_0.versionStatus), HttpCode.`200`(cc.callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getCustomer, +// apiVersion, +// "getCustomer", +// "GET", +// "/banks/BANK_ID/customer", +// "Get customer for logged in user", +// """Information about the currently authenticated user. +// | +// |Authentication via OAuth is required.""", +// EmptyBody, +// customerJsonV140, +// List(AuthenticatedUserIsRequired, UnknownError), +// List(apiTagCustomer, apiTagOldStyle)) +// +// lazy val getCustomer : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "customer" :: Nil JsonGet _ => { +// cc => { +// for { +// u <- cc.user ?~! ErrorMessages.AuthenticatedUserIsRequired +// (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} +// ucls <- tryo{UserCustomerLink.userCustomerLink.vend.getUserCustomerLinksByUserId(u.userId)} ?~! ErrorMessages.UserCustomerLinksNotFoundForUser +// ucl <- tryo{ucls.find(x=>CustomerX.customerProvider.vend.getBankIdByCustomerId(x.customerId) == bankId.value)} +// _ <- booleanToBox(ucl.size > 0, ErrorMessages.UserCustomerLinksNotFoundForUser) +// u <- ucl +// info <- CustomerX.customerProvider.vend.getCustomerByCustomerId(u.customerId) ?~! ErrorMessages.CustomerNotFoundByCustomerId +// } yield { +// val json = JSONFactory1_4_0.createCustomerJson(info) +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// getCustomersMessages, +// apiVersion, +// "getCustomersMessages", +// "GET", +// "/banks/BANK_ID/customer/messages", +// "Get Customer Messages for all Customers", +// """Get messages for the logged in customer +// |Messages sent to the currently authenticated user. +// | +// |Authentication via OAuth is required.""", +// EmptyBody, +// customerMessagesJson, +// List(AuthenticatedUserIsRequired, UnknownError), +// List(apiTagMessage, apiTagCustomer)) +// +// lazy val getCustomersMessages : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "customer" :: "messages" :: Nil JsonGet _ => { +// cc => { +// implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// //au <- ResourceUser.find(By(ResourceUser.id, u.apiId)) +// //role <- au.isCustomerMessageAdmin ~> APIFailure("User does not have sufficient permissions", 401) +// } yield { +// val messages = CustomerMessages.customerMessageProvider.vend.getMessages(u, bankId) +// val json = JSONFactory1_4_0.createCustomerMessagesJson(messages) +// (json, HttpCode.`200`(callContext)) +// } +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addCustomerMessage, +// apiVersion, +// nameOf(addCustomerMessage), +// "POST", +// "/banks/BANK_ID/customer/CUSTOMER_ID/messages", +// "Create Customer Message", +// "Create a message for the customer specified by CUSTOMER_ID", +// // We use Extraction.decompose to convert to json +// addCustomerMessageJson, +// successMessage, +// List(AuthenticatedUserIsRequired, UnknownError), +// List(apiTagMessage, apiTagCustomer, apiTagPerson) +// ) +// +// // TODO Add Role +// +// lazy val addCustomerMessage : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "customer" :: customerId :: "messages" :: Nil JsonPost json -> _ => { +// cc =>{ +// implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(user), callContext) <- authenticatedAccess(cc) +// failMsg = s"$InvalidJsonFormat The Json body should be the $AddCustomerMessageJson " +// postedData <- NewStyle.function.tryons(failMsg, 400, callContext) { +// json.extract[AddCustomerMessageJson] +// } +// (_, callContext) <- NewStyle.function.getBank(bankId, callContext) +// (_, callContext) <- NewStyle.function.getCustomerByCustomerId(customerId, callContext) +// (userCustomerLink, callContext) <- NewStyle.function.getUserCustomerLinkByCustomerId(customerId, callContext) +// (user, callContext) <- NewStyle.function.findByUserId(userCustomerLink.userId, callContext) +// (_, callContext)<- NewStyle.function.createMessage(user, bankId, postedData.message, postedData.from_department, postedData.from_person, callContext) +// +// } yield { +// (successMessage, HttpCode.`201`(callContext)) +// } +// } +// } +// } +// +// +// val getBranchesIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getBranchesIsPublic", true) +// +// resourceDocs += ResourceDoc( +// getBranches, +// apiVersion, +// "getBranches", +// "GET", +// "/banks/BANK_ID/branches", +// "Get Bank Branches", +// s"""Returns information about branches for a single bank specified by BANK_ID including: +// | +// |* Name +// |* Address +// |* Geo Location +// |* License the data under this endpoint is released under +// | +// ${urlParametersDocument(false, false)} +// | +// |You can use the url query parameters *limit* and *offset* for pagination +// | +// |${userAuthenticationMessage(!getBranchesIsPublic)}""".stripMargin, +// EmptyBody, +// branchesJson, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// "No branches available. License may not be set.", +// UnknownError), +// List(apiTagBranch, apiTagOldStyle) +// ) +// +// lazy val getBranches : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "branches" :: Nil JsonGet req => { +// cc =>{ +// for { +// _ <- if(getBranchesIsPublic) +// Box(Some(1)) +// else +// cc.user ?~! AuthenticatedUserIsRequired +// (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} +// // Get branches from the active provider +// httpParams <- createHttpParamsByUrl(cc.url) +// obpQueryParams <- createQueriesByHttpParams(httpParams) +// branches <- Box(Branches.branchesProvider.vend.getBranches(bankId, obpQueryParams)) ~> APIFailure("No branches available. License may not be set.", 204) +// } yield { +// // Format the data as json +// val json = JSONFactory1_4_0.createBranchesJson(branches) +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// } +// +// +// val getAtmsIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getAtmsIsPublic", true) +// +// resourceDocs += ResourceDoc( +// getAtms, +// apiVersion, +// "getAtms", +// "GET", +// "/banks/BANK_ID/atms", +// "Get Bank ATMS", +// s"""Returns information about ATMs for a single bank specified by BANK_ID including: +// | +// |* Address +// |* Geo Location +// |* License the data under this endpoint is released under +// | +// | +// |${urlParametersDocument(false,false)} +// | +// |${userAuthenticationMessage(!getAtmsIsPublic)}""".stripMargin, +// EmptyBody, +// atmsJson, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// "No ATMs available. License may not be set.", +// UnknownError), +// List(apiTagBank, apiTagOldStyle) +// ) +// +// lazy val getAtms : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "atms" :: Nil JsonGet req => { +// cc =>{ +// for { +// // Get atms from the active provider +// +// _ <- if(getAtmsIsPublic) +// Box(Some(1)) +// else +// cc.user ?~! AuthenticatedUserIsRequired +// (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} +// +// httpParams <- createHttpParamsByUrl(cc.url) +// obpQueryParams <- createQueriesByHttpParams(httpParams) +// atms <- Box(Atms.atmsProvider.vend.getAtms(bankId, obpQueryParams)) ~> APIFailure("No ATMs available. License may not be set.", 204) +// } yield { +// // Format the data as json +// val json = JSONFactory1_4_0.createAtmsJson(atms) +// // Return +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// } +// +// +// val getProductsIsPublic = APIUtil.getPropsAsBoolValue("apiOptions.getProductsIsPublic", true) +// +// +// resourceDocs += ResourceDoc( +// getProducts, +// apiVersion, +// "getProducts", +// "GET", +// "/banks/BANK_ID/products", +// "Get Bank Products", +// s"""Returns information about the financial products offered by a bank specified by BANK_ID including: +// | +// |* Name +// |* Code +// |* Category +// |* Family +// |* Super Family +// |* More info URL +// |* Description +// |* Terms and Conditions +// |* License the data under this endpoint is released under +// |${userAuthenticationMessage(!getProductsIsPublic)}""".stripMargin, +// EmptyBody, +// productsJson, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// "No products available.", +// "License may not be set.", +// UnknownError), +// List(apiTagBank, apiTagOldStyle) +// ) +// +// lazy val getProducts : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "products" :: Nil JsonGet _ => { +// cc =>{ +// for { +// // Get products from the active provider +// _ <- if(getProductsIsPublic) +// Box(Some(1)) +// else +// cc.user ?~! AuthenticatedUserIsRequired +// (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} +// products <- Box(Products.productsProvider.vend.getProducts(bankId)) ~> APIFailure("No products available. License may not be set.", 204) +// } yield { +// // Format the data as json +// val json = JSONFactory1_4_0.createProductsJson(products) +// // Return +// successJsonResponse(Extraction.decompose(json)) +// } +// } +// } +// } +// +// +// resourceDocs += ResourceDoc( +// getCrmEvents, +// apiVersion, +// "getCrmEvents", +// "GET", +// "/banks/BANK_ID/crm-events", +// "Get CRM Events", +// "", +// EmptyBody, +// crmEventsJson, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// "No CRM Events available.", +// UnknownError), +// List(apiTagCustomer) +// ) +// +// // TODO Require Role +// +// lazy val getCrmEvents : OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "crm-events" :: Nil JsonGet _ => { +// cc => { +// implicit val ec = EndpointContext(Some(cc)) +// for { +// (_, callContext) <- authenticatedAccess(cc) +// (bank, callContext ) <- NewStyle.function.getBank(bankId, callContext) +// crmEvents <- NewStyle.function.getCrmEvents(bank.bankId, callContext) +// } yield { +// val json = JSONFactory1_4_0.createCrmEventsJson(crmEvents) +// (json, HttpCode.`200`(callContext)) +// } +// } +// } +// } +// +// /* +// transaction requests (new payments since 1.4.0) +// */ +// +// resourceDocs += ResourceDoc( +// getTransactionRequestTypes, +// apiVersion, +// "getTransactionRequestTypes", +// "GET", +// "/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/transaction-request-types", +// "Get Transaction Request Types for Account", +// """Returns the Transaction Request Types that the account specified by ACCOUNT_ID and view specified by VIEW_ID has access to. +// | +// |These are the ways this API Server can create a Transaction via a Transaction Request +// |(as opposed to Transaction Types which include external types too e.g. for Transactions created by core banking etc.) +// | +// | A Transaction Request Type internally determines: +// | +// | * the required Transaction Request 'body' i.e. fields that define the 'what' and 'to' of a Transaction Request, +// | * the type of security challenge that may be be raised before the Transaction Request proceeds, and +// | * the threshold of that challenge. +// | +// | For instance in a 'SANDBOX_TAN' Transaction Request, for amounts over 1000 currency units, the user must supply a positive integer to complete the Transaction Request and create a Transaction. +// | +// | This approach aims to provide only one endpoint for initiating transactions, and one that handles challenges, whilst still allowing flexibility with the payload and internal logic. +// | +// """.stripMargin, +// EmptyBody, +// transactionRequestTypesJsonV140, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// AccountNotFound, +// "Please specify a valid value for CURRENCY of your Bank Account. " +// ,"Current user does not have access to the view ", +// "account not found at bank", +// "user does not have access to owner view", +// TransactionRequestsNotEnabled, +// UnknownError), +// List(apiTagTransactionRequest, apiTagPSD2PIS, apiTagPsd2)) +// +// lazy val getTransactionRequestTypes: OBPEndpoint = { +// case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "transaction-request-types" :: +// Nil JsonGet _ => { +// cc => implicit val ec = EndpointContext(Some(cc)) +// for { +// (Full(u), callContext) <- authenticatedAccess(cc) +// _ <- NewStyle.function.isEnabledTransactionRequests(callContext) +// (bank, callContext ) <- NewStyle.function.getBank(bankId, callContext) +// (fromAccount, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext) +// failMsg = ErrorMessages.InvalidISOCurrencyCode.concat("Please specify a valid value for CURRENCY of your Bank Account. ") +// _ <- NewStyle.function.isValidCurrencyISOCode(fromAccount.currency, failMsg, callContext) +// view <- ViewNewStyle.checkViewAccessAndReturnView(viewId, BankIdAccountId(fromAccount.bankId, fromAccount.accountId), Some(u), callContext) +// _ <- Helper.booleanToFuture( +// s"${ErrorMessages.ViewDoesNotPermitAccess} You need the `${(CAN_SEE_TRANSACTION_REQUEST_TYPES)}` permission on the View(${viewId.value} )", +// cc = callContext +// ) { +// ViewPermission.findViewPermissions(view).exists(_.permission.get == CAN_SEE_TRANSACTION_REQUEST_TYPES) +// } +// // TODO: Consider storing allowed_transaction_request_types (List of String) in View Definition. +// // TODO: This would allow us to restrict transaction request types available to the User for an Account +// (transactionRequestTypes, callContext) <- Future(Connector.connector.vend.getTransactionRequestTypes(u, fromAccount, callContext)) map { +// connectorEmptyResponse(_, callContext) +// } +// (transactionRequestTypeCharges, callContext) <- NewStyle.function.getTransactionRequestTypeCharges(bankId, accountId, viewId, transactionRequestTypes, callContext) +// } yield { +// val json = JSONFactory1_4_0.createTransactionRequestTypesJSONs(transactionRequestTypeCharges) +// (json, HttpCode.`200`(callContext)) +// } +// } +// } +// +// resourceDocs += ResourceDoc( +// addCustomer, +// apiVersion, +// "addCustomer", +// "POST", +// "/banks/BANK_ID/customer", +// "Add a customer.", +// s"""Add a customer linked to the currently authenticated user. +// |The Customer resource stores the customer number, legal name, email, phone number, their date of birth, relationship status, education attained, a url for a profile image, KYC status etc. +// |This call may require additional permissions/role in the future. +// |For now the authenticated user can create at most one linked customer. +// |Dates need to be in the format 2013-01-21T23:08:00Z +// |${userAuthenticationMessage(true) } +// |Note: This call is depreciated in favour of v.2.0.0 createCustomer +// |""", +// code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createCustomerJson, +// customerJsonV140, +// List( +// AuthenticatedUserIsRequired, +// BankNotFound, +// InvalidJsonFormat, +// "entitlements required", +// CustomerNumberAlreadyExists, +// "Problem getting user_id", +// UserNotFoundById, +// "Could not create customer", +// "Could not create user_customer_links", +// UnknownError), +// List(apiTagCustomer, apiTagOldStyle), +// Some(List(canCreateCustomer, canCreateUserCustomerLink))) +// +// lazy val addCustomer : OBPEndpoint = { +// //updates a view on a bank account +// case "banks" :: BankId(bankId) :: "customer" :: Nil JsonPost json -> _ => { +// cc => +// for { +// u <- cc.user ?~! "User must be logged in to post Customer" +// (bank, callContext ) <- BankX(bankId, Some(cc)) ?~! {ErrorMessages.BankNotFound} +// postedData <- tryo{json.extract[CreateCustomerJson]} ?~! ErrorMessages.InvalidJsonFormat +// requiredEntitlements = ApiRole.canCreateCustomer :: ApiRole.canCreateUserCustomerLink :: Nil +// _ <- NewStyle.function.hasAllEntitlements(bankId.value, u.userId, requiredEntitlements, callContext) +// _ <- tryo(assert(CustomerX.customerProvider.vend.checkCustomerNumberAvailable(bankId, postedData.customer_number) == true)) ?~! ErrorMessages.CustomerNumberAlreadyExists +// user_id <- tryo{if (postedData.user_id.nonEmpty) postedData.user_id else u.userId} ?~ s"Problem getting user_id" +// _ <- UserX.findByUserId(user_id) ?~! ErrorMessages.UserNotFoundById +// customer <- CustomerX.customerProvider.vend.addCustomer(bankId, +// postedData.customer_number, +// postedData.legal_name, +// postedData.mobile_phone_number, +// postedData.email, +// CustomerFaceImage(postedData.face_image.date, postedData.face_image.url), +// postedData.date_of_birth, +// postedData.relationship_status, +// postedData.dependants, +// postedData.dob_of_dependants, +// postedData.highest_education_attained, +// postedData.employment_status, +// postedData.kyc_status, +// postedData.last_ok_date, +// None, +// None, +// "", +// "", +// "" +// ) ?~! "Could not create customer" +// _ <- UserCustomerLink.userCustomerLink.vend.createUserCustomerLink(user_id, customer.customerId, DateWithMsExampleObject, true) ?~! "Could not create user_customer_links" +// } yield { +// val successJson = JSONFactory1_4_0.createCustomerJson(customer) +// successJsonResponse(Extraction.decompose(successJson)) +// } +// } +// } +// +// +// +// // `testResourceDoc` (dev-mode-only `GET /dummy` stub) deleted in the auth-stack / +// // bridge-removal cleanup sweep. It returned a dummy `APIInfoJSON`, had no production +// // behaviour, and its sole purpose was exercising the resource-doc renderer's +// // description-markdown handling — covered today by real endpoints. +// +// } +//}