From 5fd595e5693b8122b8221d5d1335017126bc846d Mon Sep 17 00:00:00 2001 From: Petar Bozin Date: Mon, 24 Oct 2016 19:45:34 +0200 Subject: [PATCH] Fixed Boot.scala --- src/main/scala/bootstrap/liftweb/Boot.scala | 429 ++++++++++---------- 1 file changed, 209 insertions(+), 220 deletions(-) mode change 100755 => 100644 src/main/scala/bootstrap/liftweb/Boot.scala diff --git a/src/main/scala/bootstrap/liftweb/Boot.scala b/src/main/scala/bootstrap/liftweb/Boot.scala old mode 100755 new mode 100644 index 61a961187..edcd0fab0 --- a/src/main/scala/bootstrap/liftweb/Boot.scala +++ b/src/main/scala/bootstrap/liftweb/Boot.scala @@ -1,33 +1,33 @@ /** - * Open Bank Project - API - * Copyright (C) 2011-2016, TESOBE / Music Pictures Ltd - ** - *This program is free software: you can redistribute it and/or modify - *it under the terms of the GNU Affero General Public License as published by - *the Free Software Foundation, either version 3 of the License, or - *(at your option) any later version. - ** - *This program is distributed in the hope that it will be useful, - *but WITHOUT ANY WARRANTY; without even the implied warranty of - *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - *GNU Affero General Public License for more details. - ** - *You should have received a copy of the GNU Affero General Public License -*along with this program. If not, see . - ** - *Email: contact@tesobe.com -*TESOBE / Music Pictures Ltd -*Osloerstrasse 16/17 -*Berlin 13359, Germany - ** - *This product includes software developed at - *TESOBE (http://www.tesobe.com/) - * by - *Simon Redfern : simon AT tesobe DOT com - *Stefan Bethge : stefan AT tesobe DOT com - *Everett Sochowski : everett AT tesobe DOT com - *Ayoub Benali: ayoub AT tesobe DOT com - * +Open Bank Project - API +Copyright (C) 2011-2016, TESOBE / Music Pictures Ltd + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + +Email: contact@tesobe.com +TESOBE / Music Pictures Ltd +Osloerstrasse 16/17 +Berlin 13359, Germany + + This product includes software developed at + TESOBE (http://www.tesobe.com/) + by + Simon Redfern : simon AT tesobe DOT com + Stefan Bethge : stefan AT tesobe DOT com + Everett Sochowski : everett AT tesobe DOT com + Ayoub Benali: ayoub AT tesobe DOT com + */ package bootstrap.liftweb @@ -62,7 +62,7 @@ import code.model.dataAccess._ import code.products.MappedProduct import code.transaction_types.MappedTransactionType import code.snippet.{OAuthAuthorisation, OAuthWorkedThanks} -import code.transactionrequests.{MappedTransactionRequest, MappedTransactionRequest210} +import code.transactionrequests.{MappedTransactionRequest210, MappedTransactionRequest} import code.usercustomerlinks.MappedUserCustomerLink import net.liftweb.common._ import net.liftweb.http._ @@ -73,8 +73,7 @@ import net.liftweb.util.Helpers._ import net.liftweb.util.{Helpers, Schedule, _} import code.api.Constant._ import code.transaction.MappedTransaction -import code.views.{AkkaMapperViewsActor, RemoteDataStandalone} -import com.typesafe.config.ConfigFactory +import code.views.RemoteDataStandalone /** @@ -141,219 +140,209 @@ class Boot extends Loggable{ firstChoicePropsDir.flatten.toList ::: secondChoicePropsDir.flatten.toList } - // set up the way to connect to the relational DB we're using (ok if other connector than relational) - if (!DB.jndiJdbcConnAvailable_?) { - val driver = - Props.mode match { - case Props.RunModes.Production | Props.RunModes.Staging | Props.RunModes.Development => Props.get("db.driver") openOr "org.h2.Driver" - case _ => "org.h2.Driver" - } - val vendor = - Props.mode match { - case Props.RunModes.Production | Props.RunModes.Staging | Props.RunModes.Development => - new StandardDBVendor(driver, - Props.get("db.url") openOr "jdbc:h2:lift_proto.db;AUTO_SERVER=TRUE", - Props.get("db.user"), Props.get("db.password")) - case _ => - new StandardDBVendor( - driver, - "jdbc:h2:mem:OBPTest;DB_CLOSE_DELAY=-1", - Empty, Empty) - } + // set up the way to connect to the relational DB we're using (ok if other connector than relational) + if (!DB.jndiJdbcConnAvailable_?) { + val driver = + Props.mode match { + case Props.RunModes.Production | Props.RunModes.Staging | Props.RunModes.Development => Props.get("db.driver") openOr "org.h2.Driver" + case _ => "org.h2.Driver" + } + val vendor = + Props.mode match { + case Props.RunModes.Production | Props.RunModes.Staging | Props.RunModes.Development => + new StandardDBVendor(driver, + Props.get("db.url") openOr "jdbc:h2:lift_proto.db;AUTO_SERVER=TRUE", + Props.get("db.user"), Props.get("db.password")) + case _ => + new StandardDBVendor( + driver, + "jdbc:h2:mem:OBPTest;DB_CLOSE_DELAY=-1", + Empty, Empty) + } - logger.debug("Using database driver: " + driver) - LiftRules.unloadHooks.append(vendor.closeAllConnections_! _) + logger.debug("Using database driver: " + driver) + LiftRules.unloadHooks.append(vendor.closeAllConnections_! _) - DB.defineConnectionManager(net.liftweb.util.DefaultConnectionIdentifier, vendor) - } + DB.defineConnectionManager(net.liftweb.util.DefaultConnectionIdentifier, vendor) + } - // ensure our relational database's tables are created/fit the schema - if (Props.get("connector").getOrElse("") == "mapped" || - Props.get("connector").getOrElse("").startsWith("kafka")) - schemifyAll() + // ensure our relational database's tables are created/fit the schema + if(Props.get("connector").getOrElse("") == "mapped" || + Props.get("connector").getOrElse("") == "kafka" ) + schemifyAll() - // This sets up MongoDB config (for the mongodb connector) - if (Props.get("connector").getOrElse("") == "mongodb") - MongoConfig.init + // This sets up MongoDB config (for the mongodb connector) + if(Props.get("connector").getOrElse("") == "mongodb") + MongoConfig.init - val runningMode = Props.mode match { - case Props.RunModes.Production => "Production mode" - case Props.RunModes.Staging => "Staging mode" - case Props.RunModes.Development => "Development mode" - case Props.RunModes.Test => "test mode" - case _ => "other mode" - } + val runningMode = Props.mode match { + case Props.RunModes.Production => "Production mode" + case Props.RunModes.Staging => "Staging mode" + case Props.RunModes.Development => "Development mode" + case Props.RunModes.Test => "test mode" + case _ => "other mode" + } - logger.info("running mode: " + runningMode) - logger.info(s"ApiPathZero (the bit before version) is $ApiPathZero") + logger.info("running mode: " + runningMode) + logger.info(s"ApiPathZero (the bit before version) is $ApiPathZero") - // where to search snippets - LiftRules.addToPackages("code") + // where to search snippets + LiftRules.addToPackages("code") - //OAuth API call - LiftRules.statelessDispatch.append(OAuthHandshake) + //OAuth API call + LiftRules.statelessDispatch.append(OAuthHandshake) - // JWT auth endpoints - if (Props.getBool("allow_direct_login", true)) { - LiftRules.statelessDispatch.append(DirectLogin) - } + // JWT auth endpoints + if(Props.getBool("allow_direct_login", true)) { + LiftRules.statelessDispatch.append(DirectLogin) + } - // Get disbled API versions from props - val disabledVersions = Props.get("api_disabled_versions").getOrElse("").replace("[", "").replace("]", "").split(",") + // Get disbled API versions from props + val disabledVersions = Props.get("api_disabled_versions").getOrElse("").replace("[", "").replace("]", "").split(",") - // OpenIdConnect endpoint and validator - if (Props.getBool("allow_openidconnect", false)) { - LiftRules.dispatch.append(OpenIdConnect) - } + // OpenIdConnect endpoint and validator + if(Props.getBool("allow_openidconnect", false)) { + LiftRules.dispatch.append(OpenIdConnect) + } - // Add the various API versions - if (!disabledVersions.contains("v1_0")) LiftRules.statelessDispatch.append(v1_0.OBPAPI1_0) - if (!disabledVersions.contains("v1_1")) LiftRules.statelessDispatch.append(v1_1.OBPAPI1_1) - if (!disabledVersions.contains("v1_2")) LiftRules.statelessDispatch.append(v1_2.OBPAPI1_2) - // Can we depreciate the above? - if (!disabledVersions.contains("v1_2_1")) LiftRules.statelessDispatch.append(v1_2_1.OBPAPI1_2_1) - if (!disabledVersions.contains("v1_3_0")) LiftRules.statelessDispatch.append(v1_3_0.OBPAPI1_3_0) - if (!disabledVersions.contains("v1_4_0")) LiftRules.statelessDispatch.append(v1_4_0.OBPAPI1_4_0) - if (!disabledVersions.contains("v2_0_0")) LiftRules.statelessDispatch.append(v2_0_0.OBPAPI2_0_0) - if (!disabledVersions.contains("v2_1_0")) LiftRules.statelessDispatch.append(v2_1_0.OBPAPI2_1_0) + // Add the various API versions + if (!disabledVersions.contains("v1_0")) LiftRules.statelessDispatch.append(v1_0.OBPAPI1_0) + if (!disabledVersions.contains("v1_1")) LiftRules.statelessDispatch.append(v1_1.OBPAPI1_1) + if (!disabledVersions.contains("v1_2")) LiftRules.statelessDispatch.append(v1_2.OBPAPI1_2) + // Can we depreciate the above? + if (!disabledVersions.contains("v1_2_1")) LiftRules.statelessDispatch.append(v1_2_1.OBPAPI1_2_1) + if (!disabledVersions.contains("v1_3_0")) LiftRules.statelessDispatch.append(v1_3_0.OBPAPI1_3_0) + if (!disabledVersions.contains("v1_4_0")) LiftRules.statelessDispatch.append(v1_4_0.OBPAPI1_4_0) + if (!disabledVersions.contains("v2_0_0")) LiftRules.statelessDispatch.append(v2_0_0.OBPAPI2_0_0) + if (!disabledVersions.contains("v2_1_0")) LiftRules.statelessDispatch.append(v2_1_0.OBPAPI2_1_0) - //add management apis - LiftRules.statelessDispatch.append(ImporterAPI) - LiftRules.statelessDispatch.append(AccountsAPI) + //add management apis + LiftRules.statelessDispatch.append(ImporterAPI) + LiftRules.statelessDispatch.append(AccountsAPI) - // add other apis - LiftRules.statelessDispatch.append(BankMockAPI) + // add other apis + LiftRules.statelessDispatch.append(BankMockAPI) - // Add Resource Docs - LiftRules.statelessDispatch.append(ResourceDocs) + // Add Resource Docs + LiftRules.statelessDispatch.append(ResourceDocs) - // LiftRules.statelessDispatch.append(Metrics) TODO: see metric menu entry below + // LiftRules.statelessDispatch.append(Metrics) TODO: see metric menu entry below - //add sandbox api calls only if we're running in sandbox mode - if (Props.getBool("allow_sandbox_data_import", false)) { - LiftRules.statelessDispatch.append(SandboxApiCalls) + //add sandbox api calls only if we're running in sandbox mode + if(Props.getBool("allow_sandbox_data_import", false)) { + LiftRules.statelessDispatch.append(SandboxApiCalls) + } else { + logger.info("Not adding sandbox api calls") + } + + //launch the scheduler to clean the database from the expired tokens and nonces + Schedule.schedule(()=> OAuthAuthorisation.dataBaseCleaner, 2 minutes) + + val accountCreation = { + if(Props.getBool("allow_sandbox_account_creation", false)){ + //user must be logged in, as a created account needs an owner + // Not mentioning test and sandbox for App store purposes right now. + List(Menu("Sandbox Account Creation", "Create Bank Account") / "create-sandbox-account" >> OBPUser.loginFirst) } else { - logger.info("Not adding sandbox api calls") + Nil } + } - //launch the scheduler to clean the database from the expired tokens and nonces - Schedule.schedule(() => OAuthAuthorisation.dataBaseCleaner, 2 minutes) + // API Metrics (logs of API calls) + // If set to true we will write each URL with params to a datastore / log file + if (Props.getBool("write_metrics", false)) { + logger.info("writeMetrics is true. We will write API metrics") + } else { + logger.info("writeMetrics is false. We will NOT write API metrics") + } + + + // Build SiteMap + val sitemap = List( + Menu.i("Home") / "index", + Menu.i("Consumer Admin") / "admin" / "consumers" >> Admin.loginFirst >> LocGroup("admin") + submenus(Consumer.menus : _*), + Menu("Consumer Registration", "Get API Key") / "consumer-registration" >> OBPUser.loginFirst, + // Menu.i("Metrics") / "metrics", //TODO: allow this page once we can make the account number anonymous in the URL + Menu.i("OAuth") / "oauth" / "authorize", //OAuth authorization page + OAuthWorkedThanks.menu //OAuth thanks page that will do the redirect + ) ++ accountCreation ++ Admin.menus + + def sitemapMutators = OBPUser.sitemapMutator + + // set the sitemap. Note if you don't want access control for + // each page, just comment this line out. + LiftRules.setSiteMapFunc(() => sitemapMutators(SiteMap(sitemap : _*))) + // Use jQuery 1.4 + LiftRules.jsArtifacts = net.liftweb.http.js.jquery.JQuery14Artifacts + + //Show the spinny image when an Ajax call starts + LiftRules.ajaxStart = + Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd) + + // Make the spinny image go away when it ends + LiftRules.ajaxEnd = + Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd) + + // Force the request to be UTF-8 + LiftRules.early.append(_.setCharacterEncoding("UTF-8")) + + // What is the function to test if a user is logged in? + LiftRules.loggedInTest = Full(() => OBPUser.loggedIn_?) + + // Template(/Response?) encoding + LiftRules.early.append(_.setCharacterEncoding("utf-8")) + + // Use HTML5 for rendering + LiftRules.htmlProperties.default.set((r: Req) => + new Html5Properties(r.userAgent)) + + LiftRules.explicitlyParsedSuffixes = Helpers.knownSuffixes &~ (Set("com")) + + //set base localization to english (instead of computer default) + Locale.setDefault(Locale.ENGLISH) + + //override locale calculated from client request with default (until we have translations) + LiftRules.localeCalculator = { + case fullReq @ Full(req) => Locale.ENGLISH + case _ => Locale.ENGLISH + } + + // Make a transaction span the whole HTTP request + S.addAround(DB.buildLoanWrapper) + + try { + val useMessageQueue = Props.getBool("messageQueue.createBankAccounts", false) + if(useMessageQueue) + BankAccountCreationListener.startListen + } catch { + case e: java.lang.ExceptionInInitializerError => logger.warn(s"BankAccountCreationListener Exception: $e") + } + + Mailer.devModeSend.default.set( (m : MimeMessage) => { + logger.info("Would have sent email if not in dev mode: " + m.getContent) + }) + + LiftRules.exceptionHandler.prepend{ + //same as default LiftRules.exceptionHandler + case(Props.RunModes.Development, r, e) => { + logger.error("Exception being returned to browser when processing " + r.uri.toString, e) + XhtmlResponse(( Exception occured while processing {r.uri}
{showException(e)}
), S.htmlProperties.docType, List("Content-Type" -> "text/html; charset=utf-8"), Nil, 500, S.legacyIeCompatibilityMode) - val accountCreation = { - if (Props.getBool("allow_sandbox_account_creation", false)) { - //user must be logged in, as a created account needs an owner - // Not mentioning test and sandbox for App store purposes right now. - List(Menu("Sandbox Account Creation", "Create Bank Account") / "create-sandbox-account" >> OBPUser.loginFirst) - } else { - Nil - } } - - // API Metrics (logs of API calls) - // If set to true we will write each URL with params to a datastore / log file - if (Props.getBool("write_metrics", false)) { - logger.info("writeMetrics is true. We will write API metrics") - } else { - logger.info("writeMetrics is false. We will NOT write API metrics") + //same as default LiftRules.exceptionHandler, except that it also send an email notification + case (_, r , e) => { + sendExceptionEmail(e) + logger.error("Exception being returned to browser when processing " + r.uri.toString, e) + XhtmlResponse(( Something unexpected happened while serving the page at {r.uri} ), S.htmlProperties.docType, List("Content-Type" -> "text/html; charset=utf-8"), Nil, 500, S.legacyIeCompatibilityMode) } + } - - // Build SiteMap - val sitemap = List( - Menu.i("Home") / "index", - Menu.i("Consumer Admin") / "admin" / "consumers" >> Admin.loginFirst >> LocGroup("admin") - submenus (Consumer.menus: _*), - Menu("Consumer Registration", "Get API Key") / "consumer-registration" >> OBPUser.loginFirst, - // Menu.i("Metrics") / "metrics", //TODO: allow this page once we can make the account number anonymous in the URL - Menu.i("OAuth") / "oauth" / "authorize", //OAuth authorization page - OAuthWorkedThanks.menu //OAuth thanks page that will do the redirect - ) ++ accountCreation ++ Admin.menus - - def sitemapMutators = OBPUser.sitemapMutator - - // set the sitemap. Note if you don't want access control for - // each page, just comment this line out. - LiftRules.setSiteMapFunc(() => sitemapMutators(SiteMap(sitemap: _*))) - // Use jQuery 1.4 - LiftRules.jsArtifacts = net.liftweb.http.js.jquery.JQuery14Artifacts - - //Show the spinny image when an Ajax call starts - LiftRules.ajaxStart = - Full(() => LiftRules.jsArtifacts.show("ajax-loader").cmd) - - // Make the spinny image go away when it ends - LiftRules.ajaxEnd = - Full(() => LiftRules.jsArtifacts.hide("ajax-loader").cmd) - - // Force the request to be UTF-8 - LiftRules.early.append(_.setCharacterEncoding("UTF-8")) - - // What is the function to test if a user is logged in? - LiftRules.loggedInTest = Full(() => OBPUser.loggedIn_?) - - // Template(/Response?) encoding - LiftRules.early.append(_.setCharacterEncoding("utf-8")) - - // Use HTML5 for rendering - LiftRules.htmlProperties.default.set((r: Req) => - new Html5Properties(r.userAgent)) - - LiftRules.explicitlyParsedSuffixes = Helpers.knownSuffixes &~ (Set("com")) - - //set base localization to english (instead of computer default) - Locale.setDefault(Locale.ENGLISH) - - //override locale calculated from client request with default (until we have translations) - LiftRules.localeCalculator = { - case fullReq@Full(req) => Locale.ENGLISH - case _ => Locale.ENGLISH - } - - // Make a transaction span the whole HTTP request - S.addAround(DB.buildLoanWrapper) - - try { - val useMessageQueue = Props.getBool("messageQueue.createBankAccounts", false) - if (useMessageQueue) - BankAccountCreationListener.startListen - } catch { - case e: java.lang.ExceptionInInitializerError => logger.warn(s"BankAccountCreationListener Exception: $e") - } - - Mailer.devModeSend.default.set((m: MimeMessage) => { - logger.info("Would have sent email if not in dev mode: " + m.getContent) - }) - - LiftRules.exceptionHandler.prepend { - //same as default LiftRules.exceptionHandler - case (Props.RunModes.Development, r, e) => { - logger.error("Exception being returned to browser when processing " + r.uri.toString, e) - XhtmlResponse(( - Exception occured while processing - {r.uri}
-              {showException(e)}
-            
- - ), S.htmlProperties.docType, List("Content-Type" -> "text/html; charset=utf-8"), Nil, 500, S.legacyIeCompatibilityMode) - - } - //same as default LiftRules.exceptionHandler, except that it also send an email notification - case (_, r, e) => { - sendExceptionEmail(e) - logger.error("Exception being returned to browser when processing " + r.uri.toString, e) - XhtmlResponse(( - Something unexpected happened while serving the page at - {r.uri} - - ), S.htmlProperties.docType, List("Content-Type" -> "text/html; charset=utf-8"), Nil, 500, S.legacyIeCompatibilityMode) - } - } - - if (!Props.getBool("enable_akka_remote_data", false)) { - RemoteDataStandalone.startLocalWorkerSystem() - } + if (!Props.getBool("enable_akka_remote_data", false)) { + RemoteDataStandalone.startLocalWorkerSystem() + } } @@ -448,5 +437,5 @@ object ToSchemify { Nonce, OBPUser, Token - ) + ) }