create direct login tokens for dummy customers

This commit is contained in:
shuang 2019-09-27 20:59:17 +08:00
parent 4d6497280f
commit fcea29261d
5 changed files with 92 additions and 45 deletions

View File

@ -423,6 +423,9 @@ webui_dummy_customer_logins = Customer Logins\
\
Please ask a member of the Open Bank Project team for more logins if you require. You can use this [application](https://sofit.openbankproject.com) which also uses OAuth to browse your transaction data (use the above username/password).\
# when this value is set to true and webui_dummy_customer_logins value not empty, the register consumer key success page will show dummy customers Direct Login tokens.
webui_show_dummy_customer_tokens=false
# when developer register the consumer successfully, it will show this message to developer on the webpage or email.
webui_register_consumer_success_message_webpage = Thanks for registering your consumer with the Open Bank Project API! Here is your developer information. Please save it in a secure location.
webui_register_consumer_success_message_email = Thank you for registering to use the Open Bank Project API.

View File

@ -266,7 +266,7 @@ trait OBPRestHelper extends RestHelper with MdcLoggable {
fn(cc.copy(user = Full(u), consumer=consumer))
}// Authentication is successful
case _ => {
var (httpCode, message, directLoginParameters) = DirectLogin.validator("protectedResource", DirectLogin.getHttpMethod)
var (httpCode, message, directLoginParameters) = DirectLogin.validator("protectedResource")
Full(errorJsonResponse(message, httpCode))
}
}

View File

@ -94,36 +94,7 @@ object DirectLogin extends RestHelper with MdcLoggable {
//Handling get request for a token
case Req("my" :: "logins" :: "direct" :: Nil,_ , PostRequest) => {
//Extract the directLogin parameters from the header and test if the request is valid
var (httpCode, message, directLoginParameters) = validator("authorizationToken", getHttpMethod)
if (httpCode == 200) {
val userId:Long = (for {id <- getUserId(directLoginParameters)} yield id).getOrElse(0)
if (userId == 0) {
message = ErrorMessages.InvalidLoginCredentials
httpCode = 401
} else if (userId == AuthUser.usernameLockedStateCode) {
message = ErrorMessages.UsernameHasBeenLocked
httpCode = 401
} else {
val jwtPayloadAsJson =
"""{
"":""
}"""
val jwtClaims: JWTClaimsSet = JWTClaimsSet.parse(jwtPayloadAsJson)
val (token:String, secret:String) = generateTokenAndSecret(jwtClaims)
//Save the token that we have generated
if (saveAuthorizationToken(directLoginParameters, token, secret, userId)) {
message = token
} else {
httpCode = 500
message = "invalid"
}
}
}
val (httpCode: Int, message: String) = createToken(getAllParameters)
if (httpCode == 200)
successJsonResponse(Extraction.decompose(JSONFactory.createTokenJSON(message)), 201)
@ -132,6 +103,45 @@ object DirectLogin extends RestHelper with MdcLoggable {
}
}
/**
* according username, password, consumer_key to generate a DirectLogin token
* @param allParameters map {"username": "some_username", "password": "some_password", "consumer_key": "some_consumer_key"}
* @return httpCode and token value
*/
def createToken(allParameters: Map[String, String]) = {
//Extract the directLogin parameters from the header and test if the request is valid
var (httpCode, message, directLoginParameters) = validator("authorizationToken", allParameters)
if (httpCode == 200) {
val userId: Long = (for {id <- getUserId(directLoginParameters)} yield id).getOrElse(0)
if (userId == 0) {
message = ErrorMessages.InvalidLoginCredentials
httpCode = 401
} else if (userId == AuthUser.usernameLockedStateCode) {
message = ErrorMessages.UsernameHasBeenLocked
httpCode = 401
} else {
val jwtPayloadAsJson =
"""{
"":""
}"""
val jwtClaims: JWTClaimsSet = JWTClaimsSet.parse(jwtPayloadAsJson)
val (token: String, secret: String) = generateTokenAndSecret(jwtClaims)
//Save the token that we have generated
if (saveAuthorizationToken(directLoginParameters, token, secret, userId)) {
message = token
} else {
httpCode = 500
message = "invalid"
}
}
}
(httpCode, message)
}
def getHttpMethod = S.request match {
case Full(s) => s.post_? match {
case true => "POST"
@ -217,7 +227,7 @@ object DirectLogin extends RestHelper with MdcLoggable {
//Check if the request (access token or request token) is valid and return a tuple
def validator(requestType : String, httpMethod : String) : (Int, String, Map[String,String]) = {
def validator(requestType : String, allParameters: Map[String, String] = getAllParameters) : (Int, String, Map[String,String]) = {
def validAccessToken(tokenKey: String) = {
Tokens.tokens.vend.getTokenByKeyAndType(tokenKey, TokenType.Access) match {
@ -229,12 +239,10 @@ object DirectLogin extends RestHelper with MdcLoggable {
var message = ""
var httpCode: Int = 500
val parameters = getAllParameters
//are all the necessary directLogin parameters present?
val missingParams = missingDirectLoginParameters(parameters, requestType)
val missingParams = missingDirectLoginParameters(allParameters, requestType)
//guard maximum length and content of strings (a-z, 0-9 etc.) for parameters
val validParams = validDirectLoginParameters(parameters)
val validParams = validDirectLoginParameters(allParameters)
if (missingParams.nonEmpty) {
message = ErrorMessages.DirectLoginMissingParameters + missingParams.mkString(", ")
@ -246,18 +254,18 @@ object DirectLogin extends RestHelper with MdcLoggable {
}
else if (
requestType == "protectedResource" &&
! validAccessToken(parameters.getOrElse("token", ""))
! validAccessToken(allParameters.getOrElse("token", ""))
) {
message = ErrorMessages.DirectLoginInvalidToken + parameters.getOrElse("token", "")
message = ErrorMessages.DirectLoginInvalidToken + allParameters.getOrElse("token", "")
httpCode = 401
}
//check if the application is registered and active
else if (
requestType == "authorizationToken" &&
APIUtil.getPropsAsBoolValue("direct_login_consumer_key_mandatory", true) &&
! APIUtil.registeredApplication(parameters.getOrElse("consumer_key", ""))) {
! APIUtil.registeredApplication(allParameters.getOrElse("consumer_key", ""))) {
logger.error("application: " + parameters.getOrElse("consumer_key", "") + " not found")
logger.error("application: " + allParameters.getOrElse("consumer_key", "") + " not found")
message = ErrorMessages.InvalidConsumerKey
httpCode = 401
}
@ -265,7 +273,7 @@ object DirectLogin extends RestHelper with MdcLoggable {
httpCode = 200
if(message.nonEmpty)
logger.error("error message : " + message)
(httpCode, message, parameters)
(httpCode, message, allParameters)
}
@ -377,7 +385,7 @@ object DirectLogin extends RestHelper with MdcLoggable {
case Full(r) => r.request.method
case _ => "GET"
}
val (httpCode, message, directLoginParameters) = validator("protectedResource", httpMethod)
val (httpCode, message, directLoginParameters) = validator("protectedResource")
if (httpCode == 400 || httpCode == 401)
ParamFailure(message, Empty, Empty, APIFailure(message, httpCode))
@ -450,7 +458,7 @@ object DirectLogin extends RestHelper with MdcLoggable {
case _ => "GET"
}
val (httpCode, message, directLoginParameters) = validator("protectedResource", httpMethod)
val (httpCode, message, directLoginParameters) = validator("protectedResource")
val consumer: Option[Consumer] = for {
tokenId: String <- directLoginParameters.get("token")

View File

@ -26,6 +26,7 @@ TESOBE (http://www.tesobe.com/)
*/
package code.snippet
import code.api.DirectLogin
import code.api.util.{APIUtil, ErrorMessages}
import code.consumer.Consumers
import code.model._
@ -37,6 +38,8 @@ import net.liftweb.util.Helpers._
import net.liftweb.util.{FieldError, Helpers}
import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue
import scala.collection.mutable.ListBuffer
class ConsumerRegistration extends MdcLoggable {
private object nameVar extends RequestVar("")
@ -89,6 +92,29 @@ class ConsumerRegistration extends MdcLoggable {
val urlOAuthEndpoint = APIUtil.getPropsValue("hostname", "") + "/oauth/initiate"
val urlDirectLoginEndpoint = APIUtil.getPropsValue("hostname", "") + "/my/logins/direct"
val createDirectLoginToken = getWebUiPropsValue("webui_create_directlogin_token_url", "")
val dummyCustomersInfo = getWebUiPropsValue("webui_dummy_customer_logins", "")
val isShowDummyCustomerTokens = getWebUiPropsValue("webui_show_dummy_customer_tokens", "false").toBoolean
val dummyUsersTokens: String = (isShowDummyCustomerTokens, dummyCustomersInfo) match {
case(true, v) if v.nonEmpty => {
val regex = """\{"user_name"\s*:\s*"(.+?)".+?"password"\s*:\s*"(.+?)".+?\}""".r
val matcher = regex.pattern.matcher(v)
val tokens = ListBuffer[String]()
while(matcher.find()) {
val userName = matcher.group(1)
val password = matcher.group(2)
val consumerKey = consumer.key.get
val (code, token) = DirectLogin.createToken(Map(("username", userName), ("password", password), ("consumer_key", consumerKey)))
val authHeader = code match {
case 200 => s"""$userName auth header --> Authorization: DirectLogin token="$token""""
case _ => s"""$userName - -> username or password is invalid, generate token fail"""
}
tokens += authHeader
}
tokens.mkString(""" | """)
}
case _ => ""
}
val registerConsumerSuccessMessageWebpage = getWebUiPropsValue(
"webui_register_consumer_success_message_webpage",
"Thanks for registering your consumer with the Open Bank Project API! Here is your developer information. Please save it in a secure location.")
@ -111,7 +137,13 @@ class ConsumerRegistration extends MdcLoggable {
"#directlogin-endpoint a [href]" #> urlDirectLoginEndpoint &
"#post-consumer-registration-more-info-link a *" #> registrationMoreInfoText &
"#post-consumer-registration-more-info-link a [href]" #> registrationMoreInfoUrl &
"#register-consumer-input" #> ""
"#register-consumer-input" #> "" & {
if(dummyUsersTokens.isEmpty) {
".preparedTokens" #> dummyUsersTokens
} else {
"#preparedTokens *" #> dummyUsersTokens
}
}
}
def showRegistrationResults(result : Consumer) = {

View File

@ -134,10 +134,14 @@ Berlin 13359, Germany
<div class="col-xs-12 col-sm-4">Direct Login Endpoint</div>
<div class="col-xs-12 col-sm-8"><span id="directlogin-endpoint"><a href="#">endpoint</a></span></div>
</div>
<div class="row preparedTokens">
<div class="col-xs-12 col-sm-4">Prepared user tokens</div>
<div class="col-xs-12 col-sm-8" id="preparedTokens"></div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-4">Direct Login Documentation</div>
<div class="col-xs-12 col-sm-8"><a href="https://github.com/OpenBankProject/OBP-API/wiki/Direct-Login">How to use Direct Login</a>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-4"></div>