mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:26:51 +00:00
commit
4d29743585
34
README.md
34
README.md
@ -58,40 +58,12 @@ To compile and run jetty, install Maven 3, create your configuration in obp-api/
|
||||
|
||||
mvn install -pl .,obp-commons && mvn jetty:run -pl obp-api
|
||||
|
||||
## To run with IntelliJ IDEA
|
||||
|
||||
* Make sure you have the IntelliJ Scala plugin installed.
|
||||
|
||||
* Create a new folder e.g. OpenBankProject and cd there
|
||||
|
||||
* git clone https://github.com/OpenBankProject/OBP-API.git
|
||||
|
||||
* In IntelliJ IDEA do File -> New -> Project from existing sources, navigate to the folder and select pom.xml
|
||||
|
||||
* Alternatively you can do File -> New -> Project from VCS and checkout the project directly from github.
|
||||
|
||||
* When / if prompted for SDK, choose Java 1.8 (and Scala 2.12) otherwise keep the defaults. Use the Maven options. Do not change the project name etc.
|
||||
|
||||
* If you see a message about an unmanaged pom.xml, click the option to let Maven manage it.
|
||||
|
||||
* Navigate to obp-api/test/scala/code/RunWebApp. You may see a Setup Scala SDK link. Click this and check Scala 2.12.4 or so.
|
||||
[Note: How to run via IntelliJ IDEA](docs/glossary/Run_via_IntelliJ_IDEA.md)
|
||||
|
||||
## Run some tests.
|
||||
|
||||
* In obp-api/src/main/resources/props create a test.default.props for tests. Set connector=mapped
|
||||
|
||||
* In obp-api/src/main/resources/props create a \<yourloginname\>.props (or default.props) for development. Set connector=mapped
|
||||
|
||||
* Now **Rebuild** the project so everything is compiled. At this point you may need to select the SDK, see above.
|
||||
|
||||
* Once you have rebuilt the project without compile errors, you should be able to RunWebApp in obp-api/src/test/scala
|
||||
|
||||
* If you have trouble (re)building, try using the IntelliJ IDEA terminal: mvn clean test-compile
|
||||
|
||||
* Run RunWebApp by right clicking on it or selecting Run. The built in jetty server should start on localhost:8080
|
||||
|
||||
* Browse to localhost:8080 but don't try anything else there yet.
|
||||
|
||||
### Run some tests.
|
||||
|
||||
* Run a single test. For instance right click on obp-api/test/scala/code/branches/MappedBranchProviderTest and select Run Mapp...
|
||||
|
||||
* Run multiple tests: Right click on obp-api/test/scala/code and select Run. If need be:
|
||||
|
||||
49
docs/glossary/Run_via_IntelliJ_IDEA.md
Normal file
49
docs/glossary/Run_via_IntelliJ_IDEA.md
Normal file
@ -0,0 +1,49 @@
|
||||
## To run via IntelliJ IDEA
|
||||
|
||||
* Make sure you have the IntelliJ Scala plugin installed.
|
||||
|
||||
* Create a new folder e.g. OpenBankProject and cd there
|
||||
|
||||
* git clone https://github.com/OpenBankProject/OBP-API.git
|
||||
|
||||
* In IntelliJ IDEA do File -> New -> Project from existing sources, navigate to the folder and select pom.xml
|
||||
|
||||
* Alternatively you can do File -> New -> Project from VCS and checkout the project directly from github.
|
||||
|
||||
* When / if prompted for SDK, choose Java 1.8 (and Scala 2.12) otherwise keep the defaults. Use the Maven options. Do not change the project name etc.
|
||||
|
||||
* If you see a message about an unmanaged pom.xml, click the option to let Maven manage it.
|
||||
|
||||
* Navigate to obp-api/test/scala/code/RunWebApp. You may see a Setup Scala SDK link. Click this and check Scala 2.12.12 or so.
|
||||
|
||||
* In obp-api/src/main/resources/props create a \<yourloginname\>.props (or default.props) for development. Set connector=mapped
|
||||
|
||||
* Now **Rebuild** the project so everything is compiled. At this point you may need to select the SDK, see above.
|
||||
|
||||
* Once you have rebuilt the project without compile errors, you should be able to RunWebApp/RunTLSWebApp/RunMTLSWebApp in obp-api/src/test/scala
|
||||
|
||||
* If you have trouble (re)building, try using the IntelliJ IDEA terminal: mvn clean test-compile
|
||||
|
||||
### To run via IntelliJ IDEA in development mode without secure connection
|
||||
|
||||
* Run RunWebApp by right clicking on it or selecting Run. The built in jetty server should start on localhost:8080
|
||||
|
||||
* Browse to http://localhost:8080 but don't try anything else there yet.
|
||||
|
||||
### To run via IntelliJ IDEA in TLS development mode (secure connection)
|
||||
|
||||
* Run RunTLSWebApp by right clicking on it and selecting Run/Debug. The built in jetty server should start on localhost:8080
|
||||
|
||||
* Browse to https://localhost:8080 but don't try anything else there yet
|
||||
|
||||
In `development` mode we use this option in order to try OpenID Connect functionality. I.e. redirect URI must be `https` one.
|
||||
|
||||
### To run via IntelliJ IDEA in MTLS development mode (secure connection)
|
||||
|
||||
* Run RunMTLSWebApp by right clicking on it and selecting Run/Debug. The built in jetty server should start on localhost:8080
|
||||
|
||||
* Import certificate obp-api/src/test/resources/cert/localhost_SAN_dns_ip.pfx into your browser.
|
||||
|
||||
* Browse to https://localhost:8080 but don't try anything else there yet
|
||||
|
||||
In `development` mode we use this option in order to try UK Open Banking APIs functionality where mutual TLS is part of that standard.
|
||||
@ -169,16 +169,6 @@
|
||||
<version>${jetty.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.liftweb</groupId>
|
||||
<artifactId>lift-mongodb_${scala.version}</artifactId>
|
||||
<version>${lift.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.liftweb</groupId>
|
||||
<artifactId>lift-mongodb-record_${scala.version}</artifactId>
|
||||
<version>${lift.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
@ -508,6 +498,12 @@
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.7.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -232,6 +232,10 @@ apiPathZero=obp
|
||||
## Not need in dev mode, but important for production
|
||||
mail.api.consumer.registered.sender.address=no-reply@example.com
|
||||
mail.api.consumer.registered.notification.addresses=you@example.com
|
||||
## Not need in dev mode, but important for production
|
||||
## We send an email after any exception
|
||||
# mail.exception.sender.address=no-reply@example.com
|
||||
# mail.exception.registered.notification.addresses=notify@example.com,notify2@example.com,notify3@example.com
|
||||
# This property allows sending API registration data to developer's email.
|
||||
#mail.api.consumer.registered.notification.send=false
|
||||
We only send consumer keys and secret if this is true
|
||||
@ -448,9 +452,6 @@ webui_oauth_1_documentation_url =
|
||||
# Link to OAuth 2.0 glossary on api explorer
|
||||
webui_oauth_2_documentation_url =
|
||||
|
||||
# URL of OAuth2.0 server
|
||||
oauth2_server_url =
|
||||
|
||||
# Link to Privacy Policy on signup page
|
||||
#webui_signup_form_submit_button_value=
|
||||
#webui_signup_form_title_text=Sign Up
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
|
||||
#which data connector to use
|
||||
|
||||
#connector=mongodb
|
||||
#connector=rest
|
||||
#connector=kafka
|
||||
#connector=obpjvm
|
||||
|
||||
@ -29,6 +29,7 @@ package bootstrap.liftweb
|
||||
import java.io.{File, FileInputStream}
|
||||
import java.util.stream.Collectors
|
||||
import java.util.{Locale, TimeZone}
|
||||
|
||||
import code.CustomerDependants.MappedCustomerDependant
|
||||
import code.DynamicData.DynamicData
|
||||
import code.DynamicEndpoint.DynamicEndpoint
|
||||
@ -47,24 +48,33 @@ import code.api.util.APIUtil.{enableVersionIfAllowed, errorJsonResponse, getProp
|
||||
import code.api.util._
|
||||
import code.api.util.migration.Migration
|
||||
import code.api.util.migration.Migration.DbFunction
|
||||
import code.apicollection.ApiCollection
|
||||
import code.apicollectionendpoint.ApiCollectionEndpoint
|
||||
import code.atms.MappedAtm
|
||||
import code.authtypevalidation.AuthenticationTypeValidation
|
||||
import code.bankattribute.BankAttribute
|
||||
import code.bankconnectors.storedprocedure.StoredProceduresMockedData
|
||||
import code.bankconnectors.{Connector, ConnectorEndpoints}
|
||||
import code.branches.MappedBranch
|
||||
import code.cardattribute.MappedCardAttribute
|
||||
import code.cards.{MappedPhysicalCard, PinReset}
|
||||
import code.connectormethod.ConnectorMethod
|
||||
import code.consent.{ConsentRequest, MappedConsent}
|
||||
import code.consumer.Consumers
|
||||
import code.context.{MappedConsentAuthContext, MappedUserAuthContext, MappedUserAuthContextUpdate}
|
||||
import code.crm.MappedCrmEvent
|
||||
import code.customer.internalMapping.MappedCustomerIdMapping
|
||||
import code.customer.{MappedCustomer, MappedCustomerMessage}
|
||||
import code.customeraccountlinks.CustomerAccountLink
|
||||
import code.customeraddress.MappedCustomerAddress
|
||||
import code.customerattribute.MappedCustomerAttribute
|
||||
import code.database.authorisation.Authorisation
|
||||
import code.directdebit.DirectDebit
|
||||
import code.dynamicEntity.DynamicEntity
|
||||
import code.dynamicMessageDoc.DynamicMessageDoc
|
||||
import code.dynamicResourceDoc.DynamicResourceDoc
|
||||
import code.endpointMapping.EndpointMapping
|
||||
import code.endpointTag.EndpointTag
|
||||
import code.entitlement.MappedEntitlement
|
||||
import code.entitlementrequest.MappedEntitlementRequest
|
||||
import code.fx.{MappedCurrency, MappedFXRate}
|
||||
@ -85,28 +95,19 @@ import code.metadata.wheretags.MappedWhereTag
|
||||
import code.methodrouting.MethodRouting
|
||||
import code.metrics.{MappedConnectorMetric, MappedMetric, MetricsArchive}
|
||||
import code.migration.MigrationScriptLog
|
||||
import code.model.{Consumer, _}
|
||||
import code.model.dataAccess._
|
||||
import code.model.dataAccess.internalMapping.AccountIdMapping
|
||||
import code.model.{Consumer, _}
|
||||
import code.obp.grpc.HelloWorldServer
|
||||
import code.productAttributeattribute.MappedProductAttribute
|
||||
import code.productcollection.MappedProductCollection
|
||||
import code.productcollectionitem.MappedProductCollectionItem
|
||||
import code.productfee.ProductFee
|
||||
import code.products.MappedProduct
|
||||
import code.ratelimiting.RateLimiting
|
||||
import code.remotedata.RemotedataActors
|
||||
import code.scheduler.{DatabaseDriverScheduler, MetricsArchiveScheduler}
|
||||
import code.scope.{MappedScope, MappedUserScope}
|
||||
import code.apicollectionendpoint.ApiCollectionEndpoint
|
||||
import code.apicollection.ApiCollection
|
||||
import code.bankattribute.BankAttribute
|
||||
import code.connectormethod.ConnectorMethod
|
||||
import code.customeraccountlinks.CustomerAccountLink
|
||||
import code.dynamicMessageDoc.DynamicMessageDoc
|
||||
import code.dynamicResourceDoc.DynamicResourceDoc
|
||||
import code.endpointMapping.EndpointMapping
|
||||
import code.endpointTag.EndpointTag
|
||||
import code.productfee.ProductFee
|
||||
import code.snippet.{OAuthAuthorisation, OAuthWorkedThanks}
|
||||
import code.socialmedia.MappedSocialMedia
|
||||
import code.standingorders.StandingOrder
|
||||
@ -121,19 +122,17 @@ import code.transactionattribute.MappedTransactionAttribute
|
||||
import code.transactionrequests.{MappedTransactionRequest, MappedTransactionRequestTypeCharge, TransactionRequestReasons}
|
||||
import code.usercustomerlinks.MappedUserCustomerLink
|
||||
import code.userlocks.UserLocks
|
||||
import code.users.{UserAgreement, UserAttribute, UserInitAction, UserInvitation, Users}
|
||||
import code.users._
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.util.{Helper, HydraUtil}
|
||||
import code.validation.JsonSchemaValidation
|
||||
import code.views.Views
|
||||
import code.views.system.{AccountAccess, ViewDefinition}
|
||||
import code.webhook.{BankAccountNotificationWebhook, MappedAccountWebhook, SystemAccountNotificationWebhook, WebhookHelperActors}
|
||||
import code.webhook.{BankAccountNotificationWebhook, MappedAccountWebhook, SystemAccountNotificationWebhook}
|
||||
import code.webuiprops.WebUiProps
|
||||
import com.openbankproject.commons.model.{ErrorMessage, User}
|
||||
import com.openbankproject.commons.model.ErrorMessage
|
||||
import com.openbankproject.commons.util.Functions.Implicits._
|
||||
import com.openbankproject.commons.util.{ApiVersion, Functions}
|
||||
|
||||
import javax.mail.{Authenticator, PasswordAuthentication}
|
||||
import javax.mail.internet.MimeMessage
|
||||
import net.liftweb.common._
|
||||
import net.liftweb.db.DBLogEntry
|
||||
@ -332,12 +331,8 @@ class Boot extends MdcLoggable {
|
||||
|
||||
// ensure our relational database's tables are created/fit the schema
|
||||
val connector = APIUtil.getPropsValue("connector").openOrThrowException("no connector set")
|
||||
if(connector != "mongodb")
|
||||
schemifyAll()
|
||||
schemifyAll()
|
||||
|
||||
// This sets up MongoDB config (for the mongodb connector)
|
||||
if( connector == "mongodb")
|
||||
MongoConfig.init
|
||||
|
||||
val runningMode = Props.mode match {
|
||||
case Props.RunModes.Production => "Production mode"
|
||||
@ -488,8 +483,7 @@ class Boot extends MdcLoggable {
|
||||
Nil
|
||||
}
|
||||
}
|
||||
|
||||
WebhookHelperActors.startLocalWebhookHelperWorkers(actorSystem)
|
||||
|
||||
|
||||
if (connector.startsWith("kafka") || (connector == "star" && APIUtil.getPropsValue("starConnector_supported_types","").split(",").contains("kafka"))) {
|
||||
logger.info(s"KafkaHelperActors.startLocalKafkaHelperWorkers( ${actorSystem} ) starting")
|
||||
|
||||
@ -6,7 +6,6 @@ import code.bankconnectors.LocalMappedOutInBoundTransfer
|
||||
import code.bankconnectors.akka.actor.{AkkaConnectorActorConfig, AkkaConnectorHelperActor}
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.webhook.WebhookHelperActors
|
||||
import com.openbankproject.adapter.akka.commons.config.AkkaConfig
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import net.liftweb.common.Full
|
||||
@ -79,31 +78,6 @@ trait ObpLookupSystem extends MdcLoggable {
|
||||
this.obpLookupSystem.actorSelection(actorPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is a Single Point Of Entry for Webhook's Actor
|
||||
* I.e. we can obtain te Actor all over the code in next way:
|
||||
* {
|
||||
* val actor: ActorSelection = ObpLookupSystem.getWebhookActor()
|
||||
* }
|
||||
*
|
||||
* @return An ActorSelection which is a logical view of a section of an ActorSystem's tree of Actors,
|
||||
* allowing for broadcasting of messages to that section.
|
||||
*/
|
||||
def getWebhookActor(): ActorSelection = {
|
||||
val name = WebhookHelperActors.actorName
|
||||
val actorPath: String = {
|
||||
val hostname = ObpActorConfig.localHostname
|
||||
val port = ObpActorConfig.localPort
|
||||
val props_hostname = Helper.getHostname
|
||||
if (port == 0) {
|
||||
logger.error("Failed to connect to local Webhook's actor")
|
||||
}
|
||||
s"akka.tcp://ObpActorSystem_${props_hostname}@${hostname}:${port}/user/${name}"
|
||||
}
|
||||
this.obpLookupSystem.actorSelection(actorPath)
|
||||
}
|
||||
|
||||
|
||||
def getAkkaConnectorActor(actorName: String) = {
|
||||
|
||||
val hostname = APIUtil.getPropsValue("akka_connector.hostname")
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_AccountAccessConsentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_AccountsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_BalancesApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_BeneficiariesApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_DirectDebitsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_DomesticFutureDatedPaymentConsentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_DomesticFutureDatedPaymentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_DomesticPaymentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_DomesticPaymentsConsentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_EventNotificationApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_FilePaymentConsentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_FilePaymentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_FutureDatedPaymentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_InternationalPaymentConsentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_InternationalPaymentsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_OffersApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_PartiesApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_StandingOrdersApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_StatementsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_SupplementaryAccountInfoApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -1,27 +1,19 @@
|
||||
package code.api.BahrainOBF.v1_0_0
|
||||
|
||||
import code.api.APIFailureNewStyle
|
||||
import code.api.berlin.group.v1_3.JvalueCaseClass
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
import code.api.util.APIUtil.{defaultBankId, _}
|
||||
import code.api.util.NewStyle
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiTag
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.bankconnectors.Connector
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.views.Views
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.json
|
||||
import net.liftweb.json._
|
||||
|
||||
import scala.collection.immutable.Nil
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
import code.api.BahrainOBF.v1_0_0.ApiCollector
|
||||
import code.api.util.ApiTag
|
||||
|
||||
object APIMethods_TransactionsApi extends RestHelper {
|
||||
val apiVersion = ApiCollector.apiVersion
|
||||
|
||||
@ -128,11 +128,14 @@ object OAuth2Login extends RestHelper with MdcLoggable {
|
||||
if(consumer.isEmpty) {
|
||||
return (Failure(Oauth2TokenHaveNoConsumer), Some(cc.copy(consumer = Failure(Oauth2TokenHaveNoConsumer))))
|
||||
}
|
||||
val clientCert = APIUtil.`getPSD2-CERT`(cc.requestHeaders)
|
||||
val clientCert: Option[String] = APIUtil.`getPSD2-CERT`(cc.requestHeaders)
|
||||
clientCert.filter(StringUtils.isNotBlank).foreach {cert =>
|
||||
val foundConsumer = consumer.orNull
|
||||
val certInConsumer = foundConsumer.clientCertificate.get
|
||||
if(StringUtils.isBlank(certInConsumer)) {
|
||||
// In case that the certificate of a consumer is not populated in a database
|
||||
// we use the value at PSD2-CERT header in order to populate it for the first time.
|
||||
// Please note that every next call MUST match that value.
|
||||
foundConsumer.clientCertificate.set(cert)
|
||||
consumer = Full(foundConsumer.saveMe())
|
||||
val clientId = foundConsumer.key.get
|
||||
@ -147,10 +150,18 @@ object OAuth2Login extends RestHelper with MdcLoggable {
|
||||
// hydra update client endpoint have bug, So here delete and create to do update
|
||||
hydraAdmin.deleteOAuth2Client(clientId)
|
||||
hydraAdmin.createOAuth2Client(oAuth2Client)
|
||||
} else if(stringNotEq(certInConsumer, cert)) {
|
||||
} else if(stringNotEq(certInConsumer, cert)) {
|
||||
// Cannot match the value from PSD2-CERT header and the database value Consumer.clientCertificate
|
||||
logger.debug("Cert in Consumer: " + certInConsumer)
|
||||
logger.debug("Cert in Request: " + cert)
|
||||
logger.debug(s"Token: $value")
|
||||
logger.debug(s"Client ID: ${introspectOAuth2Token.getClientId}")
|
||||
return (Failure(Oauth2TokenMatchCertificateFail), Some(cc.copy(consumer = Failure(Oauth2TokenMatchCertificateFail))))
|
||||
} else {
|
||||
// Certificate is matched. Just make some debug logging.
|
||||
logger.debug("The token is linked with a proper client certificate.")
|
||||
logger.debug(s"Token: $value")
|
||||
logger.debug(s"Client Key: ${introspectOAuth2Token.getClientId}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import java.util.Date
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.{APIUtil, ConsentJWT, CustomJsonFormats, JwtUtil}
|
||||
import code.bankconnectors.Connector
|
||||
import code.consent.Consent
|
||||
import code.consent.ConsentTrait
|
||||
import code.database.authorisation.Authorisation
|
||||
import code.model.ModeratedTransaction
|
||||
import com.openbankproject.commons.model.enums.AccountRoutingScheme
|
||||
@ -496,7 +496,7 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
|
||||
)
|
||||
}
|
||||
|
||||
def createPostConsentResponseJson(consent: Consent) : PostConsentResponseJson = {
|
||||
def createPostConsentResponseJson(consent: ConsentTrait) : PostConsentResponseJson = {
|
||||
PostConsentResponseJson(
|
||||
consentId = consent.consentId,
|
||||
consentStatus = consent.status.toLowerCase(),
|
||||
@ -504,7 +504,7 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
|
||||
)
|
||||
}
|
||||
|
||||
def createGetConsentResponseJson(createdConsent: Consent) : GetConsentResponseJson = {
|
||||
def createGetConsentResponseJson(createdConsent: ConsentTrait) : GetConsentResponseJson = {
|
||||
val jsonWebTokenAsJValue: Box[ConsentJWT] = JwtUtil.getSignedPayloadAsJson(createdConsent.jsonWebToken)
|
||||
.map(parse(_).extract[ConsentJWT])
|
||||
val access: ConsentAccessJson = jsonWebTokenAsJValue
|
||||
@ -520,7 +520,7 @@ object JSONFactory_BERLIN_GROUP_1_3 extends CustomJsonFormats {
|
||||
)
|
||||
}
|
||||
|
||||
def createStartConsentAuthorisationJson(consent: Consent, challenge: ChallengeTrait) : StartConsentAuthorisationJson = {
|
||||
def createStartConsentAuthorisationJson(consent: ConsentTrait, challenge: ChallengeTrait) : StartConsentAuthorisationJson = {
|
||||
StartConsentAuthorisationJson(
|
||||
scaStatus = challenge.scaStatus.map(_.toString).getOrElse("None"),
|
||||
pushMessage = "started", //TODO Not implement how to fill this.
|
||||
|
||||
@ -3452,10 +3452,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
|
||||
// All OBP REST end points start with /obp
|
||||
def getObpApiRoot: String = s"$getServerUrl/obp"
|
||||
|
||||
// Get OAuth2 Authentication Server URL
|
||||
def getOAuth2ServerUrl: String = getPropsValue("oauth2_server_url").openOr(MissingPropsValueAtThisInstance + "oauth2_server_url")
|
||||
|
||||
|
||||
lazy val defaultBankId =
|
||||
if (Props.mode == Props.RunModes.Test)
|
||||
APIUtil.getPropsValue("defaultBank.bank_id", "DEFAULT_BANK_ID_NOT_SET_Test")
|
||||
|
||||
@ -334,6 +334,8 @@ object Consent {
|
||||
case _ =>
|
||||
(Failure(ErrorMessages.UnknownError), Some(cc))
|
||||
}
|
||||
case _ =>
|
||||
(Failure("Cannot add entitlements based on: " + consentAsJwt), Some(cc))
|
||||
}
|
||||
case _ =>
|
||||
(Failure("Cannot create or get the user based on: " + consentAsJwt), Some(cc))
|
||||
@ -421,13 +423,15 @@ object Consent {
|
||||
case _ =>
|
||||
(Failure(ErrorMessages.UnknownError), Some(cc))
|
||||
}
|
||||
case _ =>
|
||||
(Failure("Cannot add entitlements based on: " + consentId), Some(cc))
|
||||
}
|
||||
case _ =>
|
||||
(Failure("Cannot create or get the user based on: " + consentId), Some(cc))
|
||||
}
|
||||
}
|
||||
|
||||
def checkFrequencyPerDay(storedConsent: consent.Consent) = {
|
||||
def checkFrequencyPerDay(storedConsent: consent.ConsentTrait) = {
|
||||
def isSameDay(date1: Date, date2: Date): Boolean = {
|
||||
val fmt = new SimpleDateFormat("yyyyMMdd")
|
||||
fmt.format(date1).equals(fmt.format(date2))
|
||||
|
||||
@ -213,7 +213,7 @@ object ErrorMessages {
|
||||
val Oauth2JOSEException = "OBP-20207: Bad JSON Object Signing and Encryption (JOSE) exception. An internal JOSE exception was encountered. "
|
||||
val Oauth2CannotMatchIssuerAndJwksUriException = "OBP-20208: Cannot match the issuer and JWKS URI at this server instance. "
|
||||
val Oauth2TokenHaveNoConsumer = "OBP-20209: The token have no linked consumer. "
|
||||
val Oauth2TokenMatchCertificateFail = "OBP-20210: The token linked with a different client certificate. "
|
||||
val Oauth2TokenMatchCertificateFail = "OBP-20210: The token is linked with a different client certificate. "
|
||||
|
||||
val OneTimePasswordExpired = "OBP-20211: The One Time Password (OTP) has expired. "
|
||||
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
package code.api.util
|
||||
|
||||
import java.io.File
|
||||
|
||||
import code.api.Constant.PARAM_LOCALE
|
||||
import code.api.util.APIUtil.{getOAuth2ServerUrl, getObpApiRoot, getServerUrl}
|
||||
import code.api.util.APIUtil.{getObpApiRoot, getServerUrl}
|
||||
import code.api.util.ExampleValue.{accountIdExample, bankIdExample, customerIdExample, userIdExample}
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue
|
||||
import net.liftweb.http.LiftRules
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue
|
||||
|
||||
|
||||
object Glossary extends MdcLoggable {
|
||||
@ -3106,7 +3109,38 @@ object Glossary extends MdcLoggable {
|
||||
|""".stripMargin)
|
||||
|
||||
|
||||
private def getContentFromMarkdownFile(path: String): String = {
|
||||
val source = scala.io.Source.fromFile(path)
|
||||
val lines: String = try source.mkString finally source.close()
|
||||
lines
|
||||
.replaceAll("getServerUrl", getServerUrl)
|
||||
.replaceAll("getObpApiRoot", getObpApiRoot)
|
||||
}
|
||||
|
||||
private def getListOfFiles():List[File] = {
|
||||
val dir= LiftRules.getResource("/")
|
||||
.map(_.toURI.getPath
|
||||
.replace("obp-api/src/main/webapp", "docs/glossary"))
|
||||
val d = new File(dir.getOrElse(""))
|
||||
if (d.exists && d.isDirectory) {
|
||||
d.listFiles.filter(_.isFile).filter(_.getName.endsWith(".md")).toList
|
||||
} else {
|
||||
List[File]()
|
||||
}
|
||||
}
|
||||
|
||||
// Append all files from /OBP-API/docs/glossary as items
|
||||
// File name is used as a title
|
||||
// File content is used as a description
|
||||
glossaryItems.appendAll(
|
||||
getListOfFiles().map(file =>
|
||||
GlossaryItem(
|
||||
title = file.getName.replace(".md", "").replace("_", " "),
|
||||
description = getContentFromMarkdownFile(file.getPath)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// NOTE! Some glossary items are generated in ExampleValue.scala
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -35,7 +35,7 @@ object TableAccountAccess {
|
||||
.user_fk(permission.user.get)
|
||||
.view_id(viewId)
|
||||
.view_fk(viewFk)
|
||||
.save()
|
||||
.save
|
||||
}
|
||||
val isSuccessful = insertedRows.forall(_ == true)
|
||||
val accountAccess = AccountAccess.findAll()
|
||||
|
||||
@ -99,7 +99,7 @@ object MigrationOfAccountRoutings {
|
||||
false // DB have the same routing
|
||||
case Full(routing) =>
|
||||
// only accountRoutingAddress is different.
|
||||
routing.AccountRoutingAddress(accountRoutingAddress).save()
|
||||
routing.AccountRoutingAddress(accountRoutingAddress).save
|
||||
case _ =>
|
||||
// query according unique index: UniqueIndex(BankId, AccountRoutingScheme, AccountRoutingAddress)
|
||||
BankAccountRouting.find(By(BankAccountRouting.BankId, bankId),
|
||||
@ -108,7 +108,7 @@ object MigrationOfAccountRoutings {
|
||||
) match {
|
||||
case Full(routing) =>
|
||||
// only accountId is different
|
||||
routing.AccountId(accountId).save()
|
||||
routing.AccountId(accountId).save
|
||||
case _ =>
|
||||
// not exists corresponding routing in DB.
|
||||
BankAccountRouting.create
|
||||
@ -116,7 +116,7 @@ object MigrationOfAccountRoutings {
|
||||
.AccountId(accountId)
|
||||
.AccountRoutingScheme(accountRoutingScheme)
|
||||
.AccountRoutingAddress(accountRoutingAddress)
|
||||
.save()
|
||||
.save
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ object TableRateLmiting {
|
||||
.PerMonthCallLimit(consumer.perMonthCallLimit.get)
|
||||
.FromDate(Date.from(oneDayAgo.toInstant()))
|
||||
.ToDate(Date.from(oneYearInFuture.toInstant()))
|
||||
.save()
|
||||
.save
|
||||
}
|
||||
}
|
||||
val isSuccessful = insertedRows.forall(_ == true)
|
||||
|
||||
@ -58,7 +58,7 @@ object UpdateTableViewDefinition {
|
||||
view <- views
|
||||
accountAccess <- AccountAccess.find(By(AccountAccess.view_fk, view.id)).toList
|
||||
} yield {
|
||||
accountAccess.view_id(view.viewId.value).save()
|
||||
accountAccess.view_id(view.viewId.value).save
|
||||
}
|
||||
|
||||
val isSuccessful = views.forall(_.isSystem == false)
|
||||
|
||||
3
obp-api/src/main/scala/code/api/util/test.md
Normal file
3
obp-api/src/main/scala/code/api/util/test.md
Normal file
@ -0,0 +1,3 @@
|
||||
#What is mutual TLS (mTLS)?
|
||||
|
||||
Mutual TLS (mTLS) is a type of authentication in which the two parties in a connection authenticate each other using the TLS protocol.
|
||||
@ -9559,7 +9559,7 @@ trait APIMethods400 {
|
||||
lazy val createJsonSchemaValidation: OBPEndpoint = {
|
||||
case "management" :: "json-schema-validations" :: operationId :: Nil JsonPost _ -> _ => {
|
||||
cc =>
|
||||
val Some(httpBody): Option[String] = cc.httpBody
|
||||
val httpBody: String = cc.httpBody.getOrElse("")
|
||||
for {
|
||||
(Full(u), callContext) <- SS.user
|
||||
|
||||
@ -9605,7 +9605,7 @@ trait APIMethods400 {
|
||||
lazy val updateJsonSchemaValidation: OBPEndpoint = {
|
||||
case "management" :: "json-schema-validations" :: operationId :: Nil JsonPut _ -> _ => {
|
||||
cc =>
|
||||
val Some(httpBody): Option[String] = cc.httpBody
|
||||
val httpBody: String = cc.httpBody.getOrElse("")
|
||||
for {
|
||||
(Full(u), callContext) <- SS.user
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package code.api.v5_1_0
|
||||
|
||||
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.{apiCollectionJson400, apiCollectionsJson400, postApiCollectionJson400, revokedConsentJsonV310}
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.{apiCollectionJson400, apiCollectionsJson400, apiInfoJson400, postApiCollectionJson400, revokedConsentJsonV310}
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiRole._
|
||||
import code.api.util.ApiTag._
|
||||
@ -16,7 +16,7 @@ import code.util.Helper
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.model.BankId
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import com.openbankproject.commons.util.{ApiVersion, ScannedApiVersion}
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
|
||||
@ -32,7 +32,7 @@ trait APIMethods510 {
|
||||
|
||||
class Implementations510 {
|
||||
|
||||
val implementedInApiVersion = ApiVersion.v5_1_0
|
||||
val implementedInApiVersion: ScannedApiVersion = ApiVersion.v5_1_0
|
||||
|
||||
private val staticResourceDocs = ArrayBuffer[ResourceDoc]()
|
||||
def resourceDocs = staticResourceDocs
|
||||
@ -41,6 +41,34 @@ trait APIMethods510 {
|
||||
val codeContext = CodeContext(staticResourceDocs, apiRelations)
|
||||
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
root,
|
||||
implementedInApiVersion,
|
||||
"root",
|
||||
"GET",
|
||||
"/root",
|
||||
"Get API Info (root)",
|
||||
"""Returns information about:
|
||||
|
|
||||
|* API version
|
||||
|* Hosted by information
|
||||
|* Hosted at information
|
||||
|* Energy source information
|
||||
|* Git Commit""",
|
||||
EmptyBody,
|
||||
apiInfoJson400,
|
||||
List(UnknownError, "no connector set"),
|
||||
apiTagApi :: apiTagNewStyle :: Nil)
|
||||
|
||||
lazy val root : OBPEndpoint = {
|
||||
case (Nil | "root" :: Nil) JsonGet _ => {
|
||||
cc => Future {
|
||||
JSONFactory510.getApiInfoJSON(implementedInApiVersion) -> HttpCode.`200`(cc.callContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
getAllApiCollections,
|
||||
implementedInApiVersion,
|
||||
|
||||
@ -26,8 +26,61 @@
|
||||
*/
|
||||
package code.api.v5_1_0
|
||||
|
||||
import code.api.Constant
|
||||
import code.api.util.APIUtil
|
||||
import code.api.util.APIUtil.gitCommit
|
||||
import code.api.v4_0_0.{EnergySource400, HostedAt400, HostedBy400}
|
||||
import com.openbankproject.commons.util.ScannedApiVersion
|
||||
|
||||
|
||||
case class APIInfoJsonV510(
|
||||
version : String,
|
||||
version_status: String,
|
||||
git_commit : String,
|
||||
stage : String,
|
||||
connector : String,
|
||||
hostname : String,
|
||||
local_identity_provider : String,
|
||||
hosted_by : HostedBy400,
|
||||
hosted_at : HostedAt400,
|
||||
energy_source : EnergySource400,
|
||||
resource_docs_requires_role: Boolean
|
||||
)
|
||||
|
||||
object JSONFactory510 {
|
||||
def getApiInfoJSON(implementedInApiVersion: ScannedApiVersion) = {
|
||||
val (apiVersion, apiVersionStatus) = (implementedInApiVersion, OBPAPI5_1_0.versionStatus)
|
||||
val organisation = APIUtil.getPropsValue("hosted_by.organisation", "TESOBE")
|
||||
val email = APIUtil.getPropsValue("hosted_by.email", "contact@tesobe.com")
|
||||
val phone = APIUtil.getPropsValue("hosted_by.phone", "+49 (0)30 8145 3994")
|
||||
val organisationWebsite = APIUtil.getPropsValue("organisation_website", "https://www.tesobe.com")
|
||||
val hostedBy = new HostedBy400(organisation, email, phone, organisationWebsite)
|
||||
|
||||
val organisationHostedAt = APIUtil.getPropsValue("hosted_at.organisation", "")
|
||||
val organisationWebsiteHostedAt = APIUtil.getPropsValue("hosted_at.organisation_website", "")
|
||||
val hostedAt = HostedAt400(organisationHostedAt, organisationWebsiteHostedAt)
|
||||
|
||||
val organisationEnergySource = APIUtil.getPropsValue("energy_source.organisation", "")
|
||||
val organisationWebsiteEnergySource = APIUtil.getPropsValue("energy_source.organisation_website", "")
|
||||
val energySource = EnergySource400(organisationEnergySource, organisationWebsiteEnergySource)
|
||||
|
||||
val connector = APIUtil.getPropsValue("connector").openOrThrowException("no connector set")
|
||||
val resourceDocsRequiresRole = APIUtil.getPropsAsBoolValue("resource_docs_requires_role", false)
|
||||
|
||||
APIInfoJsonV510(
|
||||
version = apiVersion.vDottedApiVersion,
|
||||
version_status = apiVersionStatus,
|
||||
git_commit = gitCommit,
|
||||
connector = connector,
|
||||
hostname = Constant.HostName,
|
||||
stage = System.getProperty("run.mode"),
|
||||
local_identity_provider = Constant.localIdentityProvider,
|
||||
hosted_by = hostedBy,
|
||||
hosted_at = hostedAt,
|
||||
energy_source = energySource,
|
||||
resource_docs_requires_role = resourceDocsRequiresRole
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -79,7 +79,6 @@ object Connector extends SimpleInjector {
|
||||
val nameToConnector: Map[String, () => Connector] = Map(
|
||||
"mapped" -> lazyValue(LocalMappedConnector),
|
||||
"akka_vDec2018" -> lazyValue(AkkaConnector_vDec2018),
|
||||
"mongodb" -> lazyValue(LocalRecordConnector),
|
||||
"kafka_vSept2018" -> lazyValue(KafkaMappedConnector_vSept2018),
|
||||
"kafka_vMay2019" -> lazyValue(KafkaMappedConnector_vMay2019),
|
||||
"rest_vMar2019" -> lazyValue(RestConnector_vMar2019),
|
||||
|
||||
@ -114,8 +114,7 @@ import scala.util.{Random, Try}
|
||||
object LocalMappedConnector extends Connector with MdcLoggable {
|
||||
|
||||
// override type AccountType = MappedBankAccount
|
||||
val maxBadLoginAttempts = APIUtil.getPropsValue("max.bad.login.attempts") openOr "10"
|
||||
|
||||
|
||||
val underlyingGuavaCache = CacheBuilder.newBuilder().maximumSize(10000L).build[String, Object]
|
||||
implicit val scalaCache = ScalaCache(GuavaCache(underlyingGuavaCache))
|
||||
val getTransactionsTTL = APIUtil.getPropsValue("connector.cache.ttl.seconds.getTransactions", "0").toInt * 1000 // Miliseconds
|
||||
@ -1892,7 +1891,7 @@ object LocalMappedConnector extends Connector with MdcLoggable {
|
||||
newAccountBalance <- Full(Helper.convertToSmallestCurrencyUnits(fromAccount.balance, currency) + Helper.convertToSmallestCurrencyUnits(amount, currency))
|
||||
|
||||
//Here is the `LocalMappedConnector`, once get this point, fromAccount must be a mappedBankAccount. So can use asInstanceOf....
|
||||
_ <- tryo(fromAccount.asInstanceOf[MappedBankAccount].accountBalance(newAccountBalance).save()) ?~! UpdateBankAccountException
|
||||
_ <- tryo(fromAccount.asInstanceOf[MappedBankAccount].accountBalance(newAccountBalance).save) ?~! UpdateBankAccountException
|
||||
|
||||
mappedTransaction <- tryo(MappedTransaction.create
|
||||
.bank(fromAccount.bankId.value)
|
||||
@ -2047,7 +2046,7 @@ object LocalMappedConnector extends Connector with MdcLoggable {
|
||||
newAccountBalance <- Full(Helper.convertToSmallestCurrencyUnits(fromAccount.balance, currency) + Helper.convertToSmallestCurrencyUnits(amount, currency))
|
||||
|
||||
//Here is the `LocalMappedConnector`, once get this point, fromAccount must be a mappedBankAccount. So can use asInstanceOf....
|
||||
_ <- tryo(fromAccount.asInstanceOf[MappedBankAccount].accountBalance(newAccountBalance).save()) ?~! UpdateBankAccountException
|
||||
_ <- tryo(fromAccount.asInstanceOf[MappedBankAccount].accountBalance(newAccountBalance).save) ?~! UpdateBankAccountException
|
||||
|
||||
mappedTransaction <- tryo(MappedTransaction.create
|
||||
//No matter which type (SANDBOX_TAN,SEPA,FREE_FORM,COUNTERPARTYE), always filled the following nine fields.
|
||||
@ -5070,7 +5069,7 @@ object LocalMappedConnector extends Connector with MdcLoggable {
|
||||
.Currency(reason.currency.getOrElse(""))
|
||||
.DocumentNumber(reason.documentNumber.getOrElse(""))
|
||||
.Description(reason.description.getOrElse(""))
|
||||
.save()
|
||||
.save
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,540 +0,0 @@
|
||||
package code.bankconnectors
|
||||
|
||||
import java.util.{Date, TimeZone}
|
||||
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util._
|
||||
import code.management.ImporterAPI.ImporterTransaction
|
||||
import code.metadata.counterparties.{Counterparties, Metadata, MongoCounterparties}
|
||||
import code.model._
|
||||
import code.model.dataAccess._
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.mongodb.QueryBuilder
|
||||
import com.openbankproject.commons.model._
|
||||
import com.tesobe.model.UpdateBankAccount
|
||||
import net.liftweb.common.{Box, Empty, Failure, Full}
|
||||
import net.liftweb.json.Extraction
|
||||
import net.liftweb.json.JsonAST.JValue
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.util.Helpers._
|
||||
import org.bson.types.ObjectId
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.model.enums.AccountRoutingScheme
|
||||
|
||||
import scala.collection.immutable.List
|
||||
import scala.concurrent._
|
||||
|
||||
private object LocalRecordConnector extends Connector with MdcLoggable {
|
||||
|
||||
implicit override val nameOfConnector = LocalRecordConnector.getClass.getSimpleName
|
||||
|
||||
override def getBankLegacy(bankId : BankId, callContext: Option[CallContext]) =
|
||||
getHostedBank(bankId).map(bank =>(bank, callContext))
|
||||
|
||||
//gets banks handled by this connector
|
||||
override def getBanksLegacy(callContext: Option[CallContext]) =
|
||||
Full(HostedBank.findAll, callContext)
|
||||
|
||||
override def getBankAccountLegacy(bankId : BankId, accountId : AccountId, callContext: Option[CallContext]) : Box[(BankAccount, Option[CallContext])] = {
|
||||
for{
|
||||
bank <- getHostedBank(bankId)
|
||||
account <- bank.getAccount(accountId)
|
||||
} yield (account,callContext)
|
||||
}
|
||||
|
||||
|
||||
override def getCounterpartyFromTransaction(bankId: BankId, accountId : AccountId, counterpartyID : String): Box[Counterparty] = {
|
||||
|
||||
/**
|
||||
* In this implementation (for legacy reasons), the "otherAccountID" is actually the mongodb id of the
|
||||
* "other account metadata" object.
|
||||
*/
|
||||
|
||||
for{
|
||||
objId <- tryo{ new ObjectId(counterpartyID) }
|
||||
otherAccountmetadata <- {
|
||||
//"otherAccountID" is actually the mongodb id of the other account metadata" object.
|
||||
val query = QueryBuilder.
|
||||
start("_id").is(objId)
|
||||
.put("originalPartyBankId").is(bankId.value)
|
||||
.put("originalPartyAccountId").is(accountId.value).get()
|
||||
Metadata.find(query)
|
||||
}
|
||||
} yield{
|
||||
val query = QueryBuilder
|
||||
.start("obp_transaction.other_account.holder").is(otherAccountmetadata.holder.get)
|
||||
// .put("obp_transaction.other_account.number").is(otherAccountmetadata.accountNumber.get)
|
||||
.get()
|
||||
|
||||
val otherAccountFromTransaction : OBPAccount = OBPEnvelope.find(query) match {
|
||||
case Full(envelope) => envelope.obp_transaction.get.other_account.get
|
||||
case _ => {
|
||||
logger.warn("no other account found")
|
||||
OBPAccount.createRecord
|
||||
}
|
||||
}
|
||||
createOtherBankAccount(bankId, accountId, otherAccountmetadata, otherAccountFromTransaction)
|
||||
}
|
||||
}
|
||||
|
||||
override def getCounterpartiesFromTransaction(bankId: BankId, accountId : AccountId) = {
|
||||
|
||||
/**
|
||||
* In this implementation (for legacy reasons), the "otherAccountID" is actually the mongodb id of the
|
||||
* "other account metadata" object.
|
||||
*/
|
||||
|
||||
Full(Counterparties.counterparties.vend.getMetadatas(bankId, accountId).map(meta => {
|
||||
//for legacy reasons some of the data about the "other account" are stored only on the transactions
|
||||
//so we need first to get a transaction that match to have the rest of the data
|
||||
val query = QueryBuilder
|
||||
.start("obp_transaction.other_account.holder").is(meta.getCounterpartyName)
|
||||
// .put("obp_transaction.other_account.number").is(meta.getAccountNumber)
|
||||
.get()
|
||||
|
||||
val otherAccountFromTransaction : OBPAccount = OBPEnvelope.find(query) match {
|
||||
case Full(envelope) => {
|
||||
envelope.obp_transaction.get.other_account.get
|
||||
}
|
||||
case _ => {
|
||||
logger.warn(s"envelope not found for other account ${meta.getCounterpartyId}")
|
||||
OBPAccount.createRecord
|
||||
}
|
||||
}
|
||||
createOtherBankAccount(bankId, accountId, meta, otherAccountFromTransaction)
|
||||
}))
|
||||
}
|
||||
|
||||
override def getTransactionsLegacy(bankId: BankId, accountId: AccountId, callContext: Option[CallContext], queryParams: List[OBPQueryParam]) = {
|
||||
logger.debug("getTransactions for " + bankId + "/" + accountId)
|
||||
val transactions = for{
|
||||
bank <- getHostedBank(bankId)
|
||||
account <- bank.getAccount(accountId)
|
||||
} yield {
|
||||
updateAccountTransactions(bank, account)
|
||||
account.envelopes(queryParams).map(createTransaction(_, account))
|
||||
}
|
||||
transactions.map( transactions => (transactions, callContext))
|
||||
}
|
||||
|
||||
override def getTransactionLegacy(bankId: BankId, accountId : AccountId, transactionId : TransactionId, callContext: Option[CallContext])= {
|
||||
for{
|
||||
bank <- getHostedBank(bankId) ?~! s"Transaction not found: bank $bankId not found"
|
||||
account <- bank.getAccount(accountId) ?~! s"Transaction not found: account $accountId not found"
|
||||
envelope <- OBPEnvelope.find(account.transactionsForAccount.put("transactionId").is(transactionId.value).get)
|
||||
} yield {
|
||||
updateAccountTransactions(bank, account)
|
||||
(createTransaction(envelope,account), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
override protected def makePaymentImpl(fromAccount: BankAccount, toAccount: BankAccount, transactionRequestCommonBody: TransactionRequestCommonBodyJSON, amt: BigDecimal, description: String, transactionRequestType: TransactionRequestType, chargePolicy: String): Box[TransactionId] = {
|
||||
val fromTransAmt = -amt //from account balance should decrease
|
||||
val toTransAmt = amt //to account balance should increase
|
||||
|
||||
//this is the transaction that gets attached to the account of the person making the payment
|
||||
val createdFromTrans = saveNewTransaction(fromAccount, fromTransAmt, description)
|
||||
|
||||
// this creates the transaction that gets attached to the account of the person receiving the payment
|
||||
// saveNewTransaction(toAccount, fromAccount, toTransAmt, description)
|
||||
|
||||
//assumes OBPEnvelope id is what gets used as the Transaction id in the API. If that gets changed, this needs to
|
||||
//be updated (the tests should fail if it doesn't)
|
||||
createdFromTrans.map(t => TransactionId(t.transactionId.get))
|
||||
}
|
||||
|
||||
private def createTransaction(env: OBPEnvelope, theAccount: Account): Transaction = {
|
||||
val transaction: OBPTransaction = env.obp_transaction.get
|
||||
val otherAccount_ = transaction.other_account.get
|
||||
|
||||
val id = TransactionId(env.transactionId.get)
|
||||
val uuid = id.value
|
||||
|
||||
//slight hack required: otherAccount id is, for legacy reasons, the mongodb id of its metadata object
|
||||
//so we have to find that
|
||||
val query = QueryBuilder.start("originalPartyBankId").is(theAccount.bankId.value).
|
||||
put("originalPartyAccountId").is(theAccount.permalink.get).
|
||||
put("accountNumber").is(otherAccount_.number.get).
|
||||
put("holder").is(otherAccount_.holder.get).get
|
||||
|
||||
|
||||
//it's a bit confusing what's going on here, as normally metadata should be automatically generated if
|
||||
//it doesn't exist when an OtherBankAccount object is created. The issue here is that for legacy reasons
|
||||
//otherAccount ids are mongo metadata ids, so the metadata needs to exist before we created the OtherBankAccount
|
||||
//so that we know what id to give it. That's why there's a hardcoded dependency on MongoCounterparties.
|
||||
val metadata = Metadata.find(query) match {
|
||||
case Full(m) => m
|
||||
case _ => MongoCounterparties.createMetadata(
|
||||
theAccount.bankId,
|
||||
theAccount.accountId,
|
||||
otherAccount_.holder.get,
|
||||
otherAccount_.number.get)
|
||||
}
|
||||
|
||||
val otherAccount = new Counterparty(
|
||||
counterpartyId = metadata.getCounterpartyId,
|
||||
counterpartyName = otherAccount_.holder.get,
|
||||
nationalIdentifier = otherAccount_.bank.get.national_identifier.get,
|
||||
otherBankRoutingAddress = None,
|
||||
otherAccountRoutingAddress = Some(otherAccount_.bank.get.IBAN.get),
|
||||
thisAccountId = AccountId(otherAccount_.number.get),
|
||||
thisBankId = BankId(otherAccount_.bank.get.name.get),
|
||||
kind = otherAccount_.kind.get,
|
||||
otherBankRoutingScheme = "",
|
||||
otherAccountRoutingScheme="",
|
||||
otherAccountProvider = "",
|
||||
isBeneficiary = true
|
||||
)
|
||||
val transactionType = transaction.details.get.kind.get
|
||||
val amount = transaction.details.get.value.get.amount.get
|
||||
val currency = transaction.details.get.value.get.currency.get
|
||||
val label = Some(transaction.details.get.label.get)
|
||||
val startDate = transaction.details.get.posted.get
|
||||
val finishDate = transaction.details.get.completed.get
|
||||
val balance = transaction.details.get.new_balance.get.amount.get
|
||||
|
||||
new Transaction(
|
||||
uuid,
|
||||
id,
|
||||
theAccount,
|
||||
otherAccount,
|
||||
transactionType,
|
||||
amount,
|
||||
currency,
|
||||
label,
|
||||
startDate,
|
||||
finishDate,
|
||||
balance)
|
||||
}
|
||||
|
||||
private def saveNewTransaction(account : BankAccount, amount : BigDecimal, description : String) : Box[OBPEnvelope] = {
|
||||
|
||||
val oldBalance = account.balance
|
||||
|
||||
def saveAndUpdateAccountBalance(transactionJS : JValue, thisAccount : BankAccount) : Box[OBPEnvelope] = {
|
||||
|
||||
val envelope: Box[OBPEnvelope] = OBPEnvelope.envelopesFromJValue(transactionJS)
|
||||
|
||||
val account = thisAccount.asInstanceOf[Account]
|
||||
if(envelope.isDefined) {
|
||||
val e : OBPEnvelope = envelope.openOrThrowException(attemptedToOpenAnEmptyBox)
|
||||
logger.debug(s"Updating current balance for ${account.bankName} / ${account.accountNumber} / ${account.accountType}")
|
||||
account.accountBalance(e.obp_transaction.get.details.get.new_balance.get.amount.get).save(true)
|
||||
logger.debug("Saving new transaction")
|
||||
Full(e.save(true))
|
||||
} else {
|
||||
Failure("couldn't save transaction")
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
// otherBank <- Connector.connector.vend.getBank(otherAccount.bankId) ?~! "no other bank found"
|
||||
transTime <- Full(now)
|
||||
//mongodb/the lift mongo thing wants a literal Z in the timestamp, apparently
|
||||
envJsonDateFormat = {
|
||||
val simpleDateFormat = APIUtil.DateWithMsFormat
|
||||
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
|
||||
simpleDateFormat
|
||||
}
|
||||
|
||||
envJson =
|
||||
"obp_transaction" ->
|
||||
("this_account" ->
|
||||
// ("holder" -> account.owners.headOption.map(_.name).getOrElse("")) ~ //TODO: this is rather fragile...
|
||||
("number" -> account.number) ~
|
||||
("kind" -> account.accountType) ~
|
||||
("bank" ->
|
||||
("IBAN" -> account.accountRoutings.find(_.scheme == AccountRoutingScheme.IBAN.toString).map(_.address).getOrElse("")) ~
|
||||
("national_identifier" -> account.nationalIdentifier) ~
|
||||
("name" -> account.bankId.value))) ~
|
||||
// ("other_account" ->
|
||||
//// ("holder" -> otherAccount.accountHolder) ~
|
||||
//// ("number" -> otherAccount.number) ~
|
||||
//// ("kind" -> otherAccount.accountType) ~
|
||||
// ("bank" ->
|
||||
// ("IBAN" -> "") ~
|
||||
//// ("national_identifier" -> otherBank.nationalIdentifier) ~
|
||||
//// ("name" -> otherBank.fullName))) ~
|
||||
("details" ->
|
||||
("type_en" -> "") ~
|
||||
("type_de" -> "") ~
|
||||
("posted" ->
|
||||
("$dt" -> envJsonDateFormat.format(transTime))
|
||||
) ~
|
||||
("completed" ->
|
||||
("$dt" -> envJsonDateFormat.format(transTime))
|
||||
) ~
|
||||
("new_balance" ->
|
||||
("currency" -> account.currency) ~
|
||||
("amount" -> (oldBalance + amount).toString)) ~
|
||||
("value" ->
|
||||
("currency" -> account.currency) ~
|
||||
("amount" -> amount.toString)))
|
||||
saved <- saveAndUpdateAccountBalance(envJson, account)
|
||||
} yield {
|
||||
saved
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the last update of the account was made more than one hour ago.
|
||||
* if it is the case we put a message in the message queue to ask for
|
||||
* transactions updates
|
||||
*
|
||||
* It will be used each time we fetch transactions from the DB. But the test
|
||||
* is performed in a different thread.
|
||||
*/
|
||||
|
||||
private def updateAccountTransactions(bank: HostedBank, account: Account): Unit = {
|
||||
Future {
|
||||
val useMessageQueue = APIUtil.getPropsAsBoolValue("messageQueue.updateBankAccountsTransaction", false)
|
||||
val outDatedTransactions = now after time(account.accountLastUpdate.get.getTime + hours(APIUtil.getPropsAsIntValue("messageQueue.updateTransactionsInterval", 1)))
|
||||
if(outDatedTransactions && useMessageQueue) {
|
||||
UpdatesRequestSender.sendMsg(UpdateBankAccount(account.accountNumber.get, bank.national_identifier.get))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private def createOtherBankAccount(originalPartyBankId: BankId, originalPartyAccountId: AccountId,
|
||||
otherAccount : CounterpartyMetadata, otherAccountFromTransaction : OBPAccount) : Counterparty = {
|
||||
new Counterparty(
|
||||
counterpartyId = otherAccount.getCounterpartyId,
|
||||
counterpartyName = otherAccount.getCounterpartyName,
|
||||
nationalIdentifier = otherAccountFromTransaction.bank.get.national_identifier.get,
|
||||
otherBankRoutingAddress = None,
|
||||
otherAccountRoutingAddress = Some(otherAccountFromTransaction.bank.get.IBAN.get),
|
||||
thisAccountId = AccountId(otherAccountFromTransaction.number.get),
|
||||
thisBankId = BankId(otherAccountFromTransaction.bank.get.name.get),
|
||||
kind = "",
|
||||
otherBankRoutingScheme = "",
|
||||
otherAccountRoutingScheme="",
|
||||
otherAccountProvider = "",
|
||||
isBeneficiary = true
|
||||
)
|
||||
}
|
||||
|
||||
private def getHostedBank(bankId : BankId) : Box[HostedBank] = {
|
||||
HostedBank.find("permalink", bankId.value) ?~ {"bank " + bankId + " not found"}
|
||||
}
|
||||
|
||||
//Need to pass in @hostedBank because the Account model doesn't have any references to BankId, just to the mongo id of the Bank object (which itself does have the bank id)
|
||||
private def createAccount(hostedBank : HostedBank, accountId : AccountId, accountNumber: String,
|
||||
accountType: String, accountLabel: String, currency : String, initialBalance : BigDecimal, holderName : String) : BankAccount = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
Account.find(
|
||||
(Account.accountNumber.name -> accountNumber)~
|
||||
(Account.bankID.name -> hostedBank.id.get)
|
||||
) match {
|
||||
case Full(bankAccount) => {
|
||||
logger.debug(s"account with number ${bankAccount.accountNumber} at bank ${hostedBank.bankId} already exists. No need to create a new one.")
|
||||
bankAccount
|
||||
}
|
||||
case _ => {
|
||||
logger.debug("creating account record ")
|
||||
val bankAccount =
|
||||
Account
|
||||
.createRecord
|
||||
.accountBalance(initialBalance)
|
||||
.holder(holderName)
|
||||
.accountNumber(accountNumber)
|
||||
.kind(accountType)
|
||||
.accountLabel(accountLabel)
|
||||
.accountName("")
|
||||
.permalink(accountId.value)
|
||||
.bankID(hostedBank.id.get)
|
||||
.accountCurrency(currency)
|
||||
.accountIban("")
|
||||
.accountLastUpdate(now)
|
||||
.save(true)
|
||||
bankAccount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//creates a bank account (if it doesn't exist) and creates a bank (if it doesn't exist)
|
||||
override def createBankAndAccount(
|
||||
bankName: String,
|
||||
bankNationalIdentifier: String,
|
||||
accountNumber: String,
|
||||
accountType: String,
|
||||
accountLabel: String,
|
||||
currency: String,
|
||||
accountHolderName: String,
|
||||
branchId: String,
|
||||
accountRoutingScheme: String,
|
||||
accountRoutingAddress: String
|
||||
) = {
|
||||
|
||||
// TODO: use a more unique id for the long term
|
||||
val hostedBank = {
|
||||
// TODO: use a more unique id for the long term
|
||||
HostedBank.find(HostedBank.national_identifier.name, bankNationalIdentifier) match {
|
||||
case Full(b)=> {
|
||||
logger.debug(s"bank ${b.name} found")
|
||||
b
|
||||
}
|
||||
case _ =>{
|
||||
//TODO: if name is empty use bank id as name alias
|
||||
|
||||
//TODO: need to handle the case where generatePermalink returns a permalink that is already used for another bank
|
||||
|
||||
logger.debug(s"creating HostedBank")
|
||||
HostedBank
|
||||
.createRecord
|
||||
.name(bankName)
|
||||
.alias(bankName)
|
||||
.permalink(Helper.generatePermalink(bankName))
|
||||
.national_identifier(bankNationalIdentifier)
|
||||
.save(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val createdAccount = createAccount(hostedBank, AccountId(APIUtil.generateUUID()),
|
||||
accountNumber, accountType, accountLabel, currency, BigDecimal("0.00"), accountHolderName)
|
||||
|
||||
Full((hostedBank, createdAccount))
|
||||
}
|
||||
|
||||
|
||||
//for sandbox use -> allows us to check if we can generate a new test account with the given number
|
||||
override def accountExists(bankId: BankId, accountNumber: String) = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
|
||||
getHostedBank(bankId).map(_.id.get) match {
|
||||
case Full(mongoId) =>
|
||||
Full(Account.count((Account.accountNumber.name -> accountNumber) ~ (Account.bankID.name -> mongoId)) > 0)
|
||||
case _ =>
|
||||
logger.warn("tried to check account existence for an account at a bank that doesn't exist")
|
||||
Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
override def removeAccount(bankId: BankId, accountId: AccountId) = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
for {
|
||||
account <- Account.find((Account.bankID.name -> bankId.value) ~ (Account.accountId.value -> accountId.value)) ?~
|
||||
s"No account found with number ${accountId} at bank with id ${bankId}: could not save envelope"
|
||||
} yield {
|
||||
account.delete_!
|
||||
}
|
||||
|
||||
Full(false)
|
||||
/* account
|
||||
} match {
|
||||
case Full(acc) => acc.
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//creates a bank account for an existing bank, with the appropriate values set
|
||||
override def createSandboxBankAccount(
|
||||
bankId: BankId,
|
||||
accountId: AccountId,
|
||||
accountNumber: String,
|
||||
accountType: String,
|
||||
accountLabel: String,
|
||||
currency: String,
|
||||
initialBalance: BigDecimal,
|
||||
accountHolderName: String,
|
||||
branchId: String,
|
||||
accountRoutings: List[AccountRouting]
|
||||
): Box[BankAccount] = {
|
||||
HostedBank.find(bankId) match {
|
||||
case Full(b) => Full(createAccount(b, accountId, accountNumber, accountType, accountLabel, currency, initialBalance, accountHolderName))
|
||||
case _ => Failure(s"Bank with id ${bankId.value} not found. Cannot create account at non-existing bank.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//used by transaction import api call to check for duplicates
|
||||
override def getMatchingTransactionCount(bankNationalIdentifier : String, accountNumber : String, amount: String, completed: Date, otherAccountHolder: String) = {
|
||||
|
||||
val baseQuery = QueryBuilder.start("obp_transaction.details.value.amount")
|
||||
.is(amount)
|
||||
.put("obp_transaction.details.completed")
|
||||
.is(completed)
|
||||
.put("obp_transaction.this_account.bank.national_identifier")
|
||||
.is(bankNationalIdentifier)
|
||||
.put("obp_transaction.this_account.number")
|
||||
.is(accountNumber)
|
||||
|
||||
//this is refactored legacy code, and it seems the empty account holder check had to do with potentially missing
|
||||
//fields in the db. not sure if this is still required.
|
||||
if(otherAccountHolder.isEmpty){
|
||||
def emptyHolderOrEmptyString(holder: Box[String]): Boolean = {
|
||||
holder match {
|
||||
case Full(s) => s.isEmpty
|
||||
case _ => true
|
||||
}
|
||||
}
|
||||
|
||||
val partialMatches = OBPEnvelope.findAll(baseQuery.get())
|
||||
|
||||
Full(partialMatches.filter(e => {
|
||||
emptyHolderOrEmptyString(e.obp_transaction.get.other_account.get.holder.valueBox)
|
||||
}).size)
|
||||
}
|
||||
else{
|
||||
val qry = baseQuery.put("obp_transaction.other_account.holder").is(otherAccountHolder).get
|
||||
|
||||
val partialMatches = OBPEnvelope.count(qry)
|
||||
Full(partialMatches.toInt)//icky
|
||||
}
|
||||
}
|
||||
|
||||
//used by transaction import api
|
||||
override def createImportedTransaction(transaction: ImporterTransaction): Box[Transaction] = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
|
||||
implicit val formats = CustomJsonFormats.losslessFormats
|
||||
val asJValue = Extraction.decompose(transaction)
|
||||
|
||||
for {
|
||||
env <- OBPEnvelope.envelopesFromJValue(asJValue)
|
||||
nationalIdentifier = transaction.obp_transaction.this_account.bank.national_identifier
|
||||
bank <- HostedBank.find(HostedBank.national_identifier.name -> nationalIdentifier) ?~
|
||||
s"No bank found with national identifier ${nationalIdentifier} could not save envelope"
|
||||
accountNumber = transaction.obp_transaction.this_account.number
|
||||
account <- Account.find((Account.bankID.name -> bank.id.get) ~ (Account.accountNumber.name -> accountNumber)) ?~
|
||||
s"No account found with number ${accountNumber} at bank with id ${bank.bankId}: could not save envelope"
|
||||
savedEnv <- env.saveTheRecord() ?~ "Could not save envelope"
|
||||
} yield {
|
||||
createTransaction(savedEnv, account)
|
||||
}
|
||||
}
|
||||
|
||||
//used by the transaction import api
|
||||
override def updateAccountBalance(bankId: BankId, accountId: AccountId, newBalance: BigDecimal) = {
|
||||
getBankAccountOld(bankId, accountId).map(_.asInstanceOf[Account]) match {
|
||||
case Full(acc) =>
|
||||
acc.accountBalance(newBalance).saveTheRecord().isDefined
|
||||
Full(true)
|
||||
case _ =>
|
||||
Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
override def setBankAccountLastUpdated(bankNationalIdentifier: String, accountNumber : String, updateDate: Date) = {
|
||||
Account.find(
|
||||
(Account.accountNumber.name -> accountNumber)~
|
||||
(Account.nationalIdentifier -> bankNationalIdentifier)
|
||||
) match {
|
||||
case Full(acc) => Full(acc.accountLastUpdate(updateDate).saveTheRecord().isDefined)
|
||||
case _ => logger.warn("can't set bank account.lastUpdated because the account was not found"); Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
override def updateAccountLabel(bankId: BankId, accountId: AccountId, label: String) = {
|
||||
getBankAccountOld(bankId, accountId).map(_.asInstanceOf[Account]) match {
|
||||
case Full(acc) =>
|
||||
acc.accountLabel(label).saveTheRecord().isDefined
|
||||
Full(true)
|
||||
case _ =>
|
||||
Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -110,7 +110,7 @@ object MappedPhysicalCardProvider extends PhysicalCardProvider {
|
||||
.card(v)
|
||||
.saveMe()
|
||||
v.mPinResets += pin
|
||||
v.save()
|
||||
v.save
|
||||
}
|
||||
}
|
||||
case _ => // There is no enough information to set foreign key
|
||||
@ -217,7 +217,7 @@ object MappedPhysicalCardProvider extends PhysicalCardProvider {
|
||||
.card(v)
|
||||
.saveMe()
|
||||
v.mPinResets += pin
|
||||
v.save()
|
||||
v.save
|
||||
}
|
||||
}
|
||||
case _ => // There is no enough information to set foreign key
|
||||
|
||||
@ -33,10 +33,10 @@ trait ConsentProvider {
|
||||
frequencyPerDay: Int,
|
||||
combinedServiceIndicator: Boolean,
|
||||
apiStandard: Option[String],
|
||||
apiVersion: Option[String]): Box[Consent]
|
||||
apiVersion: Option[String]): Box[ConsentTrait]
|
||||
def updateBerlinGroupConsent(
|
||||
consentId: String,
|
||||
usesSoFarTodayCounter: Int): Box[Consent]
|
||||
usesSoFarTodayCounter: Int): Box[ConsentTrait]
|
||||
|
||||
def saveUKConsent(
|
||||
user: Option[User],
|
||||
@ -49,10 +49,10 @@ trait ConsentProvider {
|
||||
transactionToDateTime: Date,
|
||||
apiStandard: Option[String],
|
||||
apiVersion: Option[String]
|
||||
): Box[Consent]
|
||||
): Box[ConsentTrait]
|
||||
}
|
||||
|
||||
trait Consent {
|
||||
trait ConsentTrait {
|
||||
def consentId: String
|
||||
def userId: String
|
||||
def secret: String
|
||||
|
||||
@ -223,7 +223,7 @@ object MappedConsentProvider extends ConsentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
class MappedConsent extends Consent with LongKeyedMapper[MappedConsent] with IdPK with CreatedUpdated {
|
||||
class MappedConsent extends ConsentTrait with LongKeyedMapper[MappedConsent] with IdPK with CreatedUpdated {
|
||||
|
||||
def getSingleton = MappedConsent
|
||||
|
||||
|
||||
@ -318,7 +318,7 @@ object MappedCustomerProvider extends CustomerProvider with MdcLoggable {
|
||||
for {
|
||||
customer <- MappedCustomer.findAll(NullRef(MappedCustomer.mCustomerId))++ MappedCustomer.findAll(By(MappedCustomer.mCustomerId, ""))
|
||||
} yield {
|
||||
customer.mCustomerId(APIUtil.generateUUID()).save()
|
||||
customer.mCustomerId(APIUtil.generateUUID()).save
|
||||
}
|
||||
}.forall(_ == true)
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ object MappedDynamicEntityProvider extends DynamicEntityProvider with CustomJson
|
||||
.HasPersonalEntity(dynamicEntity.hasPersonalEntity)
|
||||
.saveMe()
|
||||
} catch {
|
||||
case e =>
|
||||
case e : Throwable =>
|
||||
logger.error("Create or Update DynamicEntity fail.", e)
|
||||
throw e
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import net.liftweb.util.Helpers._
|
||||
|
||||
object LoginAttempt extends MdcLoggable {
|
||||
|
||||
val maxBadLoginAttempts = APIUtil.getPropsValue("max.bad.login.attempts") openOr "5"
|
||||
def maxBadLoginAttempts = APIUtil.getPropsValue("max.bad.login.attempts") openOr "5"
|
||||
|
||||
def incrementBadLoginAttempts(username: String, provider: String): Unit = {
|
||||
username.isEmpty() match {
|
||||
@ -37,7 +37,7 @@ object LoginAttempt extends MdcLoggable {
|
||||
.Provider(provider)
|
||||
.mLastFailureDate(now)
|
||||
.mBadAttemptsSinceLastSuccessOrReset(1) // Start with 1
|
||||
.save()
|
||||
.save
|
||||
|
||||
logger.debug(s"incrementBadLoginAttempts created loginAttempt")
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ object MappedMeetingProvider extends MeetingProvider {
|
||||
.mStatus(invitee.status)
|
||||
.saveMe()
|
||||
createdMeeting.mInvitees += meetingInvitee
|
||||
createdMeeting.save()
|
||||
createdMeeting.save
|
||||
}} ?~! ErrorMessages.CreateMeetingInviteeException
|
||||
} yield {
|
||||
createdMeeting
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
package code.metadata.comments
|
||||
|
||||
import code.model._
|
||||
import java.util.Date
|
||||
|
||||
import code.util.Helper.MdcLoggable
|
||||
import net.liftweb.common.{Box, Full}
|
||||
import org.bson.types.ObjectId
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
|
||||
private object MongoTransactionComments extends Comments {
|
||||
|
||||
|
||||
def getComments(bankId : BankId, accountId : AccountId, transactionId : TransactionId)(viewId : ViewId) : List[Comment] = {
|
||||
OBPComment.findAll(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
def addComment(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(userId: UserPrimaryKey, viewId : ViewId, text : String, datePosted : Date) : Box[Comment] = {
|
||||
OBPComment.createRecord.userId(userId.value).
|
||||
transactionId(transactionId.value).
|
||||
accountId(accountId.value).
|
||||
bankId(bankId.value).
|
||||
textField(text).
|
||||
date(datePosted).
|
||||
forView(viewId.value).saveTheRecord()
|
||||
}
|
||||
|
||||
def deleteComment(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(commentId : String) : Box[Boolean] = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPComment.delete(OBPComment.getFindQuery(bankId, accountId, transactionId, commentId))
|
||||
|
||||
//we don't have any useful information here so just assume it worked
|
||||
Full(true)
|
||||
}
|
||||
|
||||
def bulkDeleteComments(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
def bulkDeleteCommentsOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
}
|
||||
|
||||
private class OBPComment private() extends MongoRecord[OBPComment] with ObjectIdPk[OBPComment] with Comment {
|
||||
def meta = OBPComment
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
def viewId = ViewId(forView.get)
|
||||
def text = textField.get
|
||||
def datePosted = date.get
|
||||
def id_ = id.get.toString
|
||||
def replyToID = replyTo.get
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object textField extends StringField(this, 255)
|
||||
object date extends DateField(this)
|
||||
object replyTo extends StringField(this,255)
|
||||
}
|
||||
|
||||
private object OBPComment extends OBPComment with MongoMetaRecord[OBPComment] with MdcLoggable {
|
||||
def findAll(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : List[OBPComment] = {
|
||||
val query = QueryBuilder.
|
||||
start("bankId").is(bankId.value).
|
||||
put("accountId").is(accountId.value).
|
||||
put("transactionId").is(transactionId.value).
|
||||
put("forView").is(viewId.value).get
|
||||
findAll(query)
|
||||
}
|
||||
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, commentId : String) : DBObject = {
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
QueryBuilder.start("_id").is(new ObjectId(commentId)).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
@ -290,27 +290,27 @@ object MapperCounterparties extends Counterparties with MdcLoggable {
|
||||
}
|
||||
|
||||
override def addPublicAlias(counterpartyId : String, alias: String): Box[Boolean] = {
|
||||
getCounterpartyMetadata(counterpartyId).map(_.publicAlias(alias).save())
|
||||
getCounterpartyMetadata(counterpartyId).map(_.publicAlias(alias).save)
|
||||
}
|
||||
|
||||
override def addPrivateAlias(counterpartyId : String, alias: String): Box[Boolean] = {
|
||||
getCounterpartyMetadata(counterpartyId).map(_.privateAlias(alias).save())
|
||||
getCounterpartyMetadata(counterpartyId).map(_.privateAlias(alias).save)
|
||||
}
|
||||
|
||||
override def addURL(counterpartyId : String, url: String): Box[Boolean] = {
|
||||
getCounterpartyMetadata(counterpartyId).map(_.url(url).save())
|
||||
getCounterpartyMetadata(counterpartyId).map(_.url(url).save)
|
||||
}
|
||||
|
||||
override def addImageURL(counterpartyId : String, url: String): Box[Boolean] = {
|
||||
getCounterpartyMetadata(counterpartyId).map(_.imageUrl(url).save())
|
||||
getCounterpartyMetadata(counterpartyId).map(_.imageUrl(url).save)
|
||||
}
|
||||
|
||||
override def addOpenCorporatesURL(counterpartyId : String, url: String): Box[Boolean] = {
|
||||
getCounterpartyMetadata(counterpartyId).map(_.openCorporatesUrl(url).save())
|
||||
getCounterpartyMetadata(counterpartyId).map(_.openCorporatesUrl(url).save)
|
||||
}
|
||||
|
||||
override def addMoreInfo(counterpartyId : String, moreInfo: String): Box[Boolean] = {
|
||||
getCounterpartyMetadata(counterpartyId).map(_.moreInfo(moreInfo).save())
|
||||
getCounterpartyMetadata(counterpartyId).map(_.moreInfo(moreInfo).save)
|
||||
}
|
||||
|
||||
override def addPhysicalLocation(counterpartyId : String, userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double): Box[Boolean] = {
|
||||
@ -372,7 +372,7 @@ class MappedCounterpartyMetadata extends CounterpartyMetadata with LongKeyedMapp
|
||||
private def trySave(f : => Any) : Boolean =
|
||||
tryo{
|
||||
f
|
||||
save()
|
||||
save
|
||||
}.getOrElse(false)
|
||||
|
||||
private def setWhere(whereTag : Box[MappedCounterpartyWhereTag])
|
||||
|
||||
@ -1,182 +0,0 @@
|
||||
package code.metadata.counterparties
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util.CallContext
|
||||
import code.model._
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.mongodb.QueryBuilder
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.common.{Box, Empty, Full}
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
import org.bson.types.ObjectId
|
||||
|
||||
object MongoCounterparties extends Counterparties with MdcLoggable {
|
||||
|
||||
|
||||
def getMetadatas(originalPartyBankId: BankId, originalPartyAccountId : AccountId) : List[CounterpartyMetadata] = {
|
||||
val query = QueryBuilder.start("originalPartyBankId").is(originalPartyBankId.value).put("originalPartyAccountId").is(originalPartyAccountId.value).get
|
||||
Metadata.findAll(query)
|
||||
}
|
||||
|
||||
def getMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, counterpartyMetadataId : String) : Box[CounterpartyMetadata] = {
|
||||
/**
|
||||
* This particular implementation requires the metadata id to be the same as the otherParty (OtherBankAccount) id
|
||||
*/
|
||||
for {
|
||||
objId <- tryo { new ObjectId(counterpartyMetadataId) }
|
||||
query = QueryBuilder.start("originalPartyBankId").is(originalPartyBankId.value).put("originalPartyAccountId").is(originalPartyAccountId.value).
|
||||
put("_id").is(objId).get()
|
||||
m <- Metadata.find(query)
|
||||
} yield m
|
||||
}
|
||||
|
||||
def deleteMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, counterpartyMetadataId: String): Box[Boolean] = Empty
|
||||
|
||||
def getOrCreateMetadata(bankId: BankId, accountId : AccountId, counterpartyId:String, counterpartyName:String) : Box[CounterpartyMetadata] = {
|
||||
|
||||
/**
|
||||
* This particular implementation requires the metadata id to be the same as the otherParty (OtherBankAccount) id
|
||||
*/
|
||||
|
||||
val existing = getMetadata(bankId, accountId, counterpartyId)
|
||||
|
||||
val metadata = existing match {
|
||||
case Full(m) => m
|
||||
case _ => createMetadata(bankId, accountId, counterpartyName, counterpartyId)
|
||||
}
|
||||
|
||||
Full(metadata)
|
||||
}
|
||||
|
||||
/**
|
||||
* This only exists for OBPEnvelope. Avoid using it for any other reason outside of this class
|
||||
*/
|
||||
def createMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, otherAccountHolder : String, counterpartyId : String) : Metadata = {
|
||||
//create it
|
||||
if(otherAccountHolder.isEmpty){
|
||||
logger.info("other account holder is Empty. creating a metadata record with private alias")
|
||||
//no holder name, nothing to hide, so we don't need to create a public alias
|
||||
Metadata
|
||||
.createRecord
|
||||
.counterpartyId(counterpartyId)
|
||||
.originalPartyBankId(originalPartyBankId.value)
|
||||
.originalPartyAccountId(originalPartyAccountId.value)
|
||||
// .accountNumber(otherAccountNumber)
|
||||
.holder("")
|
||||
.save(true)
|
||||
|
||||
} else {
|
||||
Metadata.createRecord.
|
||||
counterpartyId(counterpartyId).
|
||||
originalPartyBankId(originalPartyBankId.value).
|
||||
originalPartyAccountId(originalPartyAccountId.value).
|
||||
holder(otherAccountHolder).
|
||||
// accountNumber(otherAccountNumber).
|
||||
publicAlias(newPublicAliasName(originalPartyBankId, originalPartyAccountId)).save(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new alias name that is guaranteed not to collide with any existing public alias names
|
||||
* for the account in question
|
||||
*/
|
||||
def newPublicAliasName(originalPartyBankId : BankId, originalPartyAccountId : AccountId): String = {
|
||||
import scala.util.Random
|
||||
|
||||
val firstAliasAttempt = "ALIAS_" + Random.nextLong().toString.take(6)
|
||||
|
||||
/**
|
||||
* Returns true if @publicAlias is already the name of a public alias within @account
|
||||
*/
|
||||
def isDuplicate(publicAlias: String) = {
|
||||
val query = QueryBuilder.start("originalPartyBankId").is(originalPartyBankId.value).put("originalPartyAccountId").is(originalPartyAccountId.value).get()
|
||||
Metadata.findAll(query).exists(m => {
|
||||
m.publicAlias.get == publicAlias
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends things to @publicAlias until it a unique public alias name within @account
|
||||
*/
|
||||
def appendUntilUnique(publicAlias: String): String = {
|
||||
val newAlias = publicAlias + Random.nextLong().toString.take(1)
|
||||
if (isDuplicate(newAlias)) appendUntilUnique(newAlias)
|
||||
else newAlias
|
||||
}
|
||||
|
||||
if (isDuplicate(firstAliasAttempt)) appendUntilUnique(firstAliasAttempt)
|
||||
else firstAliasAttempt
|
||||
}
|
||||
|
||||
override def getCounterparty(counterpartyId : String): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def deleteCounterparty(counterpartyId : String): Box[Boolean] = Empty
|
||||
|
||||
override def getCounterpartyByIban(iban : String): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterpartyByIbanAndBankAccountId(iban : String, bankId: BankId, accountId: AccountId): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterpartyByRoutings(
|
||||
otherBankRoutingScheme: String,
|
||||
otherBankRoutingAddress: String,
|
||||
otherBranchRoutingScheme: String,
|
||||
otherBranchRoutingAddress: String,
|
||||
otherAccountRoutingScheme: String,
|
||||
otherAccountRoutingAddress: String
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterpartyBySecondaryRouting(
|
||||
otherAccountSecondaryRoutingScheme: String,
|
||||
otherAccountSecondaryRoutingAddress: String
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def createCounterparty(
|
||||
createdByUserId: String,
|
||||
thisBankId: String,
|
||||
thisAccountId: String,
|
||||
thisViewId: String,
|
||||
name: String,
|
||||
otherAccountRoutingScheme: String,
|
||||
otherAccountRoutingAddress: String,
|
||||
otherBankRoutingScheme: String,
|
||||
otherBankRoutingAddress: String,
|
||||
otherBranchRoutingScheme: String,
|
||||
otherBranchRoutingAddress: String,
|
||||
isBeneficiary: Boolean,
|
||||
otherAccountSecondaryRoutingScheme: String,
|
||||
otherAccountSecondaryRoutingAddress: String,
|
||||
description: String,
|
||||
currency: String,
|
||||
bespoke: List[CounterpartyBespoke]
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def checkCounterpartyExists(
|
||||
name: String,
|
||||
thisBankId: String,
|
||||
thisAccountId: String,
|
||||
thisViewId: String
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterparties(thisBankId: BankId, thisAccountId: AccountId, viewId: ViewId): Box[List[CounterpartyTrait]] = ???
|
||||
|
||||
override def addPublicAlias(counterpartyId : String, alias: String): Box[Boolean] = ???
|
||||
override def addPrivateAlias(counterpartyId : String, alias: String): Box[Boolean] = ???
|
||||
override def addURL(counterpartyId : String, url: String): Box[Boolean] = ???
|
||||
override def addImageURL(counterpartyId : String, imageUrl: String): Box[Boolean] = ???
|
||||
override def addOpenCorporatesURL(counterpartyId : String, url: String): Box[Boolean] = ???
|
||||
override def addMoreInfo(counterpartyId : String, moreInfo: String): Box[Boolean] = ???
|
||||
override def addPhysicalLocation(counterpartyId : String, userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double): Box[Boolean] = ???
|
||||
override def addCorporateLocation(counterpartyId : String, userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double): Box[Boolean] = ???
|
||||
override def deletePhysicalLocation(counterpartyId : String): Box[Boolean] = ???
|
||||
override def deleteCorporateLocation(counterpartyId : String): Box[Boolean] = ???
|
||||
override def getCorporateLocation(counterpartyId : String): Box[GeoTag] = ???
|
||||
override def getPhysicalLocation(counterpartyId : String): Box[GeoTag] = ???
|
||||
override def getOpenCorporatesURL(counterpartyId : String): Box[String] = ???
|
||||
override def getImageURL(counterpartyId : String): Box[String] = ???
|
||||
override def getUrl(counterpartyId : String): Box[String] = ???
|
||||
override def getMoreInfo(counterpartyId : String): Box[String] = ???
|
||||
override def getPublicAlias(counterpartyId : String): Box[String] = ???
|
||||
override def getPrivateAlias(counterpartyId : String): Box[String] = ???
|
||||
override def bulkDeleteAllCounterparties(): Box[Boolean] = ???
|
||||
}
|
||||
@ -1,156 +0,0 @@
|
||||
package code.metadata.counterparties
|
||||
|
||||
|
||||
import code.model.UserX
|
||||
import net.liftweb.mongodb.record.{BsonMetaRecord, BsonRecord, MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.ObjectIdPk
|
||||
import net.liftweb.record.field.StringField
|
||||
import com.openbankproject.commons.model.{CounterpartyMetadata, GeoTag, UserPrimaryKey}
|
||||
//TODO: this should be private
|
||||
class Metadata private() extends CounterpartyMetadata with MongoRecord[Metadata] with ObjectIdPk[Metadata] {
|
||||
import net.liftweb.mongodb.record.field.BsonRecordField
|
||||
import java.util.Date
|
||||
|
||||
def meta = Metadata
|
||||
|
||||
//originalPartyBankId and originalPartyAccountId are used to identify the account
|
||||
//which has the counterparty this metadata is associated with
|
||||
object originalPartyBankId extends StringField(this, 100)
|
||||
object originalPartyAccountId extends StringField(this, 100)
|
||||
object counterpartyId extends StringField(this,100)
|
||||
|
||||
object holder extends StringField(this, 255)
|
||||
// object accountNumber extends StringField(this, 100)
|
||||
object publicAlias extends StringField(this, 100)
|
||||
object privateAlias extends StringField(this, 100)
|
||||
object moreInfo extends StringField(this, 100)
|
||||
object url extends StringField(this, 100)
|
||||
object imageUrl extends StringField(this, 100)
|
||||
object openCorporatesUrl extends StringField(this, 100) {
|
||||
override def optional_? = true
|
||||
}
|
||||
object corporateLocation extends BsonRecordField(this, OBPGeoTag)
|
||||
object physicalLocation extends BsonRecordField(this, OBPGeoTag)
|
||||
|
||||
def addCorporateLocationFn(userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double) : Boolean = {
|
||||
val newTag = OBPGeoTag.createRecord.
|
||||
userId(userId.value).
|
||||
date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude)
|
||||
corporateLocation(newTag).saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
def deleteCorporateLocationFn : Boolean = {
|
||||
corporateLocation.clear
|
||||
this.saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
def addPhysicalLocationFn(userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double) : Boolean = {
|
||||
val newTag = OBPGeoTag.createRecord.
|
||||
userId(userId.value).
|
||||
date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude)
|
||||
physicalLocation(newTag).saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
def deletePhysicalLocationFn : Boolean = {
|
||||
physicalLocation.clear
|
||||
this.saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
private def locationTag(loc: OBPGeoTag): Option[GeoTag]={
|
||||
if(loc.longitude==0 && loc.latitude==0)
|
||||
None
|
||||
else
|
||||
Some(loc)
|
||||
}
|
||||
|
||||
override def getCounterpartyId = counterpartyId.get
|
||||
override def getCounterpartyName = holder.get
|
||||
// override def getAccountNumber = accountNumber.get
|
||||
override def getUrl = url.get
|
||||
override def getCorporateLocation = locationTag(corporateLocation.get)
|
||||
override def getPhysicalLocation = locationTag(physicalLocation.get)
|
||||
override val deleteCorporateLocation = deleteCorporateLocationFn _
|
||||
override val deletePhysicalLocation = deletePhysicalLocationFn _
|
||||
override def getPrivateAlias = privateAlias.get
|
||||
override def getPublicAlias = publicAlias.get
|
||||
override def getMoreInfo = moreInfo.get
|
||||
override def getImageURL: String = imageUrl.get
|
||||
override val addPrivateAlias: (String) => Boolean = (alias => {
|
||||
privateAlias(alias).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addURL: (String) => Boolean = (text => {
|
||||
url(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addPhysicalLocation: (UserPrimaryKey, Date, Double, Double) => Boolean = addPhysicalLocationFn _
|
||||
override val addCorporateLocation: (UserPrimaryKey, Date, Double, Double) => Boolean = addCorporateLocationFn _
|
||||
override val addMoreInfo: (String) => Boolean = (text => {
|
||||
moreInfo(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override def getOpenCorporatesURL: String = openCorporatesUrl.get
|
||||
override val addPublicAlias: (String) => Boolean = (alias => {
|
||||
publicAlias(alias).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addOpenCorporatesURL: (String) => Boolean = (text => {
|
||||
openCorporatesUrl(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addImageURL: (String) => Boolean = (text => {
|
||||
imageUrl(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
//TODO: this should be private
|
||||
object Metadata extends Metadata with MongoMetaRecord[Metadata]
|
||||
|
||||
class OBPGeoTag private() extends BsonRecord[OBPGeoTag] with GeoTag {
|
||||
import com.openbankproject.commons.model.User
|
||||
import net.liftweb.record.field.{DoubleField, LongField}
|
||||
import net.liftweb.mongodb.record.field.DateField
|
||||
|
||||
def meta = OBPGeoTag
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object date extends DateField(this)
|
||||
|
||||
object geoLongitude extends DoubleField(this,0)
|
||||
object geoLatitude extends DoubleField(this,0)
|
||||
|
||||
override def datePosted = date.get
|
||||
override def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
override def longitude = geoLongitude.get
|
||||
override def latitude = geoLatitude.get
|
||||
|
||||
}
|
||||
//TODO: this should be private
|
||||
object OBPGeoTag extends OBPGeoTag with BsonMetaRecord[OBPGeoTag]
|
||||
@ -1,78 +0,0 @@
|
||||
package code.metadata.narrative
|
||||
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.ObjectIdPk
|
||||
import net.liftweb.record.field.StringField
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, TransactionId}
|
||||
|
||||
private object MongoTransactionNarrative extends Narrative {
|
||||
|
||||
def getNarrative(bankId: BankId, accountId: AccountId, transactionId: TransactionId)() : String = {
|
||||
OBPNarrative.find(OBPNarrative.getFindQuery(bankId, accountId, transactionId)) match {
|
||||
case Full(n) => n.narrative.get
|
||||
case _ => ""
|
||||
}
|
||||
}
|
||||
|
||||
def setNarrative(bankId: BankId, accountId: AccountId, transactionId: TransactionId)(narrative: String) : Boolean = {
|
||||
|
||||
val findQuery = OBPNarrative.getFindQuery(bankId, accountId, transactionId)
|
||||
|
||||
if(narrative.isEmpty) {
|
||||
//if we're setting the value of the narrative to "" then we can just delete it
|
||||
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPNarrative.delete(findQuery)
|
||||
} else {
|
||||
|
||||
//avoiding upsert for now as it seemed to behave a little strangely
|
||||
val found = OBPNarrative.find(findQuery)
|
||||
found match {
|
||||
case Full(f) => f.narrative(narrative).save(true)
|
||||
case _ => {
|
||||
OBPNarrative.createRecord
|
||||
.transactionId(transactionId.value)
|
||||
.accountId(accountId.value)
|
||||
.bankId(bankId.value)
|
||||
.narrative(narrative).save(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//we don't have any useful information here so just assume it worked
|
||||
true
|
||||
}
|
||||
|
||||
override def bulkDeleteNarrativeOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId): Boolean = ???
|
||||
|
||||
override def bulkDeleteNarratives(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
|
||||
}
|
||||
|
||||
private class OBPNarrative private() extends MongoRecord[OBPNarrative] with ObjectIdPk[OBPNarrative] {
|
||||
|
||||
def meta = OBPNarrative
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object narrative extends StringField(this, 255)
|
||||
}
|
||||
|
||||
private object OBPNarrative extends OBPNarrative with MongoMetaRecord[OBPNarrative] {
|
||||
|
||||
def init = createIndex((transactionId.name -> 1) ~ (accountId.name -> 1) ~ (bankId.name -> 1), true)
|
||||
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId) : DBObject = {
|
||||
QueryBuilder.start("bankId").is(bankId.value).put("accountId").is(accountId.value).put("transactionId").is(transactionId.value).get
|
||||
}
|
||||
}
|
||||
|
||||
object OBPNarrativeInit {
|
||||
def init = OBPNarrative.init
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
package code.metadata.tags
|
||||
|
||||
import code.model._
|
||||
import java.util.Date
|
||||
|
||||
import code.util.Helper
|
||||
import net.liftweb.common.{Box, Full}
|
||||
import org.bson.types.ObjectId
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
private object MongoTransactionTags extends Tags {
|
||||
|
||||
def getTags(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(viewId : ViewId) : List[TransactionTag] = {
|
||||
OBPTag.findAll(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
def getTagsOnAccount(bankId : BankId, accountId : AccountId)(viewId : ViewId) : List[TransactionTag] = {
|
||||
OBPTag.findAll(bankId, accountId, TransactionId(""), viewId)
|
||||
}
|
||||
def addTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag] = {
|
||||
OBPTag.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
transactionId(transactionId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
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))
|
||||
|
||||
//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 = ???
|
||||
def bulkDeleteTagsOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class OBPTag private() extends MongoRecord[OBPTag] with ObjectIdPk[OBPTag] with TransactionTag {
|
||||
def meta = OBPTag
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object tag extends StringField(this, 255)
|
||||
object date extends DateField(this)
|
||||
|
||||
def id_ = id.get.toString
|
||||
def datePosted = date.get
|
||||
def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
def viewId = ViewId(forView.get)
|
||||
def value = tag.get
|
||||
}
|
||||
|
||||
private object OBPTag extends OBPTag with MongoMetaRecord[OBPTag] {
|
||||
def findAll(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : List[OBPTag] = {
|
||||
val query = QueryBuilder.
|
||||
start("bankId").is(bankId.value).
|
||||
put("accountId").is(accountId.value).
|
||||
put("transactionId").is(transactionId.value).
|
||||
put("forView").is(viewId.value).get
|
||||
findAll(query)
|
||||
}
|
||||
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, tagId : String) : DBObject = {
|
||||
QueryBuilder.start("_id").is(new ObjectId(tagId)).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
package code.metadata.transactionimages
|
||||
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import net.liftweb.common.Box
|
||||
import code.util.Helper.MdcLoggable
|
||||
import java.net.URL
|
||||
import java.util.Date
|
||||
|
||||
import org.bson.types.ObjectId
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
import net.liftweb.util.Helpers._
|
||||
import net.liftweb.common.Full
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
private object MongoTransactionImages extends TransactionImages with MdcLoggable {
|
||||
|
||||
def getImagesForTransaction(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(viewId : ViewId) : List[TransactionImage] = {
|
||||
OBPTransactionImage.findAll(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
|
||||
def addTransactionImage(bankId : BankId, accountId : AccountId, transactionId: TransactionId)
|
||||
(userId: UserPrimaryKey, viewId : ViewId, description : String, datePosted : Date, imageURL: String) : Box[TransactionImage] = {
|
||||
OBPTransactionImage.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
transactionId(transactionId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
imageComment(description).
|
||||
date(datePosted).
|
||||
url(imageURL.toString).saveTheRecord()
|
||||
}
|
||||
|
||||
def deleteTransactionImage(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(imageId : String) : Box[Boolean] = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPTransactionImage.delete(OBPTransactionImage.getFindQuery(bankId, accountId, transactionId, imageId))
|
||||
|
||||
//we don't have any useful information here so just assume it worked
|
||||
Full(true)
|
||||
}
|
||||
|
||||
def bulkDeleteImagesOnTransaction(bankId : BankId, accountId : AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
def bulkDeleteTransactionImage(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
|
||||
}
|
||||
|
||||
private class OBPTransactionImage private() extends MongoRecord[OBPTransactionImage]
|
||||
with ObjectIdPk[OBPTransactionImage] with TransactionImage {
|
||||
def meta = OBPTransactionImage
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object imageComment extends StringField(this, 1000)
|
||||
object date extends DateField(this)
|
||||
object url extends StringField(this, 500)
|
||||
|
||||
def id_ = id.get.toString
|
||||
def datePosted = date.get
|
||||
def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
def viewId = ViewId(forView.get)
|
||||
def description = imageComment.get
|
||||
def imageUrl = {
|
||||
tryo {new URL(url.get)} getOrElse OBPTransactionImage.notFoundUrl
|
||||
}
|
||||
}
|
||||
|
||||
private object OBPTransactionImage extends OBPTransactionImage with MongoMetaRecord[OBPTransactionImage] {
|
||||
val notFoundUrl = new URL("http://example.com/notfound.png") //TODO: Make this image exist?
|
||||
|
||||
def findAll(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : List[OBPTransactionImage] = {
|
||||
val query = QueryBuilder.
|
||||
start("bankId").is(bankId.value).
|
||||
put("accountId").is(accountId.value).
|
||||
put("transactionId").is(transactionId.value).
|
||||
put("forView").is(viewId.value).get
|
||||
findAll(query)
|
||||
}
|
||||
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, imageId : String) : DBObject = {
|
||||
QueryBuilder.start("_id").is(new ObjectId(imageId)).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
package code.metadata.wheretags
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model._
|
||||
import net.liftweb.common.{Box, Full}
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
|
||||
private object MongoTransactionWhereTags extends WhereTags with MdcLoggable {
|
||||
|
||||
def addWhereTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)
|
||||
(userId: UserPrimaryKey, viewId : ViewId, datePosted : Date, longitude : Double, latitude : Double) : Boolean = {
|
||||
|
||||
//avoiding upsert for now as it seemed to behave a little strangely
|
||||
val findQuery = OBPWhereTag.getFindQuery(bankId, accountId, transactionId, viewId)
|
||||
val found = OBPWhereTag.find(findQuery)
|
||||
found match {
|
||||
case Full(f) => {
|
||||
f.date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude).save(true)
|
||||
}
|
||||
case _ => {
|
||||
OBPWhereTag.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
transactionId(transactionId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude).save(true)
|
||||
}
|
||||
}
|
||||
//we don't have any useful information here so just return true
|
||||
true
|
||||
}
|
||||
|
||||
def deleteWhereTag(bankId: BankId, accountId: AccountId, transactionId: TransactionId)(viewId: ViewId): Boolean = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPWhereTag.delete(OBPWhereTag.getFindQuery(bankId, accountId, transactionId, viewId))
|
||||
|
||||
//we don't have any useful information here so just return true
|
||||
true
|
||||
}
|
||||
|
||||
def getWhereTagForTransaction(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(viewId : ViewId) : Box[GeoTag] = {
|
||||
OBPWhereTag.find(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
|
||||
def bulkDeleteWhereTagsOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
|
||||
def bulkDeleteWhereTags(bankId: BankId, accountId: AccountId) : Boolean = ???
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package code.metadata.wheretags
|
||||
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{DoubleField, LongField, StringField}
|
||||
import code.model._
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
private class OBPWhereTag private() extends MongoRecord[OBPWhereTag] with ObjectIdPk[OBPWhereTag] with GeoTag {
|
||||
def meta = OBPWhereTag
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object date extends DateField(this)
|
||||
|
||||
object geoLongitude extends DoubleField(this,0)
|
||||
object geoLatitude extends DoubleField(this,0)
|
||||
|
||||
override def datePosted = date.get
|
||||
override def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
override def longitude = geoLongitude.get
|
||||
override def latitude = geoLatitude.get
|
||||
}
|
||||
|
||||
private object OBPWhereTag extends OBPWhereTag with MongoMetaRecord[OBPWhereTag] {
|
||||
|
||||
def init = createIndex((transactionId.name -> 1) ~ (accountId.name -> 1) ~ (bankId.name -> 1) ~ (forView.name -> 1), true)
|
||||
|
||||
def find(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : Option[OBPWhereTag] = {
|
||||
val query = getFindQuery(bankId, accountId, transactionId, viewId)
|
||||
find(query)
|
||||
}
|
||||
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : DBObject = {
|
||||
QueryBuilder.start("forView").is(viewId.value).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
|
||||
object OBPWhereTagInit {
|
||||
def init = OBPWhereTag.init
|
||||
}
|
||||
@ -295,7 +295,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{
|
||||
val result = scalikeDB readOnly { implicit session =>
|
||||
val sqlResult =
|
||||
sql"""SELECT count(*), avg(duration), min(duration), max(duration)
|
||||
FROM mappedmetric
|
||||
FROM metric
|
||||
WHERE date_c >= ${new Timestamp(fromDate.get.getTime)}
|
||||
AND date_c <= ${new Timestamp(toDate.get.getTime)}
|
||||
AND (${trueOrFalse(consumerId.isEmpty)} or consumerid = ${consumerId.getOrElse("")})
|
||||
@ -378,8 +378,8 @@ object MappedMetrics extends APIMetrics with MdcLoggable{
|
||||
// TODO Make it work in case of Oracle database
|
||||
val otherDbLimit = if (dbUrl.contains("sqlserver")) sqls"" else sqls"LIMIT $limit"
|
||||
val sqlResult =
|
||||
sql"""SELECT ${msSqlLimit} count(*), mappedmetric.implementedbypartialfunction, mappedmetric.implementedinversion
|
||||
FROM mappedmetric
|
||||
sql"""SELECT ${msSqlLimit} count(*), metric.implementedbypartialfunction, metric.implementedinversion
|
||||
FROM metric
|
||||
WHERE
|
||||
date_c >= ${new Timestamp(fromDate.get.getTime)} AND
|
||||
date_c <= ${new Timestamp(toDate.get.getTime)}
|
||||
@ -395,7 +395,7 @@ object MappedMetrics extends APIMetrics with MdcLoggable{
|
||||
AND (${trueOrFalse(excludeUrlPatterns.isEmpty) } or (url NOT LIKE ($excludeUrlPatternsQueries)))
|
||||
AND (${trueOrFalse(excludeAppNames.isEmpty) } or appname not in ($extendedExclueAppNameQueries))
|
||||
AND (${trueOrFalse(excludeImplementedByPartialFunctions.isEmpty) } or implementedbypartialfunction not in ($extendedExcludeImplementedByPartialFunctionsQueries))
|
||||
GROUP BY mappedmetric.implementedbypartialfunction, mappedmetric.implementedinversion
|
||||
GROUP BY metric.implementedbypartialfunction, metric.implementedinversion
|
||||
ORDER BY count(*) DESC
|
||||
${otherDbLimit}
|
||||
""".stripMargin
|
||||
@ -457,10 +457,10 @@ object MappedMetrics extends APIMetrics with MdcLoggable{
|
||||
|
||||
val result: List[TopConsumer] = scalikeDB readOnly { implicit session =>
|
||||
val sqlResult =
|
||||
sql"""SELECT ${msSqlLimit} count(*) as count, consumer.id as consumerprimaryid, mappedmetric.appname as appname,
|
||||
sql"""SELECT ${msSqlLimit} count(*) as count, consumer.id as consumerprimaryid, metric.appname as appname,
|
||||
consumer.developeremail as email, consumer.consumerid as consumerid
|
||||
FROM mappedmetric, consumer
|
||||
WHERE mappedmetric.appname = consumer.name
|
||||
FROM metric, consumer
|
||||
WHERE metric.appname = consumer.name
|
||||
AND date_c >= ${new Timestamp(fromDate.get.getTime)}
|
||||
AND date_c <= ${new Timestamp(toDate.get.getTime)}
|
||||
AND (${trueOrFalse(consumerId.isEmpty)} or consumer.consumerid = ${consumerId.getOrElse("")})
|
||||
|
||||
@ -1,122 +0,0 @@
|
||||
/**
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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.metrics
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util.OBPQueryParam
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.mongodb.record.field.{DateField, LongPk}
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.record.field.{IntField, LongField, StringField}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
private class MongoAPIMetric extends MongoRecord[MongoAPIMetric] with LongPk[MongoAPIMetric] with APIMetric {
|
||||
def meta = MongoAPIMetric
|
||||
object userId extends StringField(this,255)
|
||||
object url extends StringField(this,255)
|
||||
object date extends DateField(this)
|
||||
object duration extends LongField(this)
|
||||
object userName extends StringField(this,255)
|
||||
object appName extends StringField(this,255)
|
||||
object developerEmail extends StringField(this,255)
|
||||
//The consumerId, Foreign key to Consumer not key
|
||||
object consumerId extends StringField(this,255)
|
||||
//name of the Scala Partial Function being used for the endpoint
|
||||
object implementedByPartialFunction extends StringField(this,255)
|
||||
//name of version where the call is implemented) -- S.request.get.view
|
||||
object implementedInVersion extends StringField(this,255)
|
||||
//(GET, POST etc.) --S.request.get.requestType
|
||||
object verb extends StringField(this,255)
|
||||
object httpCode extends IntField(this)
|
||||
object correlationId extends StringField(this,255)
|
||||
|
||||
|
||||
def getMetricId(): Long = id.get
|
||||
def getUrl() = url.get
|
||||
def getDate() = date.get
|
||||
def getDuration(): Long = duration.get
|
||||
def getUserId() = userId.get
|
||||
def getUserName(): String = userName.get
|
||||
def getAppName(): String = appName.get
|
||||
def getDeveloperEmail(): String = developerEmail.get
|
||||
override def getConsumerId(): String = consumerId.get
|
||||
override def getImplementedByPartialFunction(): String = implementedByPartialFunction.get
|
||||
override def getImplementedInVersion(): String = implementedInVersion.get
|
||||
override def getVerb(): String = verb.get
|
||||
override def getHttpCode(): Int = httpCode.get
|
||||
override def getCorrelationId(): String = correlationId.get
|
||||
}
|
||||
|
||||
private object MongoAPIMetric extends MongoAPIMetric with MongoMetaRecord[MongoAPIMetric] with APIMetrics {
|
||||
|
||||
def saveMetric(userId: String, url: String, date: Date, duration: Long, userName: String, appName: String, developerEmail: String, consumerId: String, implementedByPartialFunction: String, implementedInVersion: String, verb: String, httpCode: Option[Int], correlationId: String): Unit = {
|
||||
MongoAPIMetric.createRecord.
|
||||
userId(userId).
|
||||
url(url).
|
||||
date(date).
|
||||
duration(duration).
|
||||
userName(userName).
|
||||
appName(appName).
|
||||
developerEmail(developerEmail).
|
||||
consumerId(consumerId).
|
||||
implementedByPartialFunction(implementedByPartialFunction).
|
||||
implementedInVersion(implementedInVersion).
|
||||
verb(verb).
|
||||
correlationId(correlationId)
|
||||
saveTheRecord()
|
||||
}
|
||||
override def saveMetricsArchive(primaryKey: Long, userId: String, url: String, date: Date, duration: Long, userName: String, appName: String, developerEmail: String, consumerId: String, implementedByPartialFunction: String, implementedInVersion: String, verb: String, httpCode: Option[Int], correlationId: String): Unit = ???
|
||||
|
||||
|
||||
// def getAllGroupedByUrl() : Map[String, List[APIMetric]] = {
|
||||
// MongoAPIMetric.findAll.groupBy[String](_.url.get)
|
||||
// }
|
||||
//
|
||||
// def getAllGroupedByDay() : Map[Date, List[APIMetric]] = {
|
||||
// MongoAPIMetric.findAll.groupBy[Date](APIMetrics.getMetricDay)
|
||||
// }
|
||||
//
|
||||
// def getAllGroupedByUserId() : Map[String, List[APIMetric]] = {
|
||||
// MongoAPIMetric.findAll.groupBy[String](_.getUserId)
|
||||
// }
|
||||
|
||||
override def getAllMetrics(queryParams: List[OBPQueryParam]): List[APIMetric] = {
|
||||
MongoAPIMetric.findAll
|
||||
}
|
||||
|
||||
override def bulkDeleteMetrics(): Boolean = ???
|
||||
|
||||
override def getAllAggregateMetricsFuture(queryParams: List[OBPQueryParam]): Future[Box[List[AggregateMetrics]]] = ???
|
||||
|
||||
override def getTopApisFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopApi]]] = ???
|
||||
|
||||
override def getTopConsumersFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopConsumer]]] = ???
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@ object MappedMigrationScriptLogProvider extends MigrationScriptLogProvider with
|
||||
.StartDate(startDate)
|
||||
.EndDate(endDate)
|
||||
.Remark(comment)
|
||||
.save()
|
||||
.save
|
||||
case _ =>
|
||||
MigrationScriptLog
|
||||
.create
|
||||
@ -25,7 +25,7 @@ object MappedMigrationScriptLogProvider extends MigrationScriptLogProvider with
|
||||
.StartDate(startDate)
|
||||
.EndDate(endDate)
|
||||
.Remark(comment)
|
||||
.save()
|
||||
.save
|
||||
}
|
||||
}
|
||||
override def isExecuted(name: String): Boolean = {
|
||||
|
||||
@ -455,7 +455,7 @@ object MappedConsumersProvider extends ConsumersProvider with MdcLoggable {
|
||||
for {
|
||||
consumer <- Consumer.findAll(NullRef(Consumer.consumerId))++ Consumer.findAll(By(Consumer.consumerId,""))
|
||||
} yield {
|
||||
consumer.consumerId(APIUtil.generateUUID()).save()
|
||||
consumer.consumerId(APIUtil.generateUUID()).save
|
||||
}
|
||||
}.forall(_ == true)
|
||||
|
||||
@ -843,7 +843,7 @@ object MappedTokenProvider extends TokensProvider {
|
||||
|
||||
override def updateToken(id: Long, userId: Long): Boolean = {
|
||||
Token.find(By(Token.id, id)) match {
|
||||
case Full(t) => t.userForeignKey(userId).save()
|
||||
case Full(t) => t.userForeignKey(userId).save
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,249 +0,0 @@
|
||||
/**
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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.model.dataAccess
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util._
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.mongodb.QueryBuilder
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.common._
|
||||
import net.liftweb.mapper.By
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk, ObjectIdRefField}
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.{Limit, Skip}
|
||||
import net.liftweb.record.field.{DecimalField, StringField}
|
||||
|
||||
import scala.collection.immutable.List
|
||||
|
||||
class Account extends BankAccount with MongoRecord[Account] with ObjectIdPk[Account] with MdcLoggable{
|
||||
def meta = Account
|
||||
|
||||
object accountBalance extends DecimalField(this, 0) {
|
||||
//this is the legacy db field name
|
||||
override def name = "balance"
|
||||
}
|
||||
object holder extends StringField(this, 255)
|
||||
object accountNumber extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "number"
|
||||
}
|
||||
object kind extends StringField(this, 255)
|
||||
|
||||
// object productCode extends StringField(this, 255)
|
||||
|
||||
object accountName extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "name"
|
||||
}
|
||||
object permalink extends StringField(this, 255)
|
||||
object bankID extends ObjectIdRefField(this, HostedBank)
|
||||
object accountLabel extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "label"
|
||||
}
|
||||
object accountCurrency extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "currency"
|
||||
}
|
||||
object accountIban extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "iban"
|
||||
}
|
||||
object accountLastUpdate extends DateField(this)
|
||||
object mAccountRoutingScheme extends StringField(this, 255)
|
||||
object mAccountRoutingAddress extends StringField(this, 255)
|
||||
object mBranchId extends StringField(this, 255)
|
||||
|
||||
object mAccountRuleScheme1 extends StringField(this, 10)
|
||||
object mAccountRuleValue1 extends DecimalField(this, 0)
|
||||
object mAccountRuleScheme2 extends StringField(this, 10)
|
||||
object mAccountRuleValue2 extends DecimalField(this, 0)
|
||||
|
||||
|
||||
def transactionsForAccount: QueryBuilder = {
|
||||
QueryBuilder
|
||||
.start("obp_transaction.this_account.number")
|
||||
.is(accountNumber.get)
|
||||
//FIX: change that to use the bank identifier
|
||||
.put("obp_transaction.this_account.bank.national_identifier")
|
||||
.is(this.nationalIdentifier)
|
||||
}
|
||||
|
||||
//find all the envelopes related to this account
|
||||
def allEnvelopes: List[OBPEnvelope] = OBPEnvelope.findAll(transactionsForAccount.get)
|
||||
|
||||
def envelopes(queryParams: List[OBPQueryParam]): List[OBPEnvelope] = {
|
||||
import com.mongodb.DBObject
|
||||
import net.liftweb.mongodb.FindOption
|
||||
|
||||
val limit: Seq[Limit] = queryParams.collect { case OBPLimit(value) => Limit(value) }
|
||||
val offset: Seq[Skip] = queryParams.collect { case OBPOffset(value) => Skip(value) }
|
||||
val limitAndOffset: Seq[FindOption] = limit ++ offset
|
||||
|
||||
val fromDate: Option[OBPFromDate] = queryParams.collect { case param: OBPFromDate => param }.headOption
|
||||
val toDate: Option[OBPToDate] = queryParams.collect { case param: OBPToDate => param }.headOption
|
||||
|
||||
val query: DBObject = {
|
||||
val queryWithOptionalFromDate = fromDate.map{
|
||||
date => {
|
||||
transactionsForAccount
|
||||
.put("obp_transaction.details.completed")
|
||||
.greaterThanEquals(date.value)
|
||||
}
|
||||
}.getOrElse(transactionsForAccount)
|
||||
|
||||
val queryWithOptionalFromDateAndToDate = toDate.map{
|
||||
date => {
|
||||
queryWithOptionalFromDate
|
||||
.put("obp_transaction.details.completed")
|
||||
.lessThanEquals(date.value)
|
||||
}
|
||||
}.getOrElse(queryWithOptionalFromDate)
|
||||
|
||||
queryWithOptionalFromDateAndToDate.get
|
||||
}
|
||||
|
||||
val defaultSortField = "obp_transaction.details.completed"
|
||||
val orderingParams = queryParams
|
||||
.collect { case param: OBPOrdering => param}
|
||||
.headOption
|
||||
|
||||
val ordering: Option[DBObject] =
|
||||
orderingParams.map{
|
||||
o => {
|
||||
QueryBuilder
|
||||
.start(defaultSortField)
|
||||
.is(o.order.orderValue)
|
||||
.get
|
||||
}
|
||||
}
|
||||
|
||||
ordering match {
|
||||
case Some(o) =>{
|
||||
OBPEnvelope.findAll(query, o, limitAndOffset: _*)
|
||||
}
|
||||
case _ =>{
|
||||
OBPEnvelope.findAll(query, limitAndOffset: _*)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def bankId: BankId = {
|
||||
bankID.obj match {
|
||||
case Full(bank) => BankId(bank.permalink.get)
|
||||
case _ => BankId("")
|
||||
}
|
||||
}
|
||||
override def accountId : AccountId = AccountId(permalink.get)
|
||||
def iban: Option[String] = {
|
||||
val i = accountIban.get
|
||||
if (i.isEmpty) None else Some(i)
|
||||
}
|
||||
override def currency: String = accountCurrency.get
|
||||
override def number: String = accountNumber.get
|
||||
override def balance: BigDecimal = accountBalance.get
|
||||
override def name: String = accountName.get
|
||||
override def accountType: String = kind.get
|
||||
override def label: String = accountLabel.get
|
||||
override def accountHolder: String = holder.get
|
||||
override def lastUpdate: Date = accountLastUpdate.get
|
||||
def accountRoutingScheme: String = mAccountRoutingScheme.get
|
||||
def accountRoutingAddress: String = mAccountRoutingAddress.get
|
||||
override def branchId: String = mBranchId.get
|
||||
def createAccountRule(scheme: String, value: Long) = {
|
||||
scheme match {
|
||||
case s: String if s.equalsIgnoreCase("") == false =>
|
||||
val v = Helper.smallestCurrencyUnitToBigDecimal(value, accountCurrency.get)
|
||||
List(AccountRule(scheme, v.toString()))
|
||||
case _ =>
|
||||
Nil
|
||||
}
|
||||
}
|
||||
override def accountRoutings: List[AccountRouting] = {
|
||||
BankAccountRouting.findAll(
|
||||
By(BankAccountRouting.BankId, this.bankId.value),
|
||||
By(BankAccountRouting.AccountId, this.accountId.value)
|
||||
).map(_.accountRouting) match {
|
||||
case Nil => // This is the fallback if the BankAccountRouting failed
|
||||
List(AccountRouting(mAccountRoutingScheme.get, mAccountRoutingAddress.get))
|
||||
case everythingElseJustForward =>
|
||||
everythingElseJustForward
|
||||
}
|
||||
}
|
||||
override def accountRules: List[AccountRule] = createAccountRule(mAccountRuleScheme1.get, mAccountRuleValue1.get.toLong) :::
|
||||
createAccountRule(mAccountRuleScheme2.get, mAccountRuleValue2.get.toLong)
|
||||
}
|
||||
|
||||
object Account extends Account with MongoMetaRecord[Account] {
|
||||
def init = createIndex((permalink.name -> 1) ~ (bankID.name -> 1), true)
|
||||
}
|
||||
|
||||
class HostedBank extends Bank with MongoRecord[HostedBank] with ObjectIdPk[HostedBank]{
|
||||
def meta = HostedBank
|
||||
|
||||
object name extends StringField(this, 255)
|
||||
object alias extends StringField(this, 255)
|
||||
object logoURL extends StringField(this, 255)
|
||||
object website extends StringField(this, 255)
|
||||
object email extends StringField(this, 255)
|
||||
object permalink extends StringField(this, 255)
|
||||
object swiftBIC extends StringField(this, 255)
|
||||
object national_identifier extends StringField(this, 255)
|
||||
object mBankRoutingScheme extends StringField(this, 255)
|
||||
object mBankRoutingAddress extends StringField(this, 255)
|
||||
|
||||
def getAccount(bankAccountId: AccountId) : Box[Account] = {
|
||||
Account.find((Account.permalink.name -> bankAccountId.value) ~ (Account.bankID.name -> id.get)) ?~ {"account " + bankAccountId +" not found at bank " + permalink}
|
||||
}
|
||||
|
||||
def isAccount(bankAccountId : AccountId) : Boolean =
|
||||
Account.count((Account.permalink.name -> bankAccountId.value) ~ (Account.bankID.name -> id.get)) == 1
|
||||
|
||||
override def bankId: BankId = BankId(permalink.get)
|
||||
override def shortName: String = alias.get
|
||||
override def fullName: String = name.get
|
||||
override def logoUrl: String = logoURL.get
|
||||
override def websiteUrl: String = website.get
|
||||
override def swiftBic: String = swiftBIC.get
|
||||
override def nationalIdentifier: String = national_identifier.get
|
||||
override def bankRoutingScheme = mBankRoutingAddress.get
|
||||
override def bankRoutingAddress = mBankRoutingAddress.get
|
||||
}
|
||||
|
||||
object HostedBank extends HostedBank with MongoMetaRecord[HostedBank] {
|
||||
|
||||
def init = createIndex((permalink.name -> 1), true)
|
||||
|
||||
def find(bankId : BankId) : Box[HostedBank] = find(HostedBank.permalink.name -> bankId.value)
|
||||
|
||||
}
|
||||
@ -82,7 +82,7 @@ import scala.concurrent.Future
|
||||
*
|
||||
*
|
||||
* 3 RelationShips:
|
||||
* 1)When `Sign up` new user --> create AuthUser --> call AuthUser.save() --> create ResourceUser user.
|
||||
* 1)When `Sign up` new user --> create AuthUser --> call AuthUser.save --> create ResourceUser user.
|
||||
* They share the same username and email.
|
||||
* 2)AuthUser `user` field as the Foreign Key to link to Resource User.
|
||||
* one AuthUser <---> one ResourceUser
|
||||
@ -370,7 +370,7 @@ class AuthUser extends MegaProtoUser[AuthUser] with CreatedUpdated with MdcLogga
|
||||
}
|
||||
}
|
||||
}
|
||||
super.save()
|
||||
super.save
|
||||
}
|
||||
|
||||
override def delete_!(): Boolean = {
|
||||
@ -1581,7 +1581,7 @@ def restoreSomeSessions(): Unit = {
|
||||
.lastName(Helpers.randomString(16))
|
||||
.password(Helpers.randomString(40))
|
||||
.validated(false)
|
||||
scrambledUser.save()
|
||||
scrambledUser.save
|
||||
case Empty => true // There is a resource user but no the correlated Auth user
|
||||
case _ => false // Error case
|
||||
}
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
/**
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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.model.dataAccess
|
||||
|
||||
import code.api.util.APIUtil
|
||||
import code.metadata.narrative.OBPNarrativeInit
|
||||
import code.metadata.wheretags.OBPWhereTagInit
|
||||
import com.mongodb.MongoClient
|
||||
import net.liftweb.util.ConnectionIdentifier
|
||||
|
||||
object AdminDb extends ConnectionIdentifier {
|
||||
val jndiName = "admin"
|
||||
}
|
||||
|
||||
object MongoConfig {
|
||||
def init: Unit = {
|
||||
import net.liftweb.mongodb.MongoDB
|
||||
import com.mongodb.{Mongo, ServerAddress}
|
||||
import net.liftweb.util.{Props, DefaultConnectionIdentifier}
|
||||
|
||||
|
||||
val srvr = new ServerAddress(
|
||||
APIUtil.getPropsValue("mongo.host", "localhost"),
|
||||
APIUtil.getPropsAsIntValue("mongo.port", 27017)
|
||||
)
|
||||
val defaultDatabase = Props.mode match {
|
||||
case Props.RunModes.Test => "test"
|
||||
case _ => "OBP006"
|
||||
}
|
||||
|
||||
MongoDB.defineDb(DefaultConnectionIdentifier, new MongoClient(srvr), APIUtil.getPropsValue("mongo.dbName", defaultDatabase))
|
||||
MongoDB.defineDb(AdminDb, new MongoClient(srvr), "admin")
|
||||
|
||||
|
||||
HostedBank.init
|
||||
Account.init
|
||||
OBPNarrativeInit.init
|
||||
OBPWhereTagInit.init
|
||||
}
|
||||
}
|
||||
@ -1,408 +0,0 @@
|
||||
/**
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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.model.dataAccess
|
||||
|
||||
import code.util.Helper
|
||||
import com.mongodb.QueryBuilder
|
||||
import net.liftweb.mongodb.record.field._
|
||||
import net.liftweb.mongodb.record.{BsonMetaRecord, BsonRecord, MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.common.{Box, Empty, Failure}
|
||||
import java.util.{Date, UUID}
|
||||
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
import net.liftweb.json.JsonAST._
|
||||
import code.model._
|
||||
import code.util.Helper.MdcLoggable
|
||||
import net.liftweb.record.field.{DecimalField, DoubleField}
|
||||
import net.liftweb.util.FieldError
|
||||
import org.bson.types.ObjectId
|
||||
|
||||
import scala.xml.Unparsed
|
||||
import net.liftweb.json.JsonAST.JObject
|
||||
|
||||
import scala.Some
|
||||
import net.liftweb.json.JsonAST.JString
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.json.JsonAST.JField
|
||||
import code.metadata.counterparties.MongoCounterparties
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, TransactionId}
|
||||
|
||||
/**
|
||||
* "Current Account View"
|
||||
curl -i -H "Content-Type: application/json" -X POST -d '[{
|
||||
"obp_transaction":{
|
||||
"this_account":{
|
||||
"holder":"Music Pictures Limited",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"DE1235123612",
|
||||
"national_identifier":"de.10010010",
|
||||
"name":"Postbank"
|
||||
}
|
||||
},
|
||||
"other_account":{
|
||||
"holder":"Client 1",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"UK12222879",
|
||||
"national_identifier":"uk.10010010",
|
||||
"name":"HSBC"
|
||||
}
|
||||
},
|
||||
"details":{
|
||||
"type_en":"Transfer",
|
||||
"type_de":"Überweisung",
|
||||
"posted":{
|
||||
"$dt":"2012-01-04T18:06:22.000Z"
|
||||
},
|
||||
"completed":{
|
||||
"$dt":"2012-09-04T18:52:13.000Z"
|
||||
},
|
||||
"new_balance":{
|
||||
"currency":"EUR",
|
||||
"amount":"4323.45"
|
||||
},
|
||||
"value":{
|
||||
"currency":"EUR",
|
||||
"amount":"123.45"
|
||||
},
|
||||
"other_data":"9"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"obp_transaction":{
|
||||
"this_account":{
|
||||
"holder":"Music Pictures Limited",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"DE1235123612",
|
||||
"national_identifier":"de.10010010",
|
||||
"name":"Postbank"
|
||||
}
|
||||
},
|
||||
"other_account":{
|
||||
"holder":"Client 2",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"UK22222879",
|
||||
"national_identifier":"uk.10010010",
|
||||
"name":"HSBC"
|
||||
}
|
||||
},
|
||||
"details":{
|
||||
"type_en":"Transfer",
|
||||
"type_de":"Überweisung",
|
||||
"posted":{
|
||||
"$dt":"2012-01-04T14:06:22.000Z"
|
||||
},
|
||||
"completed":{
|
||||
"$dt":"2012-09-04T14:52:13.000Z"
|
||||
},
|
||||
"new_balance":{
|
||||
"currency":"EUR",
|
||||
"amount":"2222.45"
|
||||
},
|
||||
"value":{
|
||||
"currency":"EUR",
|
||||
"amount":"223.45"
|
||||
},
|
||||
"other_data":"9"
|
||||
}
|
||||
}
|
||||
}]' http://localhost:8080/api/transactions
|
||||
*/
|
||||
|
||||
// Seems to map to a collection of the plural name
|
||||
class OBPEnvelope private() extends MongoRecord[OBPEnvelope] with ObjectIdPk[OBPEnvelope] with MdcLoggable with TransactionUUID {
|
||||
def meta = OBPEnvelope
|
||||
|
||||
def theTransactionId = TransactionId(transactionId.get)
|
||||
def theAccountId = theAccount.map(_.accountId).getOrElse(AccountId(""))
|
||||
def theBankId = theAccount.map(_.bankId).getOrElse(BankId(""))
|
||||
|
||||
object transactionId extends StringField(this, 100) {
|
||||
override def defaultValue = UUID.randomUUID.toString
|
||||
}
|
||||
|
||||
// This creates a json attribute called "obp_transaction"
|
||||
object obp_transaction extends BsonRecordField(this, OBPTransaction)
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
obp_transaction.get.validate ++
|
||||
super.validate
|
||||
|
||||
object DateDescending extends Ordering[OBPEnvelope] {
|
||||
def compare(e1: OBPEnvelope, e2: OBPEnvelope) = {
|
||||
val date1 = e1.obp_transaction.get.details.get.completed.get
|
||||
val date2 = e2.obp_transaction.get.details.get.completed.get
|
||||
date1.compareTo(date2)
|
||||
}
|
||||
}
|
||||
|
||||
lazy val theAccount: Box[Account] = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
val thisAcc = obp_transaction.get.this_account.get
|
||||
val num = thisAcc.number.get
|
||||
val bankNationalIdentifier = thisAcc.bank.get.national_identifier.get
|
||||
for {
|
||||
bank <- HostedBank.find((HostedBank.national_identifier.name -> bankNationalIdentifier))
|
||||
bankMongoId : ObjectId = bank.id.get
|
||||
account <- Account.find((Account.accountNumber.name -> num) ~ (Account.bankID.name -> bankMongoId))
|
||||
} yield account
|
||||
}
|
||||
|
||||
def orderByDateDescending = (e1: OBPEnvelope, e2: OBPEnvelope) => {
|
||||
val date1 = e1.obp_transaction.get.details.get.completed.get
|
||||
val date2 = e2.obp_transaction.get.details.get.completed.get
|
||||
date1.after(date2)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object OBPEnvelope extends OBPEnvelope with MongoMetaRecord[OBPEnvelope] with MdcLoggable {
|
||||
|
||||
def envelopesFromJValue(jval: JValue) : Box[OBPEnvelope] = {
|
||||
val createdBox = fromJValue(jval)
|
||||
|
||||
createdBox match {
|
||||
case Full(created) =>
|
||||
val errors = created.validate
|
||||
if(errors.isEmpty) {
|
||||
Full(created)
|
||||
} else {
|
||||
logger.warn("could not create a obp envelope.errors: ")
|
||||
logger.warn(errors)
|
||||
Empty
|
||||
}
|
||||
case Failure(msg, _, _) =>
|
||||
Failure(s"could not create Envelope from JValue: $msg")
|
||||
case _ =>
|
||||
Failure(s"could not create Envelope from JValue")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class OBPTransaction private() extends BsonRecord[OBPTransaction]{
|
||||
def meta = OBPTransaction
|
||||
|
||||
object this_account extends BsonRecordField(this, OBPAccount)
|
||||
object other_account extends BsonRecordField(this, OBPAccount)
|
||||
object details extends BsonRecordField(this, OBPDetails)
|
||||
|
||||
private def validateThisAccount: List[FieldError] = {
|
||||
val accountNumber = this_account.get.number
|
||||
val bankId = this_account.get.bank.get.national_identifier
|
||||
val accountNumberError =
|
||||
if(accountNumber.get.isEmpty)
|
||||
Some(new FieldError(accountNumber, Unparsed("this bank account number is empty")))
|
||||
else
|
||||
None
|
||||
val bankIdError =
|
||||
if(bankId.get.isEmpty)
|
||||
Some(new FieldError(bankId, Unparsed("this bank number is empty")))
|
||||
else
|
||||
None
|
||||
List(accountNumberError, bankIdError).flatten
|
||||
}
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
validateThisAccount ++
|
||||
this_account.get.validate ++
|
||||
other_account.get.validate ++
|
||||
details.get.validate ++
|
||||
super.validate
|
||||
|
||||
@deprecated(Helper.deprecatedJsonGenerationMessage, null)
|
||||
def whenAddedJson(envelopeId : String) : JObject = {
|
||||
JObject(List(JField("obp_transaction_uuid", JString(envelopeId)),
|
||||
JField("this_account", this_account.get.whenAddedJson),
|
||||
JField("other_account", other_account.get.whenAddedJson),
|
||||
JField("details", details.get.whenAddedJson)))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPTransaction extends OBPTransaction with BsonMetaRecord[OBPTransaction]
|
||||
|
||||
class OBPAccount private() extends BsonRecord[OBPAccount]{
|
||||
def meta = OBPAccount
|
||||
|
||||
object holder extends StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
|
||||
object number extends StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object kind extends StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object bank extends BsonRecordField(this, OBPBank)
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
holder.validate ++
|
||||
number.validate ++
|
||||
kind.validate ++
|
||||
bank.validate ++
|
||||
super.validate
|
||||
|
||||
/**
|
||||
* @param moderatingAccount a temporary way to provide the obp account whose aliases should
|
||||
* be used when displaying this account
|
||||
*/
|
||||
def whenAddedJson: JObject = {
|
||||
|
||||
JObject(List(JField("holder",
|
||||
JObject(List(
|
||||
JField("holder", JString(holder.get)),
|
||||
JField("alias", JString("no"))))),
|
||||
JField("number", JString(number.get)),
|
||||
JField("kind", JString(kind.get)),
|
||||
JField("bank", bank.get.whenAddedJson)))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPAccount extends OBPAccount with BsonMetaRecord[OBPAccount]{
|
||||
sealed abstract class AnAlias
|
||||
case object APublicAlias extends AnAlias
|
||||
case object APrivateAlias extends AnAlias
|
||||
}
|
||||
|
||||
class OBPBank private() extends BsonRecord[OBPBank]{
|
||||
def meta = OBPBank
|
||||
|
||||
object IBAN extends net.liftweb.record.field.StringField(this, 255)
|
||||
object national_identifier extends net.liftweb.record.field.StringField(this, 255)
|
||||
object name extends net.liftweb.record.field.StringField(this, 255)
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
IBAN.validate ++
|
||||
national_identifier.validate ++
|
||||
name.validate ++
|
||||
super.validate
|
||||
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("IBAN", JString(IBAN.get)),
|
||||
JField("national_identifier", JString(national_identifier.get)),
|
||||
JField("name", JString(name.get))))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPBank extends OBPBank with BsonMetaRecord[OBPBank]
|
||||
|
||||
|
||||
|
||||
class OBPDetails private() extends BsonRecord[OBPDetails]{
|
||||
def meta = OBPDetails
|
||||
|
||||
object kind extends net.liftweb.record.field.StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object posted extends DateField(this)
|
||||
object other_data extends net.liftweb.record.field.StringField(this, 5000){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object new_balance extends BsonRecordField(this, OBPBalance)
|
||||
object value extends BsonRecordField(this, OBPValue)
|
||||
object completed extends DateField(this)
|
||||
object label extends net.liftweb.record.field.StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
kind.validate ++
|
||||
posted.validate ++
|
||||
other_data.validate ++
|
||||
new_balance.validate ++
|
||||
value.validate ++
|
||||
completed.validate ++
|
||||
label.validate ++
|
||||
super.validate
|
||||
|
||||
|
||||
def formatDate(date : Date) : String = {
|
||||
OBPDetails.formats.dateFormat.format(date)
|
||||
}
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("type_en", JString(kind.get)),
|
||||
JField("type", JString(kind.get)),
|
||||
JField("posted", JString(formatDate(posted.get))),
|
||||
JField("completed", JString(formatDate(completed.get))),
|
||||
JField("other_data", JString(other_data.get)),
|
||||
JField("new_balance", new_balance.get.whenAddedJson),
|
||||
JField("value", value.get.whenAddedJson)))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPDetails extends OBPDetails with BsonMetaRecord[OBPDetails]
|
||||
|
||||
|
||||
class OBPBalance private() extends BsonRecord[OBPBalance]{
|
||||
def meta = OBPBalance
|
||||
|
||||
object currency extends StringField(this, 5)
|
||||
object amount extends DecimalField(this, 0) // ok to use decimal?
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
currency.validate ++
|
||||
amount.validate ++
|
||||
super.validate
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("currency", JString(currency.get)),
|
||||
JField("amount", JString(amount.get.toString))))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPBalance extends OBPBalance with BsonMetaRecord[OBPBalance]
|
||||
|
||||
class OBPValue private() extends BsonRecord[OBPValue]{
|
||||
def meta = OBPValue
|
||||
|
||||
object currency extends net.liftweb.record.field.StringField(this, 5)
|
||||
object amount extends net.liftweb.record.field.DecimalField(this, 0) // ok to use decimal?
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("currency", JString(currency.get)),
|
||||
JField("amount", JString(amount.get.toString))))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPValue extends OBPValue with BsonMetaRecord[OBPValue]
|
||||
@ -50,7 +50,7 @@ import net.liftweb.mapper._
|
||||
*
|
||||
*
|
||||
* 3 RelationShips:
|
||||
* 1)When `Sign up` new user --> create AuthUser --> call AuthUser.save() --> create ResourceUser user.
|
||||
* 1)When `Sign up` new user --> create AuthUser --> call AuthUser.save --> create ResourceUser user.
|
||||
* They share the same username and email.
|
||||
* 2)AuthUser `user` field as the Foreign Key to link to Resource User.
|
||||
* one AuthUser <---> one ResourceUser
|
||||
|
||||
@ -18,7 +18,7 @@ trait CreateAuthUsers {
|
||||
def save() = {
|
||||
val usr = Users.users.vend.saveResourceUser(value)
|
||||
for (uu <- usr) {
|
||||
u.user(uu).save()
|
||||
u.user(uu).save
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,155 +0,0 @@
|
||||
package code.sandbox
|
||||
|
||||
import code.metadata.counterparties.{MongoCounterparties, Metadata}
|
||||
import code.model._
|
||||
import code.model.dataAccess._
|
||||
import net.liftweb.common._
|
||||
import java.util.UUID
|
||||
import net.liftweb.mapper.By
|
||||
import net.liftweb.mongodb.record.MongoRecord
|
||||
import net.liftweb.util.Helpers._
|
||||
import org.bson.types.ObjectId
|
||||
|
||||
//An basic implementation of Saveable for MongoRecords
|
||||
case class SaveableMongoObj[T <: MongoRecord[_]](value : T) extends Saveable[T] {
|
||||
def save() = value.save(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports data into the format used by LocalRecordConnector (e.g. HostedBank)
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Not currently using this connector so not updating it at the moment.
|
||||
|
||||
object LocalRecordConnectorDataImport extends OBPDataImport with CreateAuthUsers {
|
||||
|
||||
type BankType = HostedBank
|
||||
type AccountType = Account
|
||||
type TransactionType = OBPEnvelope
|
||||
type MetadataType = Metadata
|
||||
|
||||
protected def createSaveableBanks(data : List[SandboxBankImport]) : Box[List[Saveable[BankType]]] = {
|
||||
val hostedBanks = data.map(b => {
|
||||
HostedBank.createRecord
|
||||
.id(ObjectId.get)
|
||||
.permalink(b.id)
|
||||
.name(b.full_name)
|
||||
.alias(b.short_name)
|
||||
.website(b.website)
|
||||
.logoURL(b.logo)
|
||||
.national_identifier(b.id) //this needs to match up with what goes in the OBPEnvelopes
|
||||
})
|
||||
|
||||
val validationErrors = hostedBanks.flatMap(_.validate)
|
||||
|
||||
if(!validationErrors.isEmpty) {
|
||||
Failure(s"Errors: ${validationErrors.map(_.msg)}")
|
||||
} else {
|
||||
Full(hostedBanks.map(SaveableMongoObj(_)))
|
||||
}
|
||||
}
|
||||
|
||||
protected def createSaveableAccount(acc : SandboxAccountImport, banks : List[HostedBank]) : Box[Saveable[Account]] = {
|
||||
def getHostedBank(acc : SandboxAccountImport) = Box(banks.find(b => b.permalink.get == acc.bank))
|
||||
|
||||
def asSaveableAccount(account : Account, hostedBank : HostedBank) = new Saveable[Account] {
|
||||
val value = account
|
||||
|
||||
def save() = {
|
||||
//this looks pointless, but what it is doing is refreshing the Account.bankID.obj reference, which
|
||||
//is used by Account.bankId. If we don't refresh it here, Account.bankId will return BankId("")
|
||||
account.bankID(account.bankID.get).save(true)
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
hBank <- getHostedBank(acc) ?~ {
|
||||
logger.warn("hosted bank not found")
|
||||
"Server error"
|
||||
}
|
||||
balance <- tryo{BigDecimal(acc.balance.amount)} ?~ s"Invalid balance: ${acc.balance.amount}"
|
||||
} yield {
|
||||
val account = Account.createRecord
|
||||
.permalink(acc.id)
|
||||
.bankID(hBank.id.get)
|
||||
.accountLabel(acc.label)
|
||||
.accountCurrency(acc.balance.currency)
|
||||
.accountBalance(balance)
|
||||
.accountNumber(acc.number)
|
||||
.kind(acc.`type`)
|
||||
.accountIban(acc.IBAN)
|
||||
|
||||
asSaveableAccount(account, hBank)
|
||||
}
|
||||
}
|
||||
|
||||
override protected def createSaveableTransaction(t : SandboxTransactionImport, createdBanks : List[BankType], createdAccounts : List[AccountType]) :
|
||||
Box[Saveable[TransactionType]] = {
|
||||
|
||||
val counterpartyHolder = t.counterparty.flatMap(_.name).getOrElse("")
|
||||
|
||||
for {
|
||||
createdBank <- Box(createdBanks.find(b => b.permalink.get == t.this_account.bank)) ?~
|
||||
s"Transaction this_account bank must be specified in import banks. Unspecified bank: ${t.this_account.bank}"
|
||||
//have to compare a.bankID to createdBank.id instead of just checking a.bankId against t.this_account.bank as createdBank hasn't been
|
||||
//saved so the a.bankId method (which involves a db lookup) will not work
|
||||
createdAcc <- Box(createdAccounts.find(a => a.bankID.toString == createdBank.id.get.toString && a.accountId == AccountId(t.this_account.id))) ?~
|
||||
s"Transaction this_account account must be specified in import accounts. Unspecified account id: ${t.this_account.id} at bank: ${t.this_account.bank}"
|
||||
newBalanceValue <- tryo{BigDecimal(t.details.new_balance)} ?~ s"Invalid new balance: ${t.details.new_balance}"
|
||||
tValue <- tryo{BigDecimal(t.details.value)} ?~ s"Invalid transaction value: ${t.details.value}"
|
||||
postedDate <- tryo{dateFormat.parse(t.details.posted)} ?~ s"Invalid date format: ${t.details.posted}. Expected pattern $datePattern"
|
||||
completedDate <-tryo{dateFormat.parse(t.details.completed)} ?~ s"Invalid date format: ${t.details.completed}. Expected pattern $datePattern"
|
||||
} yield {
|
||||
|
||||
//bankNationalIdentifier not available from createdAcc.bankNationalIdentifier as it hasn't been saved so we get it from createdBank
|
||||
val obpThisAccountBank = OBPBank.createRecord
|
||||
.national_identifier(createdBank.national_identifier.get)
|
||||
|
||||
val obpThisAccount = OBPAccount.createRecord
|
||||
.holder(createdAcc.holder.get)
|
||||
.number(createdAcc.accountNumber.get)
|
||||
.kind(createdAcc.kind.get)
|
||||
.bank(obpThisAccountBank)
|
||||
|
||||
val counterpartyAccountNumber = t.counterparty.flatMap(_.account_number)
|
||||
|
||||
val obpOtherAccount = OBPAccount.createRecord
|
||||
.holder(counterpartyHolder)
|
||||
.number(counterpartyAccountNumber.getOrElse(""))
|
||||
|
||||
val newBalance = OBPBalance.createRecord
|
||||
.amount(newBalanceValue)
|
||||
.currency(createdAcc.accountCurrency.get)
|
||||
|
||||
val transactionValue = OBPValue.createRecord
|
||||
.amount(tValue)
|
||||
.currency(createdAcc.accountCurrency.get)
|
||||
|
||||
val obpDetails = OBPDetails.createRecord
|
||||
.completed(completedDate)
|
||||
.posted(postedDate)
|
||||
.kind(t.details.`type`)
|
||||
.label(t.details.description)
|
||||
.new_balance(newBalance)
|
||||
.value(transactionValue)
|
||||
|
||||
|
||||
val obpTransaction = OBPTransaction.createRecord
|
||||
.details(obpDetails)
|
||||
.this_account(obpThisAccount)
|
||||
.other_account(obpOtherAccount)
|
||||
|
||||
val env = OBPEnvelope.createRecord
|
||||
.transactionId(t.id)
|
||||
.obp_transaction(obpTransaction)
|
||||
|
||||
SaveableMongoObj(env)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
@ -18,7 +18,7 @@ import net.liftweb.mapper.Mapper
|
||||
import net.liftweb.util.Helpers._
|
||||
|
||||
case class MappedSaveable[T <: Mapper[_]](value : T) extends Saveable[T] {
|
||||
def save() = value.save()
|
||||
def save() = value.save
|
||||
}
|
||||
|
||||
object LocalMappedConnectorDataImport extends OBPDataImport with CreateAuthUsers {
|
||||
|
||||
@ -500,22 +500,22 @@ trait OBPDataImport extends MdcLoggable {
|
||||
crmEvents <- createCrmEvents(data)
|
||||
} yield {
|
||||
logger.info(s"importData is saving ${banks.size} banks..")
|
||||
banks.foreach(_.save())
|
||||
banks.foreach(_.save)
|
||||
|
||||
logger.info(s"importData is saving ${users.size} users..")
|
||||
users.foreach(_.save())
|
||||
users.foreach(_.save)
|
||||
|
||||
logger.info(s"importData is saving ${branches.size} branches..")
|
||||
branches.foreach(_.save())
|
||||
branches.foreach(_.save)
|
||||
|
||||
logger.info(s"importData is saving ${atms.size} ATMs..")
|
||||
atms.foreach(_.save())
|
||||
atms.foreach(_.save)
|
||||
|
||||
logger.info(s"importData is saving ${products.size} products..")
|
||||
products.foreach(_.save())
|
||||
products.foreach(_.save)
|
||||
|
||||
logger.info(s"importData is saving ${crmEvents.size} crmEvents..")
|
||||
crmEvents.foreach(_.save())
|
||||
crmEvents.foreach(_.save)
|
||||
|
||||
|
||||
|
||||
@ -526,7 +526,7 @@ trait OBPDataImport extends MdcLoggable {
|
||||
logger.info(s"importData is saving ${accountResults.size} accountResults (accounts, views and permissions)..")
|
||||
accountResults.foreach {
|
||||
case (account, systemViews, accOwnerUsernames) =>
|
||||
account.save()
|
||||
account.save
|
||||
|
||||
systemViews.filterNot(_.isPublic).foreach(v => {
|
||||
//grant the owner access to Private systemViews
|
||||
@ -539,7 +539,7 @@ trait OBPDataImport extends MdcLoggable {
|
||||
}
|
||||
logger.info(s"importData is saving ${transactions.size} transactions (and loading them again)")
|
||||
transactions.foreach { t =>
|
||||
t.save()
|
||||
t.save
|
||||
//load it to force creation of metadata (If we are using Mapped connector, MappedCounterpartyMetadata.create will be called)
|
||||
val lt = Connector.connector.vend.getTransactionLegacy(t.value.theBankId, t.value.theAccountId, t.value.theTransactionId)
|
||||
}
|
||||
|
||||
@ -14,74 +14,72 @@ object WebUITemplate {
|
||||
|
||||
val webUIDoc = ArrayBuffer[WebUIDoc]()
|
||||
|
||||
|
||||
val webUiDeveloperUserInvitationEmailText =
|
||||
s"""
|
||||
|Hi ${emailRecipient},
|
||||
|Welcome to the Open Bank Project API. Your account has been registered. Please use the below link to activate it.
|
||||
|
|
||||
|Activate your account: ${activateYourAccount}
|
||||
|
|
||||
|Our operations team has granted you the appropriate access to the OBP-API. If you have any questions, or you need any assistance, please contact our support.
|
||||
|
|
||||
|Thanks,
|
||||
|Your OBP API team
|
||||
|
|
||||
|
|
||||
|
|
||||
|Please do not reply to this email. Should you wish to contact us, please raise a ticket at our support page. We maintain strict security standards and procedures to prevent unauthorised access to information about you. We will never contact you by email or otherwise and ask you to validate personal information such as your user ID, password or account numbers. This e-mail is confidential. It may also be legally privileged. If you are not the addressee you may not copy, forward, disclose or use any part of it. If you have received this message in error, please delete it and all copies from your system. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions.
|
||||
|""".stripMargin
|
||||
webUIDoc += WebUIDoc(
|
||||
webUiPropsName = "webui_developer_user_invitation_email_text",
|
||||
defaultValue = webUiDeveloperUserInvitationEmailText,
|
||||
typeOfValue = "plain_text",
|
||||
placeholders = List(emailRecipient, activateYourAccount)
|
||||
)
|
||||
val webUiDeveloperUserInvitationEmailText =
|
||||
s"""
|
||||
|Hi ${emailRecipient},
|
||||
|Welcome to the Open Bank Project API. Your account has been registered. Please use the below link to activate it.
|
||||
|
|
||||
|Activate your account: ${activateYourAccount}
|
||||
|
|
||||
|Our operations team has granted you the appropriate access to the OBP-API. If you have any questions, or you need any assistance, please contact our support.
|
||||
|
|
||||
|Thanks,
|
||||
|Your OBP API team
|
||||
|
|
||||
|
|
||||
|
|
||||
|Please do not reply to this email. Should you wish to contact us, please raise a ticket at our support page. We maintain strict security standards and procedures to prevent unauthorised access to information about you. We will never contact you by email or otherwise and ask you to validate personal information such as your user ID, password or account numbers. This e-mail is confidential. It may also be legally privileged. If you are not the addressee you may not copy, forward, disclose or use any part of it. If you have received this message in error, please delete it and all copies from your system. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions.
|
||||
|""".stripMargin
|
||||
|
||||
|
||||
val webUiDeveloperUserInvitationEmailHtmlText =
|
||||
s"""<!DOCTYPE html>
|
||||
|<html>
|
||||
|<head>
|
||||
|<style>
|
||||
|.a {
|
||||
| border: none;
|
||||
| color: white;
|
||||
| padding: 15px 32px;
|
||||
| text-align: center;
|
||||
| text-decoration: none;
|
||||
| display: inline-block;
|
||||
| font-size: 16px;
|
||||
| margin: 4px 2px;
|
||||
| cursor: pointer;
|
||||
|}
|
||||
|
|
||||
|.a1 {background-color: #4CAF50;} /* Green */
|
||||
|.a2 {background-color: #008CBA;} /* Blue */
|
||||
|</style>
|
||||
|</head>
|
||||
|<body>
|
||||
|<img src="https://static.openbankproject.com/images/OBP_full_web_25pc.png"></img>
|
||||
|<hr></hr><br></br>
|
||||
|<p>Hi ${emailRecipient},<br></br>
|
||||
|Welcome to the Open Bank Project API. Your account has been registered. Please use the below link to activate it.</p>
|
||||
|<a href="${activateYourAccount}" class="a a1">Activate your account</a>
|
||||
|<p>Our operations team has granted you the appropriate access to the OBP-API. If you have any questions, or you need any assistance, please contact our support.</p>
|
||||
|<p>Thanks,<br></br> Your OBP API team</p><br></br>
|
||||
|<hr></hr>
|
||||
|<p>
|
||||
|Please do not reply to this email. Should you wish to contact us, please raise a ticket at our support page. We maintain strict security standards and procedures to prevent unauthorised access to information about you. We will never contact you by email or otherwise and ask you to validate personal information such as your user ID, password or account numbers. This e-mail is confidential. It may also be legally privileged. If you are not the addressee you may not copy, forward, disclose or use any part of it. If you have received this message in error, please delete it and all copies from your system. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions.
|
||||
|</p>
|
||||
|</body>
|
||||
|</html>
|
||||
|
|
||||
|""".stripMargin
|
||||
webUIDoc += WebUIDoc(
|
||||
webUiPropsName = "webui_developer_user_invitation_email_html_text",
|
||||
defaultValue = webUiDeveloperUserInvitationEmailHtmlText,
|
||||
typeOfValue = "html",
|
||||
placeholders = List(emailRecipient, activateYourAccount)
|
||||
)
|
||||
val webUiDeveloperUserInvitationEmailHtmlText =
|
||||
s"""<!DOCTYPE html>
|
||||
|<html>
|
||||
|<head>
|
||||
|<style>
|
||||
|.a {
|
||||
| border: none;
|
||||
| color: white;
|
||||
| padding: 15px 32px;
|
||||
| text-align: center;
|
||||
| text-decoration: none;
|
||||
| display: inline-block;
|
||||
| font-size: 16px;
|
||||
| margin: 4px 2px;
|
||||
| cursor: pointer;
|
||||
|}
|
||||
|
|
||||
|.a1 {background-color: #4CAF50;} /* Green */
|
||||
|.a2 {background-color: #008CBA;} /* Blue */
|
||||
|</style>
|
||||
|</head>
|
||||
|<body>
|
||||
|<img src="https://static.openbankproject.com/images/OBP_full_web_25pc.png"></img>
|
||||
|<hr></hr><br></br>
|
||||
|<p>Hi ${emailRecipient},<br></br>
|
||||
|Welcome to the Open Bank Project API. Your account has been registered. Please use the below link to activate it.</p>
|
||||
|<a href="${activateYourAccount}" class="a a1">Activate your account</a>
|
||||
|<p>Our operations team has granted you the appropriate access to the OBP-API. If you have any questions, or you need any assistance, please contact our support.</p>
|
||||
|<p>Thanks,<br></br> Your OBP API team</p><br></br>
|
||||
|<hr></hr>
|
||||
|<p>
|
||||
|Please do not reply to this email. Should you wish to contact us, please raise a ticket at our support page. We maintain strict security standards and procedures to prevent unauthorised access to information about you. We will never contact you by email or otherwise and ask you to validate personal information such as your user ID, password or account numbers. This e-mail is confidential. It may also be legally privileged. If you are not the addressee you may not copy, forward, disclose or use any part of it. If you have received this message in error, please delete it and all copies from your system. Internet communications cannot be guaranteed to be timely, secure, error or virus-free. The sender does not accept liability for any errors or omissions.
|
||||
|</p>
|
||||
|</body>
|
||||
|</html>
|
||||
|
|
||||
|""".stripMargin
|
||||
|
||||
webUIDoc += WebUIDoc(
|
||||
webUiPropsName = "webui_terms_and_conditions",
|
||||
|
||||
@ -21,7 +21,7 @@ object MappedSocialMediasProvider extends SocialMediaHandleProvider {
|
||||
.mHandle(handle)
|
||||
.mDateAdded(dateAdded)
|
||||
.mDateActivated(dateActivated)
|
||||
.save()
|
||||
.save
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,19 +2,18 @@ package code.transaction
|
||||
|
||||
|
||||
import code.accountholders.AccountHolders
|
||||
import code.actorsystem.ObpLookupSystem
|
||||
import code.api.util.{APIUtil, ApiTrigger}
|
||||
import code.bankconnectors.{Connector, LocalMappedConnector}
|
||||
import code.bankconnectors.LocalMappedConnector
|
||||
import code.bankconnectors.LocalMappedConnector.getBankAccountCommon
|
||||
import code.model._
|
||||
import code.usercustomerlinks.UserCustomerLink
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.util._
|
||||
import code.webhook.WebhookActor
|
||||
import code.webhook.WebhookActor.RelatedEntity
|
||||
import code.webhook.WebhookAction
|
||||
import code.webhook.WebhookActor.{AccountNotificationWebhookRequest, RelatedEntity, WebhookRequest}
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.common._
|
||||
import net.liftweb.common.Box.tryo
|
||||
import net.liftweb.common._
|
||||
import net.liftweb.mapper._
|
||||
|
||||
class MappedTransaction extends LongKeyedMapper[MappedTransaction] with IdPK with CreatedUpdated with TransactionUUID with MdcLoggable {
|
||||
@ -239,7 +238,6 @@ object MappedTransaction extends MappedTransaction with LongKeyedMetaMapper[Mapp
|
||||
override def afterSave = List(
|
||||
t =>
|
||||
tryo {
|
||||
val actor = ObpLookupSystem.getWebhookActor()
|
||||
def getAmount(value: Long): String = {
|
||||
Helper.smallestCurrencyUnitToBigDecimal(value, t.currency.get).toString() + " " + t.currency.get
|
||||
}
|
||||
@ -256,24 +254,28 @@ object MappedTransaction extends MappedTransaction with LongKeyedMetaMapper[Mapp
|
||||
val userIdCustomerIdsPairs: Map[String, List[String]] = userIdCustomerIdPairs.groupBy(_._1).map( a => (a._1,a._2.map(_._2)))
|
||||
val eventId = APIUtil.generateUUID()
|
||||
logger.debug("Before firing WebhookActor.AccountNotificationWebhookRequest.eventId: " + eventId)
|
||||
actor ! WebhookActor.AccountNotificationWebhookRequest(
|
||||
apiTrigger,
|
||||
eventId,
|
||||
t.theBankId.value,
|
||||
t.theAccountId.value,
|
||||
t.theTransactionId.value,
|
||||
userIdCustomerIdsPairs.map(pair => RelatedEntity(pair._1, pair._2)).toList
|
||||
WebhookAction.accountNotificationWebhookRequest(
|
||||
AccountNotificationWebhookRequest(
|
||||
apiTrigger,
|
||||
eventId,
|
||||
t.theBankId.value,
|
||||
t.theAccountId.value,
|
||||
t.theTransactionId.value,
|
||||
userIdCustomerIdsPairs.map(pair => RelatedEntity(pair._1, pair._2)).toList
|
||||
)
|
||||
)
|
||||
} else{
|
||||
val eventId = APIUtil.generateUUID()
|
||||
logger.debug("Before firing WebhookActor.WebhookRequest.eventId: " + eventId)
|
||||
actor ! WebhookActor.WebhookRequest(
|
||||
apiTrigger,
|
||||
eventId,
|
||||
t.theBankId.value,
|
||||
t.theAccountId.value,
|
||||
getAmount(t.amount.get),
|
||||
getAmount(t.newAccountBalance.get)
|
||||
WebhookAction.webhookRequest(
|
||||
WebhookRequest(
|
||||
apiTrigger,
|
||||
eventId,
|
||||
t.theBankId.value,
|
||||
t.theAccountId.value,
|
||||
getAmount(t.amount.get),
|
||||
getAmount(t.newAccountBalance.get)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,12 +302,12 @@ object LiftUsers extends Users with MdcLoggable{
|
||||
.name_("DELETED-" + Helpers.randomString(16))
|
||||
.email(Helpers.randomString(10) + "@example.com")
|
||||
.providerId(Helpers.randomString(16))
|
||||
.save()
|
||||
.save
|
||||
case _ =>
|
||||
u
|
||||
.Company(Helpers.randomString(16))
|
||||
.IsDeleted(true)
|
||||
.save()
|
||||
.save
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ object MappedUserInvitationProvider extends UserInvitationProvider {
|
||||
UserInvitation.find(
|
||||
By(UserInvitation.UserInvitationId, userInvitationId)
|
||||
) match {
|
||||
case Full(userInvitation) => userInvitation.Status(status).save()
|
||||
case Full(userInvitation) => userInvitation.Status(status).save
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,7 @@ object MappedUserInvitationProvider extends UserInvitationProvider {
|
||||
.Country(Helpers.randomString(userInvitation.country.length))
|
||||
.Purpose(Helpers.randomString(userInvitation.purpose.length))
|
||||
.Status("DELETED")
|
||||
.save()
|
||||
.save
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package code.webhook
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
import code.webhook.WebhookActor.WebhookRequestTrait
|
||||
import okhttp3._
|
||||
|
||||
object OkHttpWebhookClient {
|
||||
|
||||
private val client = new OkHttpClient
|
||||
|
||||
@throws[Exception]
|
||||
def makeAsynchronousRequest(request: Request, webhookRequest: WebhookRequestTrait): Unit = {
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
def onFailure(call: Call, e: IOException): Unit = {
|
||||
WebhookAction.webhookFailure(e.getMessage, webhookRequest)
|
||||
}
|
||||
|
||||
@throws[IOException]
|
||||
def onResponse(call: Call, response: Response): Unit = {
|
||||
val responseBody = response.body
|
||||
try {
|
||||
if (!response.isSuccessful) throw new IOException("Unexpected code " + response)
|
||||
org.scalameta.logger.elem(responseBody.string)
|
||||
WebhookAction.webhookResponse(response.code().toString, webhookRequest)
|
||||
} finally if (responseBody != null) responseBody.close()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package code.webhook
|
||||
|
||||
import akka.actor.{ActorSystem, Props => ActorProps}
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
|
||||
object WebhookHelperActors extends MdcLoggable {
|
||||
|
||||
val props_hostname = Helper.getHostname
|
||||
val actorName = "Webhook-Actor"
|
||||
|
||||
//This method is called in Boot.scala
|
||||
def startLocalWebhookHelperWorkers(system: ActorSystem): Unit = {
|
||||
logger.info("Starting local WebhookHelperActors workers")
|
||||
startWebhookHelperActors(system)
|
||||
}
|
||||
|
||||
def startWebhookHelperActors(actorSystem: ActorSystem): Unit = {
|
||||
val actorsHelper = Map(
|
||||
ActorProps[WebhookActor] -> actorName
|
||||
)
|
||||
actorsHelper.foreach { a => logger.info(actorSystem.actorOf(a._1, name = a._2)) }
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,9 +1,8 @@
|
||||
package code.webhook
|
||||
|
||||
import akka.actor.{Actor, ActorLogging}
|
||||
import code.api.util.ApiTrigger
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.webhook.WebhookActor.{AccountNotificationWebhookRequest, WebhookFailure, WebhookRequest, WebhookResponse}
|
||||
import code.webhook.WebhookActor.{AccountNotificationWebhookRequest, WebhookRequestTrait}
|
||||
|
||||
|
||||
object WebhookActor {
|
||||
@ -92,42 +91,25 @@ object WebhookActor {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This Actor process all request/response messages related to Webhooks.
|
||||
* It's accessible at the North side all over the code.
|
||||
* Example:
|
||||
* {
|
||||
* val actor: ActorSelection = ObpLookupSystem.getWebhookActor()
|
||||
* }
|
||||
* We use fire and forget scenario in case of this Actor.
|
||||
* I.e. we trigger some webhook's event with:
|
||||
* 1. actor ! Request
|
||||
* and then send result of event to the Actor:
|
||||
* 2. actor ! Response
|
||||
*
|
||||
*/
|
||||
class WebhookActor extends Actor with ActorLogging with MdcLoggable {
|
||||
|
||||
def receive: Receive = waitingForRequest
|
||||
|
||||
private def waitingForRequest: Receive = {
|
||||
case request@WebhookRequest(trigger, eventId, bankId, accountId, amount, balance) =>
|
||||
implicit val ec = context.dispatcher
|
||||
logger.debug("WebhookActor.waitingForRequest.WebhookRequest(request).eventId: " + eventId)
|
||||
WebhookHttpClient.startEvent(request)
|
||||
case request@AccountNotificationWebhookRequest(trigger, eventId, bankId, accountId, transactionId, relatedEntities) =>
|
||||
implicit val ec = context.dispatcher
|
||||
logger.debug("WebhookActor.waitingForRequest.AccountNotificationWebhookRequest(request).eventId: " + eventId)
|
||||
WebhookHttpClient.startEvent(request)
|
||||
case WebhookResponse(status, request) =>
|
||||
logger.debug("WebhookActor.waitingForRequest.WebhookResponse(status, request).status: " + status)
|
||||
logger.debug("WebhookActor.waitingForRequest.WebhookResponse(status, request).request.eventId: " + request.eventId)
|
||||
logger.debug("WebhookActor.waitingForRequest.WebhookResponse(status, request).request.toEventPayload: " + request.toEventPayload)
|
||||
case WebhookFailure(error, request) =>
|
||||
logger.debug("WebhookActor.waitingForRequest.WebhookFailure(error, request).error: " + error)
|
||||
logger.debug("WebhookActor.waitingForRequest.WebhookFailure(error, request).request.eventId:: " + request.eventId)
|
||||
logger.debug("WebhookActor.waitingForRequest.WebhookFailure(error, request).request.toEventPayload: " + request.toEventPayload)
|
||||
object WebhookAction extends MdcLoggable {
|
||||
def webhookRequest(request: WebhookRequestTrait) = {
|
||||
logger.debug("WebhookActor.webhookRequest(request).eventId: " + request.eventId)
|
||||
WebhookHttpClient.startEvent(request)
|
||||
}
|
||||
def accountNotificationWebhookRequest(request: AccountNotificationWebhookRequest) = {
|
||||
logger.debug("WebhookActor.accountNotificationWebhookRequest(request).eventId: " + request.eventId)
|
||||
WebhookHttpClient.startEvent(request)
|
||||
}
|
||||
def webhookResponse(status: String,
|
||||
request: WebhookRequestTrait) = {
|
||||
logger.debug("WebhookActor.webhookResponse(status, request).status: " + status)
|
||||
logger.debug("WebhookActor.webhookResponse(status, request).request.eventId: " + request.eventId)
|
||||
logger.debug("WebhookActor.webhookResponse(status, request).request.toEventPayload: " + request.toEventPayload)
|
||||
}
|
||||
def webhookFailure(error: String,
|
||||
request: WebhookRequestTrait) = {
|
||||
logger.debug("WebhookActor.webhookFailure(error, request).error: " + error)
|
||||
logger.debug("WebhookActor.webhookFailure(error, request).request.eventId:: " + request.eventId)
|
||||
logger.debug("WebhookActor.webhookFailure(error, request).request.toEventPayload: " + request.toEventPayload)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,23 +1,14 @@
|
||||
package code.webhook
|
||||
|
||||
import akka.http.scaladsl.Http
|
||||
import akka.http.scaladsl.model.HttpMethods._
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.settings.ConnectionPoolSettings
|
||||
import akka.stream.ActorMaterializer
|
||||
import akka.util.ByteString
|
||||
import code.actorsystem.ObpLookupSystem
|
||||
import code.api.util.ApiTrigger.{OnBalanceChange, OnCreateTransaction, OnCreditTransaction, OnDebitTransaction}
|
||||
import code.api.util.{ApiTrigger, CustomJsonFormats}
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.webhook.WebhookActor.{AccountNotificationWebhookRequest, WebhookFailure, WebhookRequest, WebhookRequestTrait, WebhookResponse}
|
||||
import code.webhook.WebhookActor.{AccountNotificationWebhookRequest, WebhookRequest, WebhookRequestTrait}
|
||||
import net.liftweb
|
||||
import net.liftweb.json.Extraction
|
||||
import net.liftweb.mapper.By
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.duration.DurationInt
|
||||
import scala.util.{Failure, Success}
|
||||
import okhttp3.{MediaType, Request, RequestBody}
|
||||
import code.webhook.OkHttpWebhookClient._
|
||||
|
||||
|
||||
object WebhookHttpClient extends MdcLoggable {
|
||||
@ -57,7 +48,7 @@ object WebhookHttpClient extends MdcLoggable {
|
||||
logger.debug("WebhookHttpClient.startEvent(WebhookRequestTrait) i.httpProtocol: " + i.httpProtocol)
|
||||
val payload = getEventPayload(request)
|
||||
logger.debug("WebhookHttpClient.startEvent(WebhookRequestTrait) payload: " + payload.toString)
|
||||
makeRequest(getHttpRequest(i.url, i.httpMethod, i.httpProtocol, getEventPayload(request)), request)
|
||||
makeAsynchronousRequest(composeRequest(i.url, i.httpMethod, i.httpProtocol, payload), request)
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +81,7 @@ object WebhookHttpClient extends MdcLoggable {
|
||||
logger.debug("WebhookHttpClient.startEvent(AccountNotificationWebhookRequest) i.httpProtocol: " + i.httpProtocol)
|
||||
val payload = getEventPayload(request)
|
||||
logger.debug("WebhookHttpClient.startEvent(AccountNotificationWebhookRequest) payload: " + payload.toString)
|
||||
makeRequest(getHttpRequest(i.url, i.httpMethod, i.httpProtocol, payload), request)
|
||||
makeAsynchronousRequest(composeRequest(i.url, i.httpMethod, i.httpProtocol, payload), request)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,58 +98,51 @@ object WebhookHttpClient extends MdcLoggable {
|
||||
* }
|
||||
*
|
||||
*/
|
||||
private def getEventPayload(request: WebhookRequestTrait): RequestEntity = {
|
||||
def getEventPayload(request: WebhookRequestTrait): Option[String] = {
|
||||
request.trigger match {
|
||||
case OnBalanceChange() | OnCreditTransaction() | OnDebitTransaction() | OnCreateTransaction() =>
|
||||
implicit val formats = CustomJsonFormats.formats
|
||||
val json = liftweb.json.compactRender(Extraction.decompose(request.toEventPayload))
|
||||
val entity: RequestEntity = HttpEntity(ContentTypes.`application/json`, json)
|
||||
entity
|
||||
Some(json)
|
||||
case _ =>
|
||||
HttpEntity.Empty
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function makes HttpRequest object according to the DB's data related to an account's webhook
|
||||
* @param uri In most cases it's a URL
|
||||
* @param method GET/POST/POST/DELETE
|
||||
* @param httpProtocol HTTP/1.0 / HTTP/1.1 / HTTP/2.0
|
||||
* @param entity For instance:
|
||||
* {
|
||||
* "event_name":"OnCreditTransaction",
|
||||
* "event_id":"fc7e4a71-5ff1-4006-95bb-7fd9e4adaef9",
|
||||
* "bank_id":"gh.29.uk.x",
|
||||
* "account_id":"private_01",
|
||||
* "amount":"50.00 EUR",
|
||||
* "balance":"739.00 EUR"
|
||||
* }
|
||||
* Please note it's empty in case of GET
|
||||
* @return HttpRequest object
|
||||
*/
|
||||
private def getHttpRequest(uri: String, method: String, httpProtocol: String, entity: RequestEntity = HttpEntity.Empty): HttpRequest = {
|
||||
* This function makes HttpRequest object according to the DB's data related to an account's webhook
|
||||
* @param uri In most cases it's a URL
|
||||
* @param method GET/POST/POST/DELETE
|
||||
* @param httpProtocol HTTP/1.0 / HTTP/1.1 / HTTP/2.0
|
||||
* @param json For instance:
|
||||
* {
|
||||
* "event_name":"OnCreditTransaction",
|
||||
* "event_id":"fc7e4a71-5ff1-4006-95bb-7fd9e4adaef9",
|
||||
* "bank_id":"gh.29.uk.x",
|
||||
* "account_id":"private_01",
|
||||
* "amount":"50.00 EUR",
|
||||
* "balance":"739.00 EUR"
|
||||
* }
|
||||
* Please note it's empty in case of GET
|
||||
* @return HttpRequest object
|
||||
*/
|
||||
def composeRequest(uri: String, method: String, httpProtocol: String, json: Option[String]): Request = {
|
||||
val jsonType = MediaType.parse("application/json; charset=utf-8");
|
||||
val body = RequestBody.create(jsonType, json.getOrElse(""))
|
||||
method match {
|
||||
case m: String if m.toUpperCase == "GET" =>
|
||||
HttpRequest(uri = uri, method = GET, protocol = getHttpProtocol(httpProtocol))
|
||||
new Request.Builder().url(uri).build
|
||||
case m: String if m.toUpperCase == "POST" =>
|
||||
HttpRequest(uri = uri, method = POST, entity = entity, protocol = getHttpProtocol(httpProtocol))
|
||||
new Request.Builder().url(uri).post(body).build
|
||||
case m: String if m.toUpperCase == "PUT" =>
|
||||
HttpRequest(uri = uri, method = PUT, entity = entity, protocol = getHttpProtocol(httpProtocol))
|
||||
new Request.Builder().url(uri).put(body).build
|
||||
case m: String if m.toUpperCase == "DELETE" =>
|
||||
HttpRequest(uri = uri, method = DELETE, entity = entity, protocol = getHttpProtocol(httpProtocol))
|
||||
new Request.Builder().url(uri).delete(body).build
|
||||
case _ =>
|
||||
HttpRequest(uri = uri, method = GET, protocol = getHttpProtocol(httpProtocol))
|
||||
new Request.Builder().url(uri).build
|
||||
}
|
||||
}
|
||||
|
||||
private def getHttpProtocol(httpProtocol: String): HttpProtocol = {
|
||||
httpProtocol match {
|
||||
case m: String if m.toUpperCase == "HTTP/1.0" => HttpProtocols.`HTTP/1.0`
|
||||
case m: String if m.toUpperCase == "HTTP/1.1" => HttpProtocols.`HTTP/1.1`
|
||||
case m: String if m.toUpperCase == "HTTP/2.0" => HttpProtocols.`HTTP/2.0`
|
||||
case _ => HttpProtocols.`HTTP/1.1`
|
||||
}
|
||||
}
|
||||
|
||||
private def logEvent(request: WebhookRequestTrait): Unit = {
|
||||
logger.debug("TRIGGER: " + request.trigger)
|
||||
@ -173,76 +157,11 @@ object WebhookHttpClient extends MdcLoggable {
|
||||
logger.debug("RELATED_ENTITIES: " + request.asInstanceOf[AccountNotificationWebhookRequest].relatedEntities)
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lazy implicit val system = ObpLookupSystem.obpLookupSystem
|
||||
implicit lazy val materializer = ActorMaterializer()
|
||||
// needed for the future flatMap/onComplete in the end
|
||||
implicit lazy val executionContext = system.dispatcher
|
||||
|
||||
// The Actor which has sent the request.
|
||||
// We need to respond to it after we finish an event.
|
||||
lazy val requestActor = ObpLookupSystem.getWebhookActor()
|
||||
|
||||
private def makeRequest(httpRequest: HttpRequest, request: WebhookRequestTrait): Unit = {
|
||||
makeHttpRequest(httpRequest).onComplete {
|
||||
case Success(res@HttpResponse(status, headers, entity, protocol)) =>
|
||||
requestActor ! WebhookResponse(status.toString(), request)
|
||||
res.discardEntityBytes()
|
||||
case Failure(error) =>
|
||||
requestActor ! WebhookFailure(error.getMessage, request)
|
||||
}
|
||||
}
|
||||
|
||||
private lazy val poolSettingsWithHttpsProxy =
|
||||
ConnectionPoolSettings.apply(system)
|
||||
/*
|
||||
# The minimum duration to backoff new connection attempts after the previous connection attempt failed.
|
||||
#
|
||||
# The pool uses an exponential randomized backoff scheme. After the first failure, the next attempt will only be
|
||||
# tried after a random duration between the base connection backoff and twice the base connection backoff. If that
|
||||
# attempt fails as well, the next attempt will be delayed by twice that amount. The total delay is capped using the
|
||||
# `max-connection-backoff` setting.
|
||||
#
|
||||
# The backoff applies for the complete pool. I.e. after one failed connection attempt, further connection attempts
|
||||
# to that host will backoff for all connections of the pool. After the service recovered, connections will come out
|
||||
# of backoff one by one due to the random extra backoff time. This is to avoid overloading just recently recovered
|
||||
# services with new connections ("thundering herd").
|
||||
#
|
||||
# Example: base-connection-backoff = 100ms, max-connection-backoff = 10 seconds
|
||||
# - After 1st failure, backoff somewhere between 100ms and 200ms
|
||||
# - After 2nd, between 200ms and 400ms
|
||||
# - After 3rd, between 200ms and 400ms
|
||||
# - After 4th, between 400ms and 800ms
|
||||
# - After 5th, between 800ms and 1600ms
|
||||
# - After 6th, between 1600ms and 3200ms
|
||||
# - After 7th, between 3200ms and 6400ms
|
||||
# - After 8th, between 5000ms and 10 seconds (max capped by max-connection-backoff, min by half of that)
|
||||
# - After 9th, etc., stays between 5000ms and 10 seconds
|
||||
#
|
||||
# This setting only applies to the new pool implementation and is ignored for the legacy one.
|
||||
*/
|
||||
.withBaseConnectionBackoff(1.second)
|
||||
/*
|
||||
# Maximum backoff duration between failed connection attempts. For more information see the above comment for the
|
||||
# `base-connection-backoff` setting.
|
||||
#
|
||||
# This setting only applies to the new pool implementation and is ignored for the legacy one.
|
||||
*/
|
||||
.withMaxConnectionBackoff(1.minute)
|
||||
/*
|
||||
# The maximum number of times failed requests are attempted again,
|
||||
# (if the request can be safely retried) before giving up and returning an error.
|
||||
# Set to zero to completely disable request retries.
|
||||
*/
|
||||
.withMaxRetries(5)
|
||||
|
||||
private def makeHttpRequest(httpRequest: HttpRequest): Future[HttpResponse] =
|
||||
Http().singleRequest(request = httpRequest, settings = poolSettingsWithHttpsProxy)
|
||||
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
val uri = "https://www.openbankproject.com"
|
||||
val uri = "https://publicobject.com/helloworld.txt"
|
||||
val request = WebhookRequest(
|
||||
trigger=ApiTrigger.onBalanceChange ,
|
||||
eventId="418044f2-f74e-412f-a4e1-a78cdacdef9c",
|
||||
@ -251,34 +170,25 @@ object WebhookHttpClient extends MdcLoggable {
|
||||
amount="10000",
|
||||
balance="21000"
|
||||
)
|
||||
makeRequest(getHttpRequest(uri, "GET", "HTTP/1.1"), request)
|
||||
makeAsynchronousRequest(
|
||||
composeRequest(uri, "GET", "HTTP/1.1", None),
|
||||
request
|
||||
)
|
||||
|
||||
implicit val formats = CustomJsonFormats.formats
|
||||
case class User(name: String, job: String)
|
||||
val user = User("morpheus", "leader")
|
||||
val json = liftweb.json.compactRender(Extraction.decompose(user))
|
||||
val entity: RequestEntity = HttpEntity(ContentTypes.`application/json`, json)
|
||||
makeHttpRequest(getHttpRequest("https://reqres.in/api/users", "POST", "HTTP/1.1", entity)) map {
|
||||
`POST response` =>
|
||||
org.scalameta.logger.elem(`POST response`.status)
|
||||
`POST response`.entity.dataBytes.runFold(ByteString(""))(_ ++ _).foreach { body =>
|
||||
val `Got POST response, body: ` = body.utf8String
|
||||
org.scalameta.logger.elem(`Got POST response, body: `)
|
||||
}
|
||||
}
|
||||
makeAsynchronousRequest(
|
||||
composeRequest("https://reqres.in/api/users", "POST", "HTTP/1.1", Some(json)),
|
||||
request)
|
||||
|
||||
val user2 = User("morpheus", "zion resident")
|
||||
val json2 = liftweb.json.compactRender(Extraction.decompose(user2))
|
||||
val entity2: RequestEntity = HttpEntity(ContentTypes.`application/json`, json2)
|
||||
makeHttpRequest(getHttpRequest("https://reqres.in/api/users", "PUT", "HTTP/1.1", entity2)) map {
|
||||
`PUT response` =>
|
||||
org.scalameta.logger.elem(`PUT response`.status)
|
||||
`PUT response`.entity.dataBytes.runFold(ByteString(""))(_ ++ _).foreach { body =>
|
||||
val `Got PUT response, body: ` = body.utf8String
|
||||
org.scalameta.logger.elem(`Got PUT response, body: `)
|
||||
}
|
||||
}
|
||||
|
||||
makeAsynchronousRequest(
|
||||
composeRequest("https://reqres.in/api/users/2", "PUT", "HTTP/1.1", Some(json2)),
|
||||
request
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><title>Plain HTML</title></head>
|
||||
<head>
|
||||
<title>Plain HTML</title>
|
||||
<script src="/media/js/jquery.min.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<h1>I am an Example HTML, no Liftweb involved. </h1>
|
||||
with a <a href="http://www.example.com">link</a>
|
||||
<h1>Link to static</h1><a href="/static">static image</a>
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head><title>Example HTML</title></head>
|
||||
<head>
|
||||
<script src="/media/js/jquery.min.js" type="text/javascript"></script>
|
||||
<title>Example HTML</title>
|
||||
</head>
|
||||
<body bgcolor="green">
|
||||
<h1>I am some Example HTML</h1>
|
||||
with a <a href="https://static.openbankproject.com/images/OBP/OBP_full_stack_web.png">image from static</a>
|
||||
|
||||
BIN
obp-api/src/test/resources/cert/localhost_SAN_dns_ip.pfx
Normal file
BIN
obp-api/src/test/resources/cert/localhost_SAN_dns_ip.pfx
Normal file
Binary file not shown.
@ -31,12 +31,11 @@ import java.util.ResourceBundle
|
||||
|
||||
import code.api.oauth1a.OauthParams._
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import code.api.util.ErrorMessages
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util.{APIUtil, ErrorMessages}
|
||||
import code.consumer.Consumers
|
||||
import code.loginattempts.LoginAttempt
|
||||
import code.model.dataAccess.{AuthUser, ResourceUser}
|
||||
import code.model.{Consumer => OBPConsumer, Token => OBPToken}
|
||||
import code.setup.ServerSetup
|
||||
import code.util.Helper.MdcLoggable
|
||||
import dispatch.Defaults._
|
||||
@ -322,35 +321,33 @@ class OAuthTest extends ServerSetup {
|
||||
}
|
||||
}
|
||||
|
||||
feature("Login in locked") {
|
||||
feature("Login is locked") {
|
||||
scenario("valid Username, invalid password, login in too many times. The username will be locked", Verifier, Oauth) {
|
||||
Given("we will use a valid request token to get the valid username and password")
|
||||
val reply = getRequestToken(consumer, selfCallback)
|
||||
val requestToken = extractToken(reply.body)
|
||||
|
||||
Then("we set the valid username, invalid password and try more than 5 times")
|
||||
Then("we set the valid username, invalid password and try more than 2 times")
|
||||
setPropsValues("max.bad.login.attempts"-> "2")
|
||||
val invalidPassword = "wrongpassword"
|
||||
var verifier = getVerifier(requestToken.value, user1.username.get, invalidPassword)
|
||||
verifier = getVerifier(requestToken.value, user1.username.get, invalidPassword)
|
||||
verifier = getVerifier(requestToken.value, user1.username.get, invalidPassword)
|
||||
verifier = getVerifier(requestToken.value, user1.username.get, invalidPassword)
|
||||
verifier = getVerifier(requestToken.value, user1.username.get, invalidPassword)
|
||||
verifier = getVerifier(requestToken.value, user1.username.get, invalidPassword)
|
||||
verifier = getVerifier(requestToken.value, user1.username.get, invalidPassword)
|
||||
|
||||
Then("we should get a locked account verifier")
|
||||
verifier.asInstanceOf[Failure].msg.contains(ErrorMessages.UsernameHasBeenLocked)
|
||||
verifier.asInstanceOf[Failure].msg.contains(ErrorMessages.UsernameHasBeenLocked) should equal (true)
|
||||
|
||||
|
||||
Then("We login in with valid username and password, it will still be failed")
|
||||
verifier = getVerifier(requestToken.value, user1.username.get, user1Password)
|
||||
|
||||
Then("we should get a locked account verifier")
|
||||
verifier.asInstanceOf[Failure].msg.contains(ErrorMessages.UsernameHasBeenLocked)
|
||||
verifier.asInstanceOf[Failure].msg.contains(ErrorMessages.UsernameHasBeenLocked) should equal (true)
|
||||
|
||||
Then("We unlock the username")
|
||||
LoginAttempt.resetBadLoginAttempts(user1.username.get)
|
||||
|
||||
setPropsValues("max.bad.login.attempts"-> "5")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -98,7 +98,6 @@ class SandboxDataLoadingTest extends FlatSpec with SendServerRequests with Match
|
||||
m == Nonce || m == code.model.Token || m == code.model.Consumer || m == AuthUser || m == ResourceUser
|
||||
}
|
||||
//drop database tables before
|
||||
//MongoDB.getDb(DefaultMongoIdentifier).foreach(_.dropDatabase())
|
||||
ToSchemify.models.filterNot(exclusion).foreach(_.bulkDelete_!!())
|
||||
ToSchemify.modelsRemotedata.filterNot(exclusion).foreach(_.bulkDelete_!!())
|
||||
//we need to delete the test uses manully here.
|
||||
|
||||
58
obp-api/src/test/scala/code/api/v5_1_0/IndexPageTest.scala
Normal file
58
obp-api/src/test/scala/code/api/v5_1_0/IndexPageTest.scala
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH
|
||||
Osloerstrasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
*/
|
||||
package code.api.v5_1_0
|
||||
|
||||
import okhttp3.{OkHttpClient, Request}
|
||||
|
||||
|
||||
class IndexPageTest extends V510ServerSetup {
|
||||
|
||||
/**
|
||||
* Test tags
|
||||
* Example: To run tests with tag "getPermissions":
|
||||
* mvn test -D tagsToInclude
|
||||
*
|
||||
* This is made possible by the scalatest maven plugin
|
||||
*/
|
||||
|
||||
feature("Test the response of the page /index.html ") {
|
||||
scenario("We create the apiCollection get All API collections back") {
|
||||
When("We make a request ")
|
||||
val client = new OkHttpClient
|
||||
val request = new Request.Builder().url(s"http://${server.host}:${server.port}/index.html").build
|
||||
val responseFirst = client.newCall(request).execute
|
||||
val startTime: Long = System.currentTimeMillis()
|
||||
val responseSecond = client.newCall(request).execute
|
||||
val endTime: Long = System.currentTimeMillis()
|
||||
Then("We should get a 200")
|
||||
responseSecond.code should equal(200)
|
||||
val duration: Long = endTime - startTime
|
||||
And(s"And duration($duration) is less than 1000 ms")
|
||||
duration should be <= 1000L
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,107 +0,0 @@
|
||||
package code.setup
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model._
|
||||
import code.model.dataAccess._
|
||||
import com.mongodb.QueryBuilder
|
||||
import net.liftweb.util.Helpers._
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.openbankproject.commons.model.{AccountId, Bank, BankAccount, BankId}
|
||||
|
||||
import scala.math.BigDecimal
|
||||
import scala.math.BigDecimal.RoundingMode
|
||||
import scala.util.Random._
|
||||
|
||||
/**
|
||||
* This trait is for Liftweb record, link to MangoDB....
|
||||
*/
|
||||
trait LocalRecordConnectorTestSetup extends TestConnectorSetupWithStandardPermissions {
|
||||
|
||||
override protected def createBank(id : String) : Bank = {
|
||||
HostedBank.createRecord.
|
||||
name(randomString(5)).
|
||||
alias(randomString(5)).
|
||||
permalink(id).
|
||||
national_identifier(randomString(5)).
|
||||
save(true)
|
||||
}
|
||||
|
||||
override protected def createAccount(bankId: BankId, accountId : AccountId, currency : String) : BankAccount = {
|
||||
val q = QueryBuilder.start(HostedBank.permalink.name).is(bankId.value).get()
|
||||
val hostedBank = HostedBank.find(q).openOrThrowException(attemptedToOpenAnEmptyBox)
|
||||
|
||||
Account.createRecord.
|
||||
accountBalance(900000000).
|
||||
holder(randomString(4)).
|
||||
accountNumber(randomString(4)).
|
||||
kind(randomString(4)).
|
||||
accountName(randomString(4)).
|
||||
permalink(accountId.value).
|
||||
bankID(hostedBank.id.get).
|
||||
accountLabel(randomString(4)).
|
||||
accountCurrency(currency).
|
||||
save(true)
|
||||
}
|
||||
|
||||
override protected def createTransaction(account: BankAccount, startDate: Date, finishDate: Date) = {
|
||||
|
||||
val thisAccountBank = OBPBank.createRecord.
|
||||
IBAN(randomString(5)).
|
||||
national_identifier(account.nationalIdentifier).
|
||||
name(account.bankName)
|
||||
val thisAccount = OBPAccount.createRecord.
|
||||
holder(account.accountHolder).
|
||||
number(account.number).
|
||||
kind(account.accountType).
|
||||
bank(thisAccountBank)
|
||||
|
||||
val otherAccountBank = OBPBank.createRecord.
|
||||
IBAN(randomString(5)).
|
||||
national_identifier(randomString(5)).
|
||||
name(randomString(5))
|
||||
|
||||
val otherAccount = OBPAccount.createRecord.
|
||||
holder(randomString(5)).
|
||||
number(randomString(5)).
|
||||
kind(randomString(5)).
|
||||
bank(otherAccountBank)
|
||||
|
||||
val transactionAmount = BigDecimal(nextDouble * 1000).setScale(2,RoundingMode.HALF_UP)
|
||||
|
||||
val newBalance : OBPBalance = OBPBalance.createRecord.
|
||||
currency(account.currency).
|
||||
amount(account.balance + transactionAmount)
|
||||
|
||||
val newValue : OBPValue = OBPValue.createRecord.
|
||||
currency(account.currency).
|
||||
amount(transactionAmount)
|
||||
|
||||
val details ={
|
||||
OBPDetails
|
||||
.createRecord
|
||||
.kind(randomString(5))
|
||||
.posted(startDate)
|
||||
.other_data(randomString(5))
|
||||
.new_balance(newBalance)
|
||||
.value(newValue)
|
||||
.completed(finishDate)
|
||||
.label(randomString(5))
|
||||
}
|
||||
val transaction = OBPTransaction.createRecord.
|
||||
this_account(thisAccount).
|
||||
other_account(otherAccount).
|
||||
details(details)
|
||||
|
||||
val env = OBPEnvelope.createRecord.
|
||||
obp_transaction(transaction).save(true)
|
||||
|
||||
//slightly ugly
|
||||
account.asInstanceOf[Account].accountBalance(newBalance.amount.get).accountLastUpdate(now).save(true)
|
||||
|
||||
env.save(true)
|
||||
}
|
||||
|
||||
override protected def createTransactionRequest(account: BankAccount) = Nil
|
||||
|
||||
}
|
||||
@ -8,8 +8,6 @@ import code.model.dataAccess._
|
||||
import code.views.Views
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.mapper.MetaMapper
|
||||
import net.liftweb.mongodb._
|
||||
import net.liftweb.util.DefaultConnectionIdentifier
|
||||
import net.liftweb.util.Helpers._
|
||||
|
||||
/**
|
||||
@ -40,9 +38,6 @@ trait TestConnectorSetupWithStandardPermissions extends TestConnectorSetup {
|
||||
|
||||
protected def wipeTestData(): Unit = {
|
||||
|
||||
//drop the mongo Database after each test
|
||||
MongoDB.getDb(DefaultConnectionIdentifier).foreach(_.dropDatabase())
|
||||
|
||||
//returns true if the model should not be wiped after each test
|
||||
def exclusion(m : MetaMapper[_]) = {
|
||||
m == Nonce || m == Token || m == Consumer || m == AuthUser || m == ResourceUser
|
||||
|
||||
@ -41,14 +41,14 @@ import net.liftweb.http.provider.HTTPParam
|
||||
import org.scalatest.{FeatureSpec, GivenWhenThen, Matchers}
|
||||
|
||||
class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with PropsReset {
|
||||
|
||||
|
||||
val DefaultFromDateString = APIUtil.epochTimeString
|
||||
val DefaultToDateString = APIUtil.DefaultToDateString
|
||||
val startDateString = DefaultFromDateString
|
||||
val startDateStringWrongFormat = "Wrong Date Format"
|
||||
val endDateString = DefaultToDateString
|
||||
val endDateStringWrongFormat = "Wrong Date Format"
|
||||
val inputStringDateFormat = DateWithMsFormat
|
||||
val DefaultFromDateString = APIUtil.epochTimeString
|
||||
val DefaultToDateString = APIUtil.DefaultToDateString
|
||||
val startDateObject: Date = DateWithMsFormat.parse(DefaultFromDateString)
|
||||
val endDateObject: Date = DateWithMsFormat.parse(DefaultToDateString)
|
||||
ZonedDateTime.now(ZoneId.of("UTC"))
|
||||
@ -239,7 +239,7 @@ class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with Prop
|
||||
val httpParams: List[HTTPParam] = List(HTTPParam("wrongName", List(s"$DateWithMsExampleString")))
|
||||
val startTime = OBPFromDate(theEpochTime)
|
||||
val returnValue = getFromDate(httpParams)
|
||||
returnValue shouldBe a[Full[OBPFromDate]]
|
||||
returnValue.toString should startWith("Full(OBPFromDate")
|
||||
|
||||
val currentTime = OBPFromDate(theEpochTime)
|
||||
val beWithinTolerance = be >= startTime and be <= currentTime
|
||||
@ -251,7 +251,7 @@ class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with Prop
|
||||
val httpParams: List[HTTPParam] = List(HTTPParam("wrongName", List("wrongValue")))
|
||||
val startTime = OBPFromDate(theEpochTime)
|
||||
val returnValue = getFromDate(httpParams)
|
||||
returnValue shouldBe a[Full[OBPFromDate]]
|
||||
returnValue.toString should startWith("Full(OBPFromDate")
|
||||
|
||||
val currentTime = OBPFromDate(theEpochTime)
|
||||
val beWithinTolerance = be >= startTime and be <= currentTime
|
||||
@ -293,7 +293,7 @@ class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with Prop
|
||||
val startTime = OBPToDate(DefaultToDate)
|
||||
|
||||
val returnValue = getToDate(httpParams)
|
||||
returnValue shouldBe a[Full[OBPToDate]]
|
||||
returnValue.toString should startWith("Full(OBPToDate")
|
||||
|
||||
val currentTime = OBPToDate(DefaultToDate)
|
||||
val beWithinTolerance = be >= startTime and be <= currentTime
|
||||
@ -307,7 +307,7 @@ class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with Prop
|
||||
val startTime = OBPToDate(DefaultToDate)
|
||||
|
||||
val returnValue = getToDate(httpParams)
|
||||
returnValue shouldBe a[Full[OBPToDate]]
|
||||
returnValue.toString should startWith("Full(OBPToDate")
|
||||
|
||||
val currentTime = OBPToDate(DefaultToDate)
|
||||
val beWithinTolerance = be >= startTime and be <= currentTime
|
||||
|
||||
@ -44,7 +44,7 @@ import java.util.Date
|
||||
*
|
||||
*
|
||||
* 3 RelationShips:
|
||||
* 1)When `Sign up` new user --> create AuthUser --> call AuthUser.save() --> create ResourceUser user.
|
||||
* 1)When `Sign up` new user --> create AuthUser --> call AuthUser.save --> create ResourceUser user.
|
||||
* They share the same username and email.
|
||||
* 2)AuthUser `user` field as the Foreign Key to link to Resource User.
|
||||
* one AuthUser <---> one ResourceUser
|
||||
|
||||
@ -32,7 +32,7 @@ object JsonSerializers {
|
||||
override def lookupParameterNames(constructor: Constructor[_]): Traversable[String] = try {
|
||||
defaultFormats.parameterNameReader.lookupParameterNames(constructor)
|
||||
} catch {
|
||||
case _ => constructor.getParameters.map(_.getName)
|
||||
case _ : Throwable => constructor.getParameters.map(_.getName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
pom.xml
4
pom.xml
@ -11,12 +11,12 @@
|
||||
<inceptionYear>2011</inceptionYear>
|
||||
<properties>
|
||||
<scala.version>2.12</scala.version>
|
||||
<scala.compiler>2.12.10</scala.compiler>
|
||||
<scala.compiler>2.12.12</scala.compiler>
|
||||
<akka.version>2.5.32</akka.version>
|
||||
<akka-streams-kafka.version>2.0.5</akka-streams-kafka.version>
|
||||
<kafka.version>1.1.0</kafka.version>
|
||||
<avro.version>1.8.2</avro.version>
|
||||
<lift.version>3.4.1</lift.version>
|
||||
<lift.version>3.5.0</lift.version>
|
||||
<jetty.version>9.4.50.v20221201</jetty.version>
|
||||
<log4j.version>2.17.1</log4j.version>
|
||||
<obp-ri.version>2016.11-RC6-SNAPSHOT</obp-ri.version>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user