Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor/add the log to consent issue #2414

Merged
merged 6 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading