mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:17:09 +00:00
Merge pull request #670 from constantine2nd/develop
Gateway integration
This commit is contained in:
commit
48c9910f3d
@ -28,14 +28,16 @@ package code.api
|
||||
|
||||
import authentikat.jwt.{JsonWebToken, JwtClaimsSet, JwtHeader}
|
||||
import code.api.util.ErrorMessages
|
||||
import code.model.User
|
||||
import code.consumer.Consumers
|
||||
import code.model.{Consumer, User}
|
||||
import code.users.Users
|
||||
import code.util.Helper.MdcLoggable
|
||||
import net.liftweb.common._
|
||||
import net.liftweb.http._
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
import net.liftweb.json._
|
||||
import net.liftweb.util.Helpers._
|
||||
import net.liftweb.util.Props
|
||||
import net.liftweb.util.{Helpers, Props}
|
||||
|
||||
/**
|
||||
* This object provides the API calls necessary to
|
||||
@ -43,11 +45,38 @@ import net.liftweb.util.Props
|
||||
*/
|
||||
|
||||
|
||||
object JSONFactoryGateway {
|
||||
case class TokenJSON(
|
||||
username: String,
|
||||
is_first: Option[Boolean],
|
||||
CBS_auth_token: Option[String],
|
||||
timestamp: String,
|
||||
consumer_id: String,
|
||||
consumer_name: String
|
||||
)
|
||||
}
|
||||
|
||||
object GatewayLogin extends RestHelper with MdcLoggable {
|
||||
|
||||
val gateway = "Gateway" // This value is used for ResourceUser.provider and Consumer.description
|
||||
|
||||
def createJwt(payloadAsJsonString: String) : String = {
|
||||
val jwtJson = parse(payloadAsJsonString) // Transform Json string to JsonAST
|
||||
val username = compact(render(jwtJson.\\("username"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
val consumerId = compact(render(jwtJson.\\("consumer_id"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
val consumerName = compact(render(jwtJson.\\("consumer_name"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
val isFirst = compact(render(jwtJson.\\("is_first"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
val timestamp = compact(render(jwtJson.\\("timestamp"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
val json = JSONFactoryGateway.TokenJSON(
|
||||
username = username,
|
||||
is_first = None,
|
||||
CBS_auth_token = None,
|
||||
timestamp = timestamp,
|
||||
consumer_id = consumerId,
|
||||
consumer_name = consumerName
|
||||
)
|
||||
val header = JwtHeader("HS256")
|
||||
val claimsSet = JwtClaimsSet(payloadAsJsonString)
|
||||
val claimsSet = JwtClaimsSet(compact(render(Extraction.decompose(json))))
|
||||
val secretKey = Props.get("gateway.token_secret", "Cannot get the secret")
|
||||
val jwt: String = JsonWebToken(header, claimsSet, secretKey)
|
||||
jwt
|
||||
@ -106,11 +135,39 @@ object GatewayLogin extends RestHelper with MdcLoggable {
|
||||
}
|
||||
}
|
||||
|
||||
def getUser(jwt: String) : Box[User] = {
|
||||
def getOrCreateResourceUser(jwt: String) : Box[User] = {
|
||||
val jwtJson = parse(jwt) // Transform Json string to JsonAST
|
||||
val username = compact(render(jwtJson.\\("username"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
logger.debug("username: " + username)
|
||||
Empty
|
||||
Users.users.vend.getUserByProviderId(provider = "Gateway", idGivenByProvider = username).or {
|
||||
Users.users.vend.createResourceUser(
|
||||
provider = gateway,
|
||||
providerId = Some(username),
|
||||
name = Some(username),
|
||||
email = None,
|
||||
userId = None
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def getOrCreateConsumer(jwt: String, u: User) : Box[Consumer] = {
|
||||
val jwtJson = parse(jwt) // Transform Json string to JsonAST
|
||||
val consumerId = compact(render(jwtJson.\\("consumer_id"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
logger.debug("consumer_id: " + consumerId)
|
||||
val consumerName = compact(render(jwtJson.\\("consumer_name"))).replace("\"", "") // Extract value from field username and remove quotation
|
||||
logger.debug("consumerName: " + consumerName)
|
||||
Consumers.consumers.vend.getOrCreateConsumer(
|
||||
consumerId=Some(consumerId),
|
||||
Some(Helpers.randomString(40).toLowerCase),
|
||||
Some(Helpers.randomString(40).toLowerCase),
|
||||
Some(true),
|
||||
name = Some(consumerName),
|
||||
appType = None,
|
||||
description = Some(gateway),
|
||||
developerEmail = None,
|
||||
redirectURL = None,
|
||||
createdByUserId = Some(u.userId)
|
||||
)
|
||||
}
|
||||
|
||||
// Return a Map containing the GatewayLogin parameter : token -> value
|
||||
|
||||
@ -133,14 +133,14 @@ trait OBPRestHelper extends RestHelper with MdcLoggable {
|
||||
def failIfBadAuthorizationHeader(fn: (Box[User]) => Box[JsonResponse]) : JsonResponse = {
|
||||
if (hasAnOAuthHeader) {
|
||||
getUser match {
|
||||
case Full(u) => fn(Full(u))
|
||||
case Full(u) => fn(Full(u)) // Authentication is successful
|
||||
case ParamFailure(_, _, _, apiFailure : APIFailure) => errorJsonResponse(apiFailure.msg, apiFailure.responseCode)
|
||||
case Failure(msg, _, _) => errorJsonResponse(msg)
|
||||
case _ => errorJsonResponse("oauth error")
|
||||
}
|
||||
} else if (Props.getBool("allow_direct_login", true) && hasDirectLoginHeader) {
|
||||
DirectLogin.getUser match {
|
||||
case Full(u) => fn(Full(u))
|
||||
case Full(u) => fn(Full(u)) // Authentication is successful
|
||||
case _ => {
|
||||
var (httpCode, message, directLoginParameters) = DirectLogin.validator("protectedResource", DirectLogin.getHttpMethod)
|
||||
errorJsonResponse(message, httpCode)
|
||||
@ -152,11 +152,15 @@ trait OBPRestHelper extends RestHelper with MdcLoggable {
|
||||
val (httpCode, message, parameters) = GatewayLogin.validator(S.request)
|
||||
httpCode match {
|
||||
case 200 =>
|
||||
val jwt = GatewayLogin.parseJwt(parameters)
|
||||
GatewayLogin.getUser(jwt: String) match {
|
||||
case Full(u) => fn(Full(u))
|
||||
val payload = GatewayLogin.parseJwt(parameters)
|
||||
GatewayLogin.getOrCreateResourceUser(payload: String) match {
|
||||
case Full(u) => // Authentication is successful
|
||||
GatewayLogin.getOrCreateConsumer(payload, u)
|
||||
val jwtResponse = GatewayLogin.createJwt(payload)
|
||||
setGatewayResponseHeader(jwtResponse)
|
||||
fn(Full(u))
|
||||
case Failure(msg, _, _) => errorJsonResponse(msg)
|
||||
case _ => errorJsonResponse(jwt, httpCode)
|
||||
case _ => errorJsonResponse(payload, httpCode)
|
||||
}
|
||||
case _ => errorJsonResponse(message, httpCode)
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ trait ConsumersProvider {
|
||||
def getConsumerByPrimaryId(id: Long): Box[Consumer]
|
||||
def getConsumerByConsumerKey(consumerKey: String): Box[Consumer]
|
||||
def createConsumer(key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer]
|
||||
def updateConsumer(consumerId: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer]
|
||||
def updateConsumer(id: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer]
|
||||
def getOrCreateConsumer(consumerId: Option[String], key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer]
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ class RemotedataConsumersCaseClasses {
|
||||
case class getConsumerByPrimaryId(id: Long)
|
||||
case class getConsumerByConsumerKey(consumerKey: String)
|
||||
case class createConsumer(key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String])
|
||||
case class updateConsumer(consumerId: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String])
|
||||
case class updateConsumer(id: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String])
|
||||
case class getOrCreateConsumer(consumerId: Option[String], key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String])
|
||||
}
|
||||
|
||||
|
||||
@ -116,7 +116,7 @@ object MappedConsumersProvider extends ConsumersProvider {
|
||||
}
|
||||
}
|
||||
|
||||
override def updateConsumer(consumerId: Long,
|
||||
override def updateConsumer(id: Long,
|
||||
key: Option[String],
|
||||
secret: Option[String],
|
||||
isActive: Option[Boolean],
|
||||
@ -126,7 +126,7 @@ object MappedConsumersProvider extends ConsumersProvider {
|
||||
developerEmail: Option[String],
|
||||
redirectURL: Option[String],
|
||||
createdByUserId: Option[String]): Box[Consumer] = {
|
||||
val consumer = Consumer.find(By(Consumer.id, consumerId))
|
||||
val consumer = Consumer.find(By(Consumer.id, id))
|
||||
consumer match {
|
||||
case Full(c) => tryo {
|
||||
key match {
|
||||
@ -181,20 +181,54 @@ object MappedConsumersProvider extends ConsumersProvider {
|
||||
developerEmail: Option[String],
|
||||
redirectURL: Option[String],
|
||||
createdByUserId: Option[String]): Box[Consumer] = {
|
||||
consumerId match {
|
||||
case Some(id) =>
|
||||
Consumer.find(By(Consumer.consumerId, id))
|
||||
case None =>
|
||||
createConsumer(key = key,
|
||||
secret = secret,
|
||||
isActive = isActive,
|
||||
name = name,
|
||||
appType = appType,
|
||||
description = description,
|
||||
developerEmail = developerEmail,
|
||||
redirectURL = redirectURL,
|
||||
createdByUserId = createdByUserId
|
||||
)
|
||||
|
||||
Consumer.find(By(Consumer.consumerId, consumerId.getOrElse(Helpers.randomString(40)))) match {
|
||||
case Full(c) => Full(c)
|
||||
case Empty =>
|
||||
tryo {
|
||||
val c = Consumer.create
|
||||
key match {
|
||||
case Some(v) => c.key(v)
|
||||
case None =>
|
||||
}
|
||||
secret match {
|
||||
case Some(v) => c.secret(v)
|
||||
case None =>
|
||||
}
|
||||
isActive match {
|
||||
case Some(v) => c.isActive(v)
|
||||
case None =>
|
||||
}
|
||||
name match {
|
||||
case Some(v) => c.name(v)
|
||||
case None =>
|
||||
}
|
||||
appType match {
|
||||
case Some(v) => c.appType(v)
|
||||
case None =>
|
||||
}
|
||||
description match {
|
||||
case Some(v) => c.description(v)
|
||||
case None =>
|
||||
}
|
||||
developerEmail match {
|
||||
case Some(v) => c.developerEmail(v)
|
||||
case None =>
|
||||
}
|
||||
redirectURL match {
|
||||
case Some(v) => c.redirectURL(v)
|
||||
case None =>
|
||||
}
|
||||
createdByUserId match {
|
||||
case Some(v) => c.createdByUserId(v)
|
||||
case None =>
|
||||
}
|
||||
consumerId match {
|
||||
case Some(v) => c.consumerId(v)
|
||||
case None =>
|
||||
}
|
||||
c.saveMe()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -47,8 +47,8 @@ object RemotedataConsumers extends ObpActorInit with ConsumersProvider {
|
||||
def createConsumer(key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer] =
|
||||
extractFutureToBox(actor ? cc.createConsumer(key, secret, isActive, name, appType, description, developerEmail, redirectURL, createdByUserId))
|
||||
|
||||
def updateConsumer(consumerId: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer] =
|
||||
extractFutureToBox(actor ? cc.updateConsumer(consumerId, key, secret, isActive, name, appType, description, developerEmail, redirectURL, createdByUserId))
|
||||
def updateConsumer(id: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer] =
|
||||
extractFutureToBox(actor ? cc.updateConsumer(id, key, secret, isActive, name, appType, description, developerEmail, redirectURL, createdByUserId))
|
||||
|
||||
def getOrCreateConsumer(consumerId: Option[String], key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]): Box[Consumer] =
|
||||
extractFutureToBox(actor ? cc.getOrCreateConsumer(consumerId, key, secret, isActive, name, appType, description, developerEmail, redirectURL, createdByUserId))
|
||||
|
||||
@ -25,9 +25,9 @@ class RemotedataConsumersActor extends Actor with ObpActorHelper with MdcLoggabl
|
||||
logger.debug("createConsumer(" + "*****" + ", " + "*****" + ", " + isActive.getOrElse("None") + ", " + name.getOrElse("None") + ", " + appType.getOrElse("None") + ", " + description.getOrElse("None") + ", " + developerEmail.getOrElse("None") + ", " + redirectURL.getOrElse("None") + ", " + createdByUserId.getOrElse("None") + ")")
|
||||
sender ! extractResult(mapper.createConsumer(key, secret, isActive, name, appType, description, developerEmail, redirectURL, createdByUserId))
|
||||
|
||||
case cc.updateConsumer(consumerId: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]) =>
|
||||
logger.debug("createConsumer(" + consumerId + ", " + "*****" + ", " + "*****" + ", " + isActive.getOrElse("None") + ", " + name.getOrElse("None") + ", " + appType.getOrElse("None") + ", " + description.getOrElse("None") + ", " + developerEmail.getOrElse("None") + ", " + redirectURL.getOrElse("None") + ", " + createdByUserId.getOrElse("None") + ")")
|
||||
sender ! extractResult(mapper.updateConsumer(consumerId, key, secret, isActive, name, appType, description, developerEmail, redirectURL, createdByUserId))
|
||||
case cc.updateConsumer(id: Long, key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]) =>
|
||||
logger.debug("createConsumer(" + id + ", " + "*****" + ", " + "*****" + ", " + isActive.getOrElse("None") + ", " + name.getOrElse("None") + ", " + appType.getOrElse("None") + ", " + description.getOrElse("None") + ", " + developerEmail.getOrElse("None") + ", " + redirectURL.getOrElse("None") + ", " + createdByUserId.getOrElse("None") + ")")
|
||||
sender ! extractResult(mapper.updateConsumer(id, key, secret, isActive, name, appType, description, developerEmail, redirectURL, createdByUserId))
|
||||
|
||||
case cc.getOrCreateConsumer(consumerId: Option[String], key: Option[String], secret: Option[String], isActive: Option[Boolean], name: Option[String], appType: Option[AppType.AppType], description: Option[String], developerEmail: Option[String], redirectURL: Option[String], createdByUserId: Option[String]) =>
|
||||
logger.debug("getOrCreateConsumer(" + consumerId.getOrElse("None") + ", " + "*****" + ", " + "*****" + ", " + isActive.getOrElse("None") + ", " + name.getOrElse("None") + ", " + appType.getOrElse("None") + ", " + description.getOrElse("None") + ", " + developerEmail.getOrElse("None") + ", " + redirectURL.getOrElse("None") + ", " + createdByUserId.getOrElse("None") + ")")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user