Merge branch 'develop' of github.com:OpenBankProject/OBP-API into develop

This commit is contained in:
Simon Redfern 2018-02-22 15:56:33 +01:00
commit 0dfd95f8cb
13 changed files with 107 additions and 42 deletions

View File

@ -23,6 +23,7 @@ object AccountHolders extends SimpleInjector {
trait AccountHolders {
def getAccountHolders(bankId: BankId, accountId: AccountId): Set[User]
def getAccountsHeld(bankId: BankId, user: User): Set[BankIdAccountId]
def createAccountHolder(userId: Long, bankId: String, accountId: String): Boolean
def getOrCreateAccountHolder(user: User, bankAccountUID :BankIdAccountId): Box[MapperAccountHolders] //There is no AccountHolder trait, database structure different with view
def bulkDeleteAllAccountHolders(): Box[Boolean]
@ -31,6 +32,7 @@ trait AccountHolders {
class RemotedataAccountHoldersCaseClasses {
case class createAccountHolder(userId: Long, bankId: String, accountId: String)
case class getAccountHolders(bankId: BankId, accountId: AccountId)
case class getAccountsHeld(bankId: BankId, user: User)
case class getOrCreateAccountHolder(user: User, bankAccountUID :BankIdAccountId)
case class bulkDeleteAllAccountHolders()
}

View File

@ -88,6 +88,18 @@ object MapperAccountHolders extends MapperAccountHolders with AccountHolders wit
ResourceUser.find(By(ResourceUser.id, accHolder.user.get))
}.toSet
}
def getAccountsHeld(bankId: BankId, user: User): Set[BankIdAccountId] = {
val accountHolders = MapperAccountHolders.findAll(
By(MapperAccountHolders.accountBankPermalink, bankId.value),
By(MapperAccountHolders.user, user.asInstanceOf[ResourceUser])
)
//accountHolders --> BankIdAccountIds
accountHolders.map { accHolder =>
BankIdAccountId(bankId,AccountId(accHolder.accountPermalink.get))
}.toSet
}
def bulkDeleteAllAccountHolders(): Box[Boolean] = {
Full( MapperAccountHolders.bulkDelete_!!() )

View File

@ -296,7 +296,7 @@ trait APIMethods121 {
"getPrivateAccountsAtOneBank",
"GET",
"/banks/BANK_ID/accounts",
"Get accounts at bank (Private, inc views).",
"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.
|

View File

@ -248,7 +248,7 @@ trait APIMethods200 {
"getPrivateAccountsAtOneBank",
"GET",
"/banks/BANK_ID/accounts",
"Get Accounts at Bank (Private, inc views).",
"Get Accounts at Bank (Private).",
s"""Get accounts at one bank that the user has access to.
|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.

View File

@ -1,5 +1,6 @@
package code.api.v3_0_0
import code.accountholder.AccountHolders
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON._
import code.api.util.APIUtil.{canGetAtm, _}
@ -1800,9 +1801,43 @@ trait APIMethods300 {
Full(successJsonResponse(Extraction.decompose(json)))
}
}
resourceDocs += ResourceDoc(
getAccountsHeld,
implementedInApiVersion,
"getAccountsHeld",
"GET",
"/banks/BANK_ID/accounts-held",
"get Accounts Held",
s"""lists accounts for the current user where the current user is a holder but doesn't have the owner view
|
|${authenticationRequiredMessage(true)}
""",
emptyObjectJson,
JSONFactory300.createGlossaryItemsJsonV300(getExampleGlossaryItems),
List(UnknownError),
Catalogs(notCore, notPSD2, notOBWG),
List(apiTagAccount)
)
lazy val getAccountsHeld : OBPEndpoint = {
case "banks" :: BankId(bankId) :: "accounts-held" :: Nil JsonGet json => {
cc =>
for {
(user, callContext) <- extractCallContext(UserNotLoggedIn, cc)
u <- unboxFullAndWrapIntoFuture{ user }
bank <- Future { Bank(bankId) } map {
x => fullBoxOrException(x ?~! BankNotFound)
}
availableAccounts <- Future{ AccountHolders.accountHolders.vend.getAccountsHeld(bankId, u)}
accounts <- Connector.connector.vend.getCoreBankAccountsHeldFuture(availableAccounts.toList, callContext) map {
x => fullBoxOrException(x ?~! ConnectorEmptyResponse)
} map { unboxFull(_) }
} yield {
(JSONFactory300.createCoreAccountsByCoreAccountsJSON(accounts), callContext)
}
}
}
/* WIP

View File

@ -233,6 +233,7 @@ case class CoreAccountJsonV300(
account_routing: AccountRoutingJsonV121
)
case class CoreAccountsJsonV300(accounts: List[CoreAccount])
case class CoreAccountsHeldJsonV300(accounts: List[AccountHeld])
case class AccountIdJson(
id: String
@ -664,25 +665,13 @@ object JSONFactory300{
def createCoreAccountsByCoreAccountsJSON(coreAccounts : List[CoreAccount]): CoreAccountsJsonV300 =
CoreAccountsJsonV300(coreAccounts)
def createCoreAccountsByCoreAccountsJSON(accountsHeld : List[AccountHeld]): CoreAccountsHeldJsonV300 =
CoreAccountsHeldJsonV300(accountsHeld)
def createAccountsIdsByBankIdAccountIds(bankaccountIds : List[BankIdAccountId]): AccountsIdsJsonV300 =
AccountsIdsJsonV300(bankaccountIds.map(x => AccountIdJson(x.accountId.value)))
def createBankAccountJSON(account : ModeratedBankAccount, viewsAvailable : List[ViewJsonV300]) : ModeratedAccountJsonV300 = {
val bankName = account.bankName.getOrElse("")
ModeratedAccountJsonV300(
account.accountId.value,
stringOrNull(account.bankId.value),
stringOptionOrNull(account.label),
stringOptionOrNull(account.number),
createOwnersJSON(account.owners.getOrElse(Set()), bankName),
stringOptionOrNull(account.accountType),
createAmountOfMoneyJSON(account.currency.getOrElse(""), account.balance),
viewsAvailable,
AccountRoutingJsonV121(stringOptionOrNull(account.accountRoutingScheme),stringOptionOrNull(account.accountRoutingAddress))
)
}
def createAccountRulesJSON(rules: List[AccountRule]): List[AccountRuleJsonV300] = {
rules.map(i => AccountRuleJsonV300(scheme = i.scheme, value = i.value))
}

View File

@ -266,6 +266,7 @@ object OBPAPI3_0_0 extends OBPRestHelper with APIMethods130 with APIMethods140 w
Implementations3_0_0.getEntitlementsForCurrentUser ::
Implementations3_0_0.getFirehoseTransactionsForBankAccount ::
Implementations3_0_0.getApiGlossary ::
Implementations3_0_0.getAccountsHeld ::
Nil

View File

@ -255,6 +255,9 @@ trait Connector extends MdcLoggable{
def getCoreBankAccounts(bankIdAccountIds: List[BankIdAccountId], session: Option[CallContext]) : Box[List[CoreAccount]]= Failure(NotImplemented + currentMethodName)
def getCoreBankAccountsFuture(bankIdAccountIds: List[BankIdAccountId], session: Option[CallContext]) : Future[Box[List[CoreAccount]]]= Future{Failure(NotImplemented + currentMethodName)}
def getBankAccountsHeld(bankIdAccountIds: List[BankIdAccountId], session: Option[CallContext]) : Box[List[AccountHeld]]= Failure(NotImplemented + currentMethodName)
def getCoreBankAccountsHeldFuture(bankIdAccountIds: List[BankIdAccountId], session: Option[CallContext]) : Future[Box[List[AccountHeld]]]= Future {Failure(NotImplemented + currentMethodName)}
def checkBankAccountExists(bankId : BankId, accountId : AccountId, session: Option[CallContext] = None) : Box[BankAccount]= Failure(NotImplemented + currentMethodName)

View File

@ -293,14 +293,14 @@ object LocalMappedConnector extends Connector with MdcLoggable {
getBankAccount(bankId: BankId, accountId: AccountId)
}
override def getCoreBankAccounts(BankIdAcountIds: List[BankIdAccountId], session: Option[CallContext]) : Box[List[CoreAccount]]= {
override def getCoreBankAccounts(bankIdAcountIds: List[BankIdAccountId], session: Option[CallContext]) : Box[List[CoreAccount]]= {
Full(
BankIdAcountIds
bankIdAcountIds
.map(bankIdAccountId =>
getBankAccount(
bankIdAccountId.bankId,
bankIdAccountId.accountId)
.openOrThrowException(ErrorMessages.BankAccountNotFound))
.openOrThrowException(s"${ErrorMessages.BankAccountNotFound} current BANK_ID(${bankIdAccountId.bankId}) and ACCOUNT_ID(${bankIdAccountId.accountId})"))
.map(account =>
CoreAccount(
account.accountId.value,
@ -310,23 +310,29 @@ object LocalMappedConnector extends Connector with MdcLoggable {
)
}
override def getCoreBankAccountsFuture(BankIdAcountIds: List[BankIdAccountId], session: Option[CallContext]) : Future[Box[List[CoreAccount]]] = {
Future {
Full(
BankIdAcountIds
.map(bankIdAccountId =>
getBankAccount(
bankIdAccountId.bankId,
bankIdAccountId.accountId)
.openOrThrowException(ErrorMessages.BankAccountNotFound))
.map(account =>
CoreAccount(
account.accountId.value,
stringOrNull(account.label),
account.bankId.value,
AccountRouting(account.accountRoutingScheme,account.accountRoutingAddress)))
)
}
override def getCoreBankAccountsFuture(bankIdAcountIds: List[BankIdAccountId], session: Option[CallContext]) : Future[Box[List[CoreAccount]]] = {
Future {getCoreBankAccounts(bankIdAcountIds: List[BankIdAccountId], session: Option[CallContext])}
}
override def getBankAccountsHeld(bankIdAccountIds: List[BankIdAccountId], session: Option[CallContext]) : Box[List[AccountHeld]]= {
Full(
bankIdAccountIds
.map(bankIdAccountId =>
getBankAccount(
bankIdAccountId.bankId,
bankIdAccountId.accountId)
.openOrThrowException(s"${ErrorMessages.BankAccountNotFound} current BANK_ID(${bankIdAccountId.bankId}) and ACCOUNT_ID(${bankIdAccountId.accountId})"))
.map(account =>
AccountHeld(
account.accountId.value,
account.bankId.value,
stringOrNull(account.number),
AccountRouting(account.accountRoutingScheme,account.accountRoutingAddress)))
)
}
override def getCoreBankAccountsHeldFuture(bankIdAcountIds: List[BankIdAccountId], session: Option[CallContext]) : Future[Box[List[AccountHeld]]] = {
Future {getBankAccountsHeld(bankIdAcountIds: List[BankIdAccountId], session: Option[CallContext])}
}

View File

@ -877,6 +877,13 @@ case class CoreAccount(
account_routing: AccountRouting
)
case class AccountHeld(
id: String,
bank_id: String,
number: String,
account_routing: AccountRouting
)
case class CounterpartyBespoke(
key: String,
value: String

View File

@ -19,6 +19,9 @@ object RemotedataAccountHolders extends ObpActorInit with AccountHolders {
override def getAccountHolders(bankId: BankId, accountId: AccountId): Set[User] =
extractFuture(actor ? cc.getAccountHolders(bankId, accountId))
override def getAccountsHeld(bankId: BankId, user: User): Set[BankIdAccountId] =
extractFuture(actor ? cc.getAccountsHeld(bankId: BankId, user: User))
def bulkDeleteAllAccountHolders(): Box[Boolean] =
extractFutureToBox(actor ? cc.bulkDeleteAllAccountHolders())

View File

@ -26,6 +26,10 @@ class RemotedataAccountHoldersActor extends Actor with ObpActorHelper with MdcLo
logger.debug("getAccountHolders(" + bankId +", "+ accountId +")")
sender ! extractResult(mapper.getAccountHolders(bankId, accountId))
case cc.getAccountsHeld(bankId: BankId, user: User) =>
logger.debug("getAccountsHeld(" + bankId +", "+ user+")")
sender ! extractResult(mapper.getAccountsHeld(bankId: BankId, user: User))
case cc.bulkDeleteAllAccountHolders() =>
logger.debug("bulkDeleteAllAccountHolders()")
sender ! extractResult(mapper.bulkDeleteAllAccountHolders())

View File

@ -1,5 +1,7 @@
package code.search
import java.nio.charset.Charset
import dispatch.{Http, url}
import code.util.Helper.MdcLoggable
@ -19,6 +21,7 @@ import org.elasticsearch.common.settings.Settings
import com.sksamuel.elastic4s.TcpClient
import com.sksamuel.elastic4s.mappings.FieldType._
import com.sksamuel.elastic4s.ElasticDsl._
import dispatch.as.String.charset
import net.liftweb.http.provider.HTTPCookie
import net.liftweb.json.JsonAST
@ -59,7 +62,7 @@ class elasticsearch extends MdcLoggable {
val esUrl = s"${httpHost}${uri.replaceAll("\"" , "")}"
logger.debug(esUrl)
logger.debug(body)
val request = url(esUrl).<<(body).GET // Note that WE ONLY do GET - Keep it this way!
val request: Req = (url(esUrl).<<(body).GET).setContentType("application/json", Charset.forName("UTF-8")) // Note that WE ONLY do GET - Keep it this way!
val response = getAPIResponse(request)
ESJsonResponse(response.body, ("Access-Control-Allow-Origin", "*") :: Nil, Nil, response.code)
} else {