Skip to content

Commit

Permalink
OpenBankProject#59 Get props from OS system environment, just like OB…
Browse files Browse the repository at this point in the history
…P API
  • Loading branch information
hongwei1 committed Feb 14, 2019
1 parent 76d5611 commit d61ce82
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 89 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/bootstrap/liftweb/Boot.scala
Expand Up @@ -124,7 +124,7 @@ class Boot extends MdcLoggable{
firstChoicePropsDir.toList.flatten ::: secondChoicePropsDir.toList.flatten
}

if(Props.get("defaultAuthProvider").isEmpty) {
if(Helper.getPropsValue("defaultAuthProvider").isEmpty) {
throw new Exception("defaultAuthProvider must be specified in the props file!")
}

Expand Down
15 changes: 8 additions & 7 deletions src/main/scala/code/lib/OAuthClient.scala
Expand Up @@ -32,6 +32,7 @@ Berlin 13359, Germany

package code.lib

import code.util.Helper
import net.liftweb.http.SessionVar
import net.liftweb.common.Box
import net.liftweb.common.Empty
Expand All @@ -42,7 +43,7 @@ import net.liftweb.http.S
import oauth.signpost.OAuthConsumer
import oauth.signpost.basic.DefaultOAuthConsumer
import net.liftweb.mapper.By
import net.liftweb.common.{Full, Failure}
import net.liftweb.common.{Failure, Full}
import net.liftweb.util.Helpers
import net.liftweb.http.LiftResponse
import code.util.Helper.MdcLoggable
Expand All @@ -69,13 +70,13 @@ sealed trait Provider {
trait DefaultProvider extends Provider with MdcLoggable {
val name = "The Open Bank Project Demo"

// val baseUrl = Props.get("oauth_1.hostname").getOrElse(Props.get("api_hostname", S.hostName))
val baseUrl = Props.get("oauth_1.hostname") match {
// val baseUrl = Helper.getPropsValue("oauth_1.hostname").getOrElse(Helper.getPropsValue("api_hostname", S.hostName))
val baseUrl = Helper.getPropsValue("oauth_1.hostname") match {
case Full(v) =>
v
case _ =>
logger.warn("==========>> THERE IS NO THE VALUE FOR PROPS oauth_1.hostname <<====================")
Props.get("api_hostname") match {
Helper.getPropsValue("api_hostname") match {
case Full(v) =>
v
case _ =>
Expand All @@ -92,8 +93,8 @@ trait DefaultProvider extends Provider with MdcLoggable {

lazy val oAuthProvider : OAuthProvider = new DefaultOAuthProvider(requestTokenUrl, accessTokenUrl, authorizeUrl)

val consumerKey = Props.get("obp_consumer_key", "")
val consumerSecret = Props.get("obp_secret_key", "")
val consumerKey = Helper.getPropsValue("obp_consumer_key", "")
val consumerSecret = Helper.getPropsValue("obp_secret_key", "")
}

object OBPDemo extends DefaultProvider
Expand Down Expand Up @@ -165,7 +166,7 @@ object OAuthClient extends MdcLoggable {
mostRecentLoginAttemptProvider.set(Full(provider))
val credential = setNewCredential(provider)

val authUrl = provider.oAuthProvider.retrieveRequestToken(credential.consumer, Props.get("base_url", S.hostName) + "/oauthcallback")
val authUrl = provider.oAuthProvider.retrieveRequestToken(credential.consumer, Helper.getPropsValue("base_url", S.hostName) + "/oauthcallback")
S.redirectTo(authUrl)
}

Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/code/lib/ObpAPI.scala
Expand Up @@ -6,6 +6,7 @@ import java.text.SimpleDateFormat
import java.util.Date

import code.lib.ObpJson._
import code.util.Helper
import code.util.Helper.MdcLoggable
import net.liftweb.common.{Box, Failure, Full, _}
import net.liftweb.http.RequestVar
Expand All @@ -31,7 +32,7 @@ object ObpAPI extends Loggable {
implicit val formats = DefaultFormats
val dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")

val defaultProvider = Props.get("defaultAuthProvider").getOrElse("")
val defaultProvider = Helper.getPropsValue("defaultAuthProvider").getOrElse("")

val userNotFoundError = "user (\\S+) at provider (\\S+) not found".r

Expand Down
7 changes: 4 additions & 3 deletions src/main/scala/code/snippet/ApiExplorer.scala
Expand Up @@ -4,6 +4,7 @@ import java.net.URL

import code.lib.ObpJson._
import code.lib._
import code.util.Helper
import code.util.Helper.MdcLoggable
import net.liftweb.util.Props

Expand Down Expand Up @@ -248,7 +249,7 @@ WIP to add comments on resource docs. This code copied from Sofit.


// If there is a main purpose of the sandbox, then know that.
val defaultCatalog = Props.get("defaultCatalog", "")
val defaultCatalog = Helper.getPropsValue("defaultCatalog", "")


val showCore = showCoreParam
Expand Down Expand Up @@ -391,7 +392,7 @@ WIP to add comments on resource docs. This code copied from Sofit.


// To link to API home page (this is duplicated in OAuthClient)
val baseUrl = Props.get("api_hostname", S.hostName)
val baseUrl = Helper.getPropsValue("api_hostname", S.hostName)


// Use to show the developer the current base version url
Expand Down Expand Up @@ -913,7 +914,7 @@ WIP to add comments on resource docs. This code copied from Sofit.

// So we can highlight (or maybe later exclusively show) the "active" banks in a sandbox.
// Filter out empty string items
val featuredBankIds = Props.get("featuredBankIds", "").split(",").toList.filter(i => i.length > 0)
val featuredBankIds = Helper.getPropsValue("featuredBankIds", "").split(",").toList.filter(i => i.length > 0)



Expand Down
13 changes: 6 additions & 7 deletions src/main/scala/code/snippet/WebUI.scala
Expand Up @@ -32,8 +32,7 @@ import net.liftweb.http.{S, SessionVar}
import net.liftweb.util.Helpers._
import net.liftweb.util.{CssSel, Props, _}

import code.util.Branding._

import code.util.Helper._



Expand Down Expand Up @@ -73,23 +72,23 @@ class WebUI extends MdcLoggable {
/*
def footer2LogoLeft = {
"img [src]" #> Props.get("webui_footer2_logo_left_url", "")
"img [src]" #> Helper.getPropsValue("webui_footer2_logo_left_url", "")
}
def footer2MiddleText: CssSel = {
"#footer2-middle-text *" #> scala.xml.Unparsed(Props.get("webui_footer2_middle_text", ""))
"#footer2-middle-text *" #> scala.xml.Unparsed(Helper.getPropsValue("webui_footer2_middle_text", ""))
}
def aboutBackground: CssSel = {
"#main-about [style]" #> ("background-image: url(" + Props.get("webui_index_page_about_section_background_image_url", "") + ");")
"#main-about [style]" #> ("background-image: url(" + Helper.getPropsValue("webui_index_page_about_section_background_image_url", "") + ");")
}
def aboutText: CssSel = {
"#main-about-text *" #> scala.xml.Unparsed(Props.get("webui_index_page_about_section_text", ""))
"#main-about-text *" #> scala.xml.Unparsed(Helper.getPropsValue("webui_index_page_about_section_text", ""))
}
def topText: CssSel = {
"#top-text *" #> scala.xml.Unparsed(Props.get("webui_top_text", ""))
"#top-text *" #> scala.xml.Unparsed(Helper.getPropsValue("webui_top_text", ""))
}
*/
Expand Down
65 changes: 1 addition & 64 deletions src/main/scala/code/util/Branding.scala
Expand Up @@ -4,9 +4,6 @@ package code.util
import code.util.Helper.MdcLoggable
import net.liftweb.common._
import net.liftweb.http.S
import net.liftweb.util.Helpers.{asLong, toBoolean, toInt}
import net.liftweb.util.Props


// This file contains a few functions related to Props and Branding copied from OBP API

Expand All @@ -25,49 +22,8 @@ object Branding extends MdcLoggable {



/**
* This function is implemented in order to support encrypted values in props file.
* Please note that some value is considered as encrypted if has an encryption mark property in addition to regular props value in props file e.g
* db.url=Helpers.base64Encode(SOME_ENCRYPTED_VALUE)
* db.url.is_encrypted=true
* getDecryptedPropsValue("db.url") = jdbc:postgresql://localhost:5432/han_obp_api_9?user=han_obp_api&password=mypassword
* Encrypt/Decrypt workflow:
* Encrypt: Array[Byte] -> Helpers.base64Encode(encrypted) -> Props file: String -> Helpers.base64Decode(encryptedValue) -> Decrypt: Array[Byte]
* @param nameOfProperty Name of property which value should be decrypted
* @return Decrypted value of a property
*/
def getPropsValue(nameOfProperty: String): Box[String] = {

val brandSpecificPropertyName = getBrandSpecificPropertyName(nameOfProperty)

logger.debug(s"Standard property $nameOfProperty has bankSpecificPropertyName: $brandSpecificPropertyName")

// Note: See OBP API for code to encrypt Props

Props.get(brandSpecificPropertyName)
}


def getPropsValue(nameOfProperty: String, defaultValue: String): String = {
getPropsValue(nameOfProperty) openOr(defaultValue)
}

def getPropsAsBoolValue(nameOfProperty: String, defaultValue: Boolean): Boolean = {
getPropsValue(nameOfProperty) map(toBoolean) openOr(defaultValue)
}
def getPropsAsIntValue(nameOfProperty: String): Box[Int] = {
getPropsValue(nameOfProperty) map(toInt)
}
def getPropsAsIntValue(nameOfProperty: String, defaultValue: Int): Int = {
getPropsAsIntValue(nameOfProperty) openOr(defaultValue)
}
def getPropsAsLongValue(nameOfProperty: String): Box[Long] = {
getPropsValue(nameOfProperty) flatMap(asLong)
}
def getPropsAsLongValue(nameOfProperty: String, defaultValue: Long): Long = {
getPropsAsLongValue(nameOfProperty) openOr(defaultValue)
}

/*
Get any brand specified in url parameter or form field, validate it, and if all good, set the session
Else just return the session
Expand Down Expand Up @@ -99,26 +55,7 @@ object Branding extends MdcLoggable {
}


/*
For bank specific branding and possibly other customisations, if we have an active brand (in url param, form field, session),
we will look for property_FOR_BRAND_<BANK_ID>
We also check that the property exists, else return the standard property name.
*/
def getBrandSpecificPropertyName(nameOfProperty: String) : String = {
// If we have an active brand, construct a target property name to look for.
val brandSpecificPropertyName = activeBrand() match {
case Some(brand) => s"${nameOfProperty}_FOR_BRAND_${brand}"
case _ => nameOfProperty
}

// Check if the property actually exits, if not, return the default / standard property name
val propertyToUse = Props.get(brandSpecificPropertyName) match {
case Full(value) => brandSpecificPropertyName
case _ => nameOfProperty
}

propertyToUse
}




Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/code/util/ExceptionLogger.scala
Expand Up @@ -17,12 +17,12 @@ object MyExceptionLogger extends MdcLoggable{
val currentTime = now.toString
val stackTrace = new String(outputStream.toByteArray)
val error = currentTime + ": " + stackTrace
val host = Props.get("base_url", "unknown host")
val host = Helper.getPropsValue("base_url", "unknown host")

val mailSent = for {
from <- Props.get("mail.exception.sender.address") ?~ "Could not send mail: Missing props param for 'from'"
from <- Helper.getPropsValue("mail.exception.sender.address") ?~ "Could not send mail: Missing props param for 'from'"
// no spaces, comma separated e.g. mail.api.consumer.registered.notification.addresses=notify@example.com,notify2@example.com,notify3@example.com
toAddressesString <- Props.get("mail.exception.registered.notification.addresses") ?~ "Could not send mail: Missing props param for 'to'"
toAddressesString <- Helper.getPropsValue("mail.exception.registered.notification.addresses") ?~ "Could not send mail: Missing props param for 'to'"
} yield {

//technically doesn't work for all valid email addresses so this will mess up if someone tries to send emails to "foo,bar"@example.com
Expand Down
65 changes: 63 additions & 2 deletions src/main/scala/code/util/Helper.scala
Expand Up @@ -2,9 +2,10 @@ package code.util

import code.lib.ObpAPI._
import code.lib.ObpJson.AccountJson
import code.util.Branding.{activeBrand}
import net.liftweb.common._
import net.liftweb.http.S
import net.liftweb.util.Helpers.{asLong, toBoolean, toInt}
import net.liftweb.util.Helpers.{asLong, toBoolean, toInt, tryo}
import net.liftweb.util.Props


Expand Down Expand Up @@ -47,7 +48,7 @@ Returns a string which can be used for the title of the account


def getHostname(): String = {
Props.get("base_url", "") match {
Helper.getPropsValue("base_url", "") match {
case s: String if s.nonEmpty => s.split(":").lift(1) match {
case Some(s) => s.replaceAll("\\/", "").replaceAll("\\.", "-")
case None => "unknown"
Expand All @@ -59,6 +60,66 @@ Returns a string which can be used for the title of the account
trait MdcLoggable extends Loggable {
MDC.put("host" -> getHostname)
}

/**
* This function is implemented in order to support encrypted values in props file.
* Please note that some value is considered as encrypted if has an encryption mark property in addition to regular props value in props file e.g
* db.url=Helpers.base64Encode(SOME_ENCRYPTED_VALUE)
* db.url.is_encrypted=true
* getDecryptedPropsValue("db.url") = jdbc:postgresql://localhost:5432/han_obp_api_9?user=han_obp_api&password=mypassword
* Encrypt/Decrypt workflow:
* Encrypt: Array[Byte] -> Helpers.base64Encode(encrypted) -> Props file: String -> Helpers.base64Decode(encryptedValue) -> Decrypt: Array[Byte]
* @param nameOfProperty Name of property which value should be decrypted
* @return Decrypted value of a property
*/
def getPropsValue(nameOfProperty: String): Box[String] = {

/*
For bank specific branding and possibly other customisations, if we have an active brand (in url param, form field, session),
we will look for property_FOR_BRAND_<BANK_ID>
We also check that the property exists, else return the standard property name.
*/
def getBrandSpecificPropertyName(nameOfProperty: String) : String = {
// If we have an active brand, construct a target property name to look for.
activeBrand() match {
case Some(brand) => s"${nameOfProperty}_FOR_BRAND_${brand}"
case _ => nameOfProperty
}

}

val brandSpecificPropertyName = getBrandSpecificPropertyName(nameOfProperty)

//All the property will first check from system environment, if not find then from the liftweb props file
//Replace "." with "_" (environment vars cannot include ".") and convert to upper case
val sysEnvironmentPropertyName = brandSpecificPropertyName.replace('.', '_').toUpperCase()
val sysEnvironmentPropertyValue: Box[String] = tryo{sys.env(sysEnvironmentPropertyName)}
sysEnvironmentPropertyValue match {
case Full(_) => sysEnvironmentPropertyValue
case _ => Props.get(brandSpecificPropertyName)
}
}


def getPropsValue(nameOfProperty: String, defaultValue: String): String = {
getPropsValue(nameOfProperty) openOr(defaultValue)
}

def getPropsAsBoolValue(nameOfProperty: String, defaultValue: Boolean): Boolean = {
getPropsValue(nameOfProperty) map(toBoolean) openOr(defaultValue)
}
def getPropsAsIntValue(nameOfProperty: String): Box[Int] = {
getPropsValue(nameOfProperty) map(toInt)
}
def getPropsAsIntValue(nameOfProperty: String, defaultValue: Int): Int = {
getPropsAsIntValue(nameOfProperty) openOr(defaultValue)
}
def getPropsAsLongValue(nameOfProperty: String): Box[Long] = {
getPropsValue(nameOfProperty) flatMap(asLong)
}
def getPropsAsLongValue(nameOfProperty: String, defaultValue: Long): Long = {
getPropsAsLongValue(nameOfProperty) openOr(defaultValue)
}


}
3 changes: 2 additions & 1 deletion src/test/scala/RunWebApp.scala
Expand Up @@ -29,6 +29,7 @@ Berlin 13359, Germany
Ayoub Benali: ayoub AT tesobe DOT com
*/

import code.util.Helper
import net.liftweb.util.Props
import org.mortbay.jetty.Server
import org.mortbay.jetty.webapp.WebAppContext
Expand All @@ -37,7 +38,7 @@ import org.mortbay.jetty.nio._
object RunWebApp extends App {
val server = new Server
val scc = new SelectChannelConnector
scc.setPort(Props.getInt("dev.port", 8082))
scc.setPort(Helper.getPropsAsIntValue("dev.port", 8082))
server.setConnectors(Array(scc))

val context = new WebAppContext()
Expand Down

0 comments on commit d61ce82

Please sign in to comment.