Skip to content

Commit

Permalink
Merge pull request #2414 from hongwei1/develop
Browse files Browse the repository at this point in the history
refactor/add the log to consent issue
  • Loading branch information
simonredfern committed Jul 16, 2024
2 parents 9d219b3 + 0f71ffc commit 166c325
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
51 changes: 37 additions & 14 deletions obp-api/src/main/scala/code/api/util/ConsentUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,16 @@ object Consent extends MdcLoggable {
}

private def verifyHmacSignedJwt(jwtToken: String, c: MappedConsent): Boolean = {
JwtUtil.verifyHmacSignedJwt(jwtToken, c.secret)
logger.debug(s"code.api.util.Consent.verifyHmacSignedJwt beginning:: jwtToken($jwtToken), MappedConsent($c)")
val result = JwtUtil.verifyHmacSignedJwt(jwtToken, c.secret)
logger.debug(s"code.api.util.Consent.verifyHmacSignedJwt result:: result($result)")
result
}

private def checkConsumerIsActiveAndMatched(consent: ConsentJWT, callContext: CallContext): Box[Boolean] = {
Consumers.consumers.vend.getConsumerByConsumerId(consent.aud) match {
val consumerBox = Consumers.consumers.vend.getConsumerByConsumerId(consent.aud)
logger.debug(s"code.api.util.Consent.checkConsumerIsActiveAndMatched.getConsumerByConsumerId consumerBox:: consumerBox($consumerBox)")
consumerBox match {
case Full(consumerFromConsent) if consumerFromConsent.isActive.get == true => // Consumer is active
val validationMetod = APIUtil.getPropsValue(nameOfProperty = "consumer_validation_method_for_consent", defaultValue = "CONSUMER_CERTIFICATE")
if(validationMetod != "CONSUMER_CERTIFICATE" && Props.mode == Props.RunModes.Production) {
Expand All @@ -150,6 +155,7 @@ object Consent extends MdcLoggable {
validationMetod match {
case "CONSUMER_KEY_VALUE" =>
val requestHeaderConsumerKey = getConsumerKey(callContext.requestHeaders)
logger.debug(s"code.api.util.Consent.checkConsumerIsActiveAndMatched.consumerBox.requestHeaderConsumerKey:: requestHeaderConsumerKey($requestHeaderConsumerKey)")
requestHeaderConsumerKey match {
case Some(reqHeaderConsumerKey) =>
if (reqHeaderConsumerKey == consumerFromConsent.key.get)
Expand All @@ -160,12 +166,17 @@ object Consent extends MdcLoggable {
}
case "CONSUMER_CERTIFICATE" =>
val clientCert: String = APIUtil.`getPSD2-CERT`(callContext.requestHeaders).getOrElse(SecureRandomUtil.csprng.nextLong().toString)
logger.debug(s"code.api.util.Consent.checkConsumerIsActiveAndMatched.consumerBox clientCert:: clientCert($clientCert)")
def removeBreakLines(input: String) = input
.replace("\n", "")
.replace("\r", "")
if (removeBreakLines(clientCert) == removeBreakLines(consumerFromConsent.clientCertificate.get))
val certificate = consumerFromConsent.clientCertificate
logger.debug(s"code.api.util.Consent.checkConsumerIsActiveAndMatched.consumer.certificate:: certificate($certificate)")
logger.debug(s"code.api.util.Consent.checkConsumerIsActiveAndMatched.consumer.certificate.dbNotNull_?(${certificate.dbNotNull_?})")
if (certificate.dbNotNull_? && removeBreakLines(clientCert) == removeBreakLines(certificate.get)) {
logger.debug(s"certificate.dbNotNull_? && removeBreakLines(clientCert) == removeBreakLines(consumerFromConsent.clientCertificate.get) result == true")
Full(true) // This consent can be used by current application
else // This consent can NOT be used by current application
} else // This consent can NOT be used by current application
Failure(ErrorMessages.ConsentDoesNotMatchConsumer)
case "NONE" => // This instance does not require validation method
Full(true)
Expand All @@ -180,7 +191,10 @@ object Consent extends MdcLoggable {
}

private def checkConsent(consent: ConsentJWT, consentIdAsJwt: String, callContext: CallContext): Box[Boolean] = {
Consents.consentProvider.vend.getConsentByConsentId(consent.jti) match {
logger.debug(s"code.api.util.Consent.checkConsent beginning: consent($consent), consentIdAsJwt($consentIdAsJwt)")
val consentBox = Consents.consentProvider.vend.getConsentByConsentId(consent.jti)
logger.debug(s"code.api.util.Consent.checkConsent.getConsentByConsentId: consentBox($consentBox)")
val result = consentBox match {
case Full(c) if c.mStatus == ConsentStatus.ACCEPTED.toString | c.mStatus == ConsentStatus.VALID.toString =>
verifyHmacSignedJwt(consentIdAsJwt, c) match {
case true =>
Expand All @@ -190,7 +204,10 @@ object Consent extends MdcLoggable {
case currentTimeInSeconds if currentTimeInSeconds > consent.exp =>
Failure(ErrorMessages.ConsentExpiredIssue)
case _ =>
checkConsumerIsActiveAndMatched(consent, callContext)
logger.debug(s"start code.api.util.Consent.checkConsent.checkConsumerIsActiveAndMatched(consent($consent))")
val result = checkConsumerIsActiveAndMatched(consent, callContext)
logger.debug(s"end code.api.util.Consent.checkConsent.checkConsumerIsActiveAndMatched: result($result)")
result
}
case false =>
Failure(ErrorMessages.ConsentVerificationIssue)
Expand All @@ -200,9 +217,12 @@ object Consent extends MdcLoggable {
case _ =>
Failure(ErrorMessages.ConsentNotFound)
}
logger.debug(s"code.api.util.Consent.checkConsent.consentBox.result: result($result)")
result
}

private def getOrCreateUser(subject: String, issuer: String, consentId: Option[String], name: Option[String], email: Option[String]): Future[(Box[User], Boolean)] = {
logger.debug(s"getOrCreateUser(subject($subject), issuer($issuer), consentId($consentId), name($name), email($email))")
Users.users.vend.getOrCreateUserByProviderIdFuture(
provider = issuer,
idGivenByProvider = subject,
Expand Down Expand Up @@ -316,9 +336,9 @@ object Consent extends MdcLoggable {
JwtUtil.getSignedPayloadAsJson(consentIdAsJwt) match {
case Full(jsonAsString) =>
try {
logger.debug(s"Start of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $jsonAsString")
logger.debug(s"applyConsentRulesCommonOldStyle.getSignedPayloadAsJson.Start of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $jsonAsString")
val consent = net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]
logger.debug(s"End of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $consent")
logger.debug(s"applyConsentRulesCommonOldStyle.getSignedPayloadAsJson.End of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $consent")
checkConsent(consent, consentIdAsJwt, calContext) match { // Check is it Consent-JWT expired
case (Full(true)) => // OK
applyConsentRules(consent)
Expand Down Expand Up @@ -373,9 +393,9 @@ object Consent extends MdcLoggable {
JwtUtil.getSignedPayloadAsJson(consentAsJwt) match {
case Full(jsonAsString) =>
try {
logger.debug(s"Start of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $jsonAsString")
logger.debug(s"applyConsentRulesCommon.Start of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $jsonAsString")
val consent = net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]
logger.debug(s"End of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $consent")
logger.debug(s"applyConsentRulesCommon.End of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $consent")
// Set Consumer into Call Context
val consumer = getCurrentConsumerViaMtls(callContext)
val updatedCallContext = callContext.copy(consumer = consumer)
Expand Down Expand Up @@ -494,13 +514,16 @@ object Consent extends MdcLoggable {
JwtUtil.getSignedPayloadAsJson(storedConsent.jsonWebToken) match {
case Full(jsonAsString) =>
try {
logger.debug(s"Start of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $jsonAsString")
logger.debug(s"applyBerlinGroupConsentRulesCommon.Start of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $jsonAsString")
val consent = net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]
logger.debug(s"End of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $consent")
checkConsent(consent, storedConsent.jsonWebToken, updatedCallContext) match { // Check is it Consent-JWT expired
logger.debug(s"applyBerlinGroupConsentRulesCommon.End of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT]: $consent")
val consentBox = checkConsent(consent, storedConsent.jsonWebToken, updatedCallContext)
logger.debug(s"End of net.liftweb.json.parse(jsonAsString).extract[ConsentJWT].checkConsent.consentBox: $consent")
consentBox match { // Check is it Consent-JWT expired
case (Full(true)) => // OK
// Update MappedConsent.usesSoFarTodayCounter field
Consents.consentProvider.vend.updateBerlinGroupConsent(consentId, currentCounterState + 1)
val consentUpdatedBox = Consents.consentProvider.vend.updateBerlinGroupConsent(consentId, currentCounterState + 1)
logger.debug(s"applyBerlinGroupConsentRulesCommon.consentUpdatedBox: $consentUpdatedBox")
applyConsentRules(consent)
case failure@Failure(_, _, _) => // Handled errors
Future(failure, Some(updatedCallContext))
Expand Down
9 changes: 7 additions & 2 deletions obp-api/src/main/scala/code/api/util/JwtUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package code.api.util
import java.net.{URI, URL}
import java.nio.file.{Files, Paths}
import java.text.ParseException

import code.api.util.RSAUtil.logger
import code.util.Helper.MdcLoggable
import com.nimbusds.jose.JWSAlgorithm
Expand All @@ -15,6 +14,7 @@ import com.nimbusds.jose.util.{DefaultResourceRetriever, JSONObjectUtils}
import com.nimbusds.jwt.proc.{BadJWTException, DefaultJWTProcessor}
import com.nimbusds.jwt.{JWTClaimsSet, SignedJWT}
import com.nimbusds.openid.connect.sdk.claims.IDTokenClaimsSet
import dispatch.Future
import net.liftweb.common.{Box, Empty, Failure, Full}

object JwtUtil extends MdcLoggable {
Expand Down Expand Up @@ -58,9 +58,14 @@ object JwtUtil extends MdcLoggable {
* @return True or False
*/
def verifyHmacSignedJwt(jwtToken: String, sharedSecret: String): Boolean = {
logger.debug(s"code.api.util.JwtUtil.verifyHmacSignedJwt beginning:: jwtToken($jwtToken), sharedSecret($sharedSecret)")
val signedJWT = SignedJWT.parse(jwtToken)
val verifier = new MACVerifier(sharedSecret)
signedJWT.verify(verifier)
logger.debug(s"code.api.util.JwtUtil.verifyHmacSignedJwt beginning:: signedJWT($signedJWT)")
logger.debug(s"code.api.util.JwtUtil.verifyHmacSignedJwt beginning:: verifier($verifier)")
val result = signedJWT.verify(verifier)
logger.debug(s"code.api.util.JwtUtil.verifyHmacSignedJwt result:: result($verifier)")
result
}

/**
Expand Down
7 changes: 5 additions & 2 deletions obp-api/src/main/scala/code/users/LiftUsers.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package code.users

import java.util.Date
import code.api.util.Consent.logger

import java.util.Date
import code.api.util._
import code.entitlement.Entitlement
import code.loginattempts.LoginAttempt.maxBadLoginAttempts
Expand Down Expand Up @@ -70,7 +71,9 @@ object LiftUsers extends Users with MdcLoggable{
}
def getOrCreateUserByProviderIdFuture(provider : String, idGivenByProvider : String, consentId: Option[String], name: Option[String], email: Option[String]) : Future[(Box[User], Boolean)] = {
Future {
getOrCreateUserByProviderId(provider, idGivenByProvider,consentId, name, email)
val result = getOrCreateUserByProviderId(provider, idGivenByProvider, consentId, name, email)
logger.debug(s"getOrCreateUserByProviderId.result ($result)")
result
}
}

Expand Down

0 comments on commit 166c325

Please sign in to comment.