mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 18:46:46 +00:00
Account Tags - WIP
This commit is contained in:
parent
ea9aaad170
commit
9309842e02
@ -1,19 +1,21 @@
|
||||
package code.api.v4_0_0
|
||||
|
||||
import code.api.ChargePolicy
|
||||
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.{AccountNotFound, AllowedAttemptsUsedUp, BankNotFound, CounterpartyBeneficiaryPermit, InsufficientAuthorisationToCreateTransactionRequest, InvalidAccountIdFormat, InvalidBankIdFormat, InvalidChallengeAnswer, InvalidChallengeType, InvalidChargePolicy, InvalidISOCurrencyCode, InvalidJsonFormat, InvalidNumber, InvalidTransactionRequesChallengeId, InvalidTransactionRequestCurrency, InvalidTransactionRequestType, NotPositiveAmount, TransactionDisabled, TransactionRequestStatusNotInitiated, TransactionRequestTypeHasChanged, UnknownError, UserHasMissingRoles, UserNoPermissionAccessView, UserNotLoggedIn, ViewNotFound}
|
||||
import code.api.util.ErrorMessages.{AccountNotFound, AllowedAttemptsUsedUp, BankAccountNotFound, BankNotFound, CounterpartyBeneficiaryPermit, InsufficientAuthorisationToCreateTransactionRequest, InvalidAccountIdFormat, InvalidBankIdFormat, InvalidChallengeAnswer, InvalidChallengeType, InvalidChargePolicy, InvalidISOCurrencyCode, InvalidJsonFormat, InvalidNumber, InvalidTransactionRequesChallengeId, InvalidTransactionRequestCurrency, InvalidTransactionRequestType, NoViewPermission, NotPositiveAmount, TransactionDisabled, TransactionRequestStatusNotInitiated, TransactionRequestTypeHasChanged, UnknownError, UserHasMissingRoles, UserNoPermissionAccessView, UserNotLoggedIn, ViewNotFound}
|
||||
import code.api.util.ExampleValue.{dynamicEntityRequestBodyExample, dynamicEntityResponseBodyExample}
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.api.util._
|
||||
import code.api.v1_2_1.{JSONFactory, PostTransactionTagJSON}
|
||||
import code.api.v1_4_0.JSONFactory1_4_0.{ChallengeAnswerJSON, TransactionRequestAccountJsonV140}
|
||||
import code.api.v2_0_0.{EntitlementJSON, EntitlementJSONs, JSONFactory200}
|
||||
import code.api.v2_1_0._
|
||||
import code.api.v3_1_0.ListResult
|
||||
import code.api.{APIFailureNewStyle, ChargePolicy}
|
||||
import code.dynamicEntity.DynamicEntityCommons
|
||||
import code.metadata.tags.Tags
|
||||
import code.model.dataAccess.AuthUser
|
||||
import code.model.toUserExtended
|
||||
import code.transactionrequests.TransactionRequests.TransactionChallengeTypes._
|
||||
@ -28,6 +30,7 @@ import net.liftweb.common.{Box, Full, ParamFailure}
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import net.liftweb.json.Serialization.write
|
||||
import net.liftweb.json._
|
||||
import net.liftweb.util.Helpers.now
|
||||
import net.liftweb.util.StringHelpers
|
||||
import org.atteo.evo.inflector.English
|
||||
|
||||
@ -35,10 +38,6 @@ import scala.collection.immutable.{List, Nil}
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.v2_0_0.{EntitlementJSON, EntitlementJSONs, JSONFactory200}
|
||||
import code.api.v3_0_0.JSONFactory300
|
||||
import code.entitlement.Entitlement
|
||||
import code.views.Views
|
||||
|
||||
trait APIMethods400 {
|
||||
self: RestHelper =>
|
||||
@ -1090,6 +1089,98 @@ trait APIMethods400 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resourceDocs += ResourceDoc(
|
||||
addTagForViewOnAccount,
|
||||
implementedInApiVersion,
|
||||
"addTagForViewOnAccount",
|
||||
"POST",
|
||||
"/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/metadata/tags",
|
||||
"Add a tag.",
|
||||
s"""Posts a tag about an account ACCOUNT_ID on a [view](#1_2_1-getViewsForBankAccount) VIEW_ID.
|
||||
|
|
||||
|${authenticationRequiredMessage(true)}
|
||||
|
|
||||
|Authentication is required as the tag is linked with the user.""",
|
||||
postTransactionTagJSON,
|
||||
transactionTagJSON,
|
||||
List(
|
||||
UserNotLoggedIn,
|
||||
BankAccountNotFound,
|
||||
InvalidJsonFormat,
|
||||
NoViewPermission,
|
||||
ViewNotFound,
|
||||
UnknownError),
|
||||
Catalogs(notCore, notPSD2, notOBWG),
|
||||
List(apiTagAccount))
|
||||
|
||||
lazy val addTagForViewOnAccount : OBPEndpoint = {
|
||||
//add a tag
|
||||
case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "metadata" :: "tags" :: Nil JsonPost json -> _ => {
|
||||
cc =>
|
||||
for {
|
||||
(Full(u), callContext) <- authorizedAccess(cc)
|
||||
(_, callContext) <- NewStyle.function.getBank(bankId, callContext)
|
||||
(_, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext)
|
||||
view <- NewStyle.function.view(viewId, BankIdAccountId(bankId, accountId), callContext)
|
||||
_ <- NewStyle.function.hasViewAccess(view, u)
|
||||
_ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_add_tag. Current ViewId($viewId)") {
|
||||
view.canAddTag
|
||||
}
|
||||
tagJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PostTransactionTagJSON ", 400, callContext) {
|
||||
json.extract[PostTransactionTagJSON]
|
||||
}
|
||||
(postedTag, callContext) <- Future(Tags.tags.vend.addTagOnAccount(bankId, accountId)(u.userPrimaryKey, viewId, tagJson.value, now)) map {
|
||||
i => (connectorEmptyResponse(i, callContext), callContext)
|
||||
}
|
||||
} yield {
|
||||
(JSONFactory.createTransactionTagJSON(postedTag), HttpCode.`201`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resourceDocs += ResourceDoc(
|
||||
deleteTagForViewOnAccount,
|
||||
implementedInApiVersion,
|
||||
"deleteTagForViewOnAccount",
|
||||
"DELETE",
|
||||
"/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/metadata/tags/TAG_ID",
|
||||
"Delete a tag.",
|
||||
"""Deletes the tag TAG_ID about the account ACCOUNT_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,
|
||||
emptyObjectJson,
|
||||
emptyObjectJson,
|
||||
List(NoViewPermission,
|
||||
ViewNotFound,
|
||||
UnknownError),
|
||||
Catalogs(notCore, notPSD2, notOBWG),
|
||||
List(apiTagAccount))
|
||||
|
||||
lazy val deleteTagForViewOnAccount : OBPEndpoint = {
|
||||
//delete a tag
|
||||
case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId) :: "metadata" :: "tags" :: tagId :: Nil JsonDelete _ => {
|
||||
cc =>
|
||||
for {
|
||||
(Full(u), callContext) <- authorizedAccess(cc)
|
||||
(_, callContext) <- NewStyle.function.getBank(bankId, callContext)
|
||||
(_, callContext) <- NewStyle.function.checkBankAccountExists(bankId, accountId, callContext)
|
||||
view <- NewStyle.function.view(viewId, BankIdAccountId(bankId, accountId), callContext)
|
||||
_ <- NewStyle.function.hasViewAccess(view, u)
|
||||
_ <- Helper.booleanToFuture(failMsg = s"$NoViewPermission can_delete_tag. Current ViewId($viewId)") {
|
||||
view.canDeleteTag
|
||||
}
|
||||
deleted <- Future(Tags.tags.vend.deleteTagOnAccount(bankId, accountId)(tagId)) map {
|
||||
i => (connectorEmptyResponse(i, callContext), callContext)
|
||||
}
|
||||
} yield {
|
||||
(Full(deleted), HttpCode.`200`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -395,6 +395,8 @@ object OBPAPI4_0_0 extends OBPRestHelper with APIMethods130 with APIMethods140 w
|
||||
Implementations4_0_0.root ::
|
||||
Implementations4_0_0.getCallContext ::
|
||||
Implementations4_0_0.getEntitlements ::
|
||||
Implementations4_0_0.addTagForViewOnAccount ::
|
||||
Implementations4_0_0.deleteTagForViewOnAccount ::
|
||||
Nil
|
||||
|
||||
def allResourceDocs = MockerConnector.doc ++
|
||||
|
||||
@ -32,11 +32,30 @@ object MappedTags extends Tags {
|
||||
.date(datePosted).saveMe
|
||||
}
|
||||
}
|
||||
|
||||
override def addTagOnAccount(bankId: BankId, accountId: AccountId)
|
||||
(userId: UserPrimaryKey, viewId: ViewId, tagText: String, datePosted: Date): Box[TransactionTag] = {
|
||||
val metadateViewId = Views.views.vend.getMetadataViewId(BankIdAccountId(bankId, accountId), viewId)
|
||||
tryo{
|
||||
MappedTag.create
|
||||
.bank(bankId.value)
|
||||
.account(accountId.value)
|
||||
.transaction(null)
|
||||
.view(metadateViewId)
|
||||
.user(userId.value)
|
||||
.tag(tagText)
|
||||
.date(datePosted).saveMe
|
||||
}
|
||||
}
|
||||
|
||||
override def deleteTag(bankId: BankId, accountId: AccountId, transactionId: TransactionId)(tagId: String): Box[Boolean] = {
|
||||
//tagId is always unique so we actually don't need to use bankId, accountId, or transactionId
|
||||
MappedTag.find(By(MappedTag.tagId, tagId)).map(_.delete_!)
|
||||
}
|
||||
override def deleteTagOnAccount(bankId: BankId, accountId: AccountId)(tagId: String): Box[Boolean] = {
|
||||
//tagId is always unique so we actually don't need to use bankId, accountId, or transactionId
|
||||
MappedTag.find(By(MappedTag.tagId, tagId), By(MappedTag.bank, bankId.value), By(MappedTag.account, accountId.value)).map(_.delete_!)
|
||||
}
|
||||
|
||||
override def bulkDeleteTags(bankId: BankId, accountId: AccountId): Boolean = {
|
||||
val tagsDeleted = MappedTag.bulkDelete_!!(
|
||||
|
||||
@ -27,6 +27,15 @@ private object MongoTransactionTags extends Tags {
|
||||
tag(tagText).
|
||||
date(datePosted).saveTheRecord()
|
||||
}
|
||||
def addTagOnAccount(bankId : BankId, accountId : AccountId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag] = {
|
||||
OBPTag.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
tag(tagText).
|
||||
date(datePosted).saveTheRecord()
|
||||
}
|
||||
def deleteTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(tagId : String) : Box[Boolean] = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPTag.delete(OBPTag.getFindQuery(bankId, accountId, transactionId, tagId))
|
||||
@ -34,6 +43,9 @@ private object MongoTransactionTags extends Tags {
|
||||
//we don't have any useful information here so just assume it worked
|
||||
Full(true)
|
||||
}
|
||||
def deleteTagOnAccount(bankId : BankId, accountId : AccountId)(tagId : String) : Box[Boolean] = {
|
||||
deleteTag(bankId, accountId, TransactionId(""))(tagId)
|
||||
}
|
||||
|
||||
def bulkDeleteTags(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
|
||||
|
||||
@ -25,8 +25,10 @@ trait Tags {
|
||||
|
||||
def getTags(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(viewId : ViewId) : List[TransactionTag]
|
||||
def addTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag]
|
||||
def addTagOnAccount(bankId : BankId, accountId : AccountId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag]
|
||||
//TODO: viewId? should tagId always be unique -> in that case bankId, accountId, and transactionId would not be required
|
||||
def deleteTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(tagId : String) : Box[Boolean]
|
||||
def deleteTagOnAccount(bankId : BankId, accountId : AccountId)(tagId : String) : Box[Boolean]
|
||||
def bulkDeleteTags(bankId: BankId, accountId: AccountId) : Boolean
|
||||
|
||||
}
|
||||
@ -34,7 +36,9 @@ trait Tags {
|
||||
class RemotedataTagsCaseClasses{
|
||||
case class getTags(bankId : BankId, accountId : AccountId, transactionId: TransactionId, viewId : ViewId)
|
||||
case class addTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId, userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date)
|
||||
case class addTagOnAccount(bankId : BankId, accountId : AccountId, userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date)
|
||||
case class deleteTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId, tagId : String)
|
||||
case class deleteTagOnAccount(bankId : BankId, accountId : AccountId, tagId : String)
|
||||
case class bulkDeleteTags(bankId: BankId, accountId: AccountId)
|
||||
}
|
||||
|
||||
|
||||
@ -23,10 +23,16 @@ object RemotedataTags extends ObpActorInit with Tags {
|
||||
def addTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag] = getValueFromFuture(
|
||||
(actor ? cc.addTag(bankId, accountId, transactionId, userId, viewId, tagText, datePosted)).mapTo[Box[TransactionTag]]
|
||||
)
|
||||
def addTagOnAccount(bankId : BankId, accountId : AccountId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag] = getValueFromFuture(
|
||||
(actor ? cc.addTagOnAccount(bankId, accountId, userId, viewId, tagText, datePosted)).mapTo[Box[TransactionTag]]
|
||||
)
|
||||
|
||||
def deleteTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(tagId : String) : Box[Boolean] = getValueFromFuture(
|
||||
(actor ? cc.deleteTag(bankId, accountId, transactionId, tagId)).mapTo[Box[Boolean]]
|
||||
)
|
||||
def deleteTagOnAccount(bankId : BankId, accountId : AccountId)(tagId : String) : Box[Boolean] = getValueFromFuture(
|
||||
(actor ? cc.deleteTagOnAccount(bankId, accountId, tagId)).mapTo[Box[Boolean]]
|
||||
)
|
||||
|
||||
def bulkDeleteTags(bankId: BankId, accountId: AccountId): Boolean = getValueFromFuture(
|
||||
(actor ? cc.bulkDeleteTags(bankId, accountId)).mapTo[Boolean]
|
||||
|
||||
@ -21,11 +21,19 @@ class RemotedataTagsActor extends Actor with ObpActorHelper with MdcLoggable {
|
||||
case cc.addTag(bankId, accountId, transactionId, userId, viewId, text, datePosted) =>
|
||||
logger.debug("addTag(" + bankId +", "+ accountId +", "+ transactionId +", "+ text +", "+ text +", "+ datePosted +")")
|
||||
sender ! (mapper.addTag(bankId, accountId, transactionId)(userId, viewId, text, datePosted))
|
||||
|
||||
case cc.addTagOnAccount(bankId, accountId, userId, viewId, text, datePosted) =>
|
||||
logger.debug("addTag(" + bankId +", "+ accountId +", " + text +", "+ text +", "+ datePosted +")")
|
||||
sender ! (mapper.addTagOnAccount(bankId, accountId)(userId, viewId, text, datePosted))
|
||||
|
||||
case cc.deleteTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId, tagId : String) =>
|
||||
logger.debug("deleteTag(" + bankId +", "+ accountId +", "+ transactionId + tagId +")")
|
||||
sender ! (mapper.deleteTag(bankId, accountId, transactionId)(tagId))
|
||||
|
||||
case cc.deleteTagOnAccount(bankId : BankId, accountId : AccountId, tagId : String) =>
|
||||
logger.debug("deleteTag(" + bankId +", "+ accountId +", "+ tagId +")")
|
||||
sender ! (mapper.deleteTagOnAccount(bankId, accountId)(tagId))
|
||||
|
||||
case cc.bulkDeleteTags(bankId: BankId, accountId: AccountId) =>
|
||||
logger.debug("bulkDeleteTags(" + bankId +", "+ accountId + ")")
|
||||
sender ! (mapper.bulkDeleteTags(bankId, accountId))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user