@@ -254,16 +254,6 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
254254 case _ => None
255255 }
256256 }
257- /**
258- * Purpose of this helper function is to get the PSD2-CERT value from a Request Headers.
259- * @return the PSD2-CERT value from a Request Header as a String
260- */
261- def getTppSignatureCertificate (requestHeaders : List [HTTPParam ]): Option [String ] = {
262- requestHeaders.toSet.filter(_.name == RequestHeader .`TPP-Signature-Certificate`).toList match {
263- case x :: Nil => Some (x.values.mkString(" , " ))
264- case _ => None
265- }
266- }
267257
268258 def getRequestHeader (name : String , requestHeaders : List [HTTPParam ]): String = {
269259 requestHeaders.toSet.filter(_.name.toLowerCase == name.toLowerCase).toList match {
@@ -527,22 +517,31 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
527517 *
528518 */
529519 def getRequestHeadersToMirror (callContext : Option [CallContextLight ]): CustomResponseHeaders = {
520+ val mirrorByProperties = getPropsValue(" mirror_request_headers_to_response" , " " ).split(" ," ).toList.map(_.trim)
521+
530522 val mirrorRequestHeadersToResponse : List [String ] =
531- getPropsValue(" mirror_request_headers_to_response" , " " ).split(" ," ).toList.map(_.trim)
523+ if (callContext.exists(_.url.contains(ApiVersion .berlinGroupV13.urlPrefix))) {
524+ // Berlin Group Specification
525+ RequestHeader .`X-Request-ID` :: mirrorByProperties
526+ } else {
527+ mirrorByProperties
528+ }
529+
532530 callContext match {
533531 case Some (cc) =>
534532 cc.requestHeaders match {
535533 case Nil => CustomResponseHeaders (Nil )
536534 case _ =>
537535 val headers = cc.requestHeaders
538536 .filter(item => mirrorRequestHeadersToResponse.contains(item.name))
539- .map(item => (item.name, item.values.head))
537+ .map(item => (item.name, item.values.headOption.getOrElse( " " ))) // Safe extraction
540538 CustomResponseHeaders (headers)
541539 }
542540 case None =>
543541 CustomResponseHeaders (Nil )
544542 }
545543 }
544+
546545 /**
547546 *
548547 */
@@ -2993,15 +2992,23 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
29932992 val remoteIpAddress = getRemoteIpAddress()
29942993
29952994 val authHeaders = AuthorisationUtil .getAuthorisationHeaders(reqHeaders)
2995+ val authHeadersWithEmptyValues = RequestHeadersUtil .checkEmptyRequestHeaderValues(reqHeaders)
2996+ val authHeadersWithEmptyNames = RequestHeadersUtil .checkEmptyRequestHeaderNames(reqHeaders)
29962997
29972998 // Identify consumer via certificate
2998- val consumerByCertificate = Consent .getCurrentConsumerViaMtls (callContext = cc)
2999+ val consumerByCertificate = Consent .getCurrentConsumerViaTppSignatureCertOrMtls (callContext = cc)
29993000
30003001 val res =
3001- if (authHeaders.size > 1 ) { // Check Authorization Headers ambiguity
3002+ if (authHeadersWithEmptyValues.nonEmpty) { // Check Authorization Headers Empty Values
3003+ val message = ErrorMessages .EmptyRequestHeaders + s " Header names: ${authHeadersWithEmptyValues.mkString(" , " )}"
3004+ Future { (fullBoxOrException(Empty ~> APIFailureNewStyle (message, 400 , Some (cc.toLight))), None ) }
3005+ } else if (authHeadersWithEmptyNames.nonEmpty) { // Check Authorization Headers Empty Names
3006+ val message = ErrorMessages .EmptyRequestHeaders + s " Header values: ${authHeadersWithEmptyNames.mkString(" , " )}"
3007+ Future { (fullBoxOrException(Empty ~> APIFailureNewStyle (message, 400 , Some (cc.toLight))), None ) }
3008+ } else if (authHeaders.size > 1 ) { // Check Authorization Headers ambiguity
30023009 Future { (Failure (ErrorMessages .AuthorizationHeaderAmbiguity + s " ${authHeaders}" ), None ) }
30033010 } else if (APIUtil .`hasConsent-ID`(reqHeaders)) { // Berlin Group's Consent
3004- Consent .applyBerlinGroupRules(APIUtil .`getConsent-ID`(reqHeaders), cc)
3011+ Consent .applyBerlinGroupRules(APIUtil .`getConsent-ID`(reqHeaders), cc.copy(consumer = consumerByCertificate) )
30053012 } else if (APIUtil .hasConsentJWT(reqHeaders)) { // Open Bank Project's Consent
30063013 val consentValue = APIUtil .getConsentJWT(reqHeaders)
30073014 Consent .getConsentJwtValueByConsentId(consentValue.getOrElse(" " )) match {
@@ -3011,12 +3018,12 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
30113018 // Note: At this point we are getting the Consumer from the Consumer in the Consent.
30123019 // This may later be cross checked via the value in consumer_validation_method_for_consent.
30133020 // Get the source of truth for Consumer (e.g. CONSUMER_CERTIFICATE) as early as possible.
3014- cc.copy(consumer = Consent .getCurrentConsumerViaMtls(callContext = cc) )
3021+ cc.copy(consumer = consumerByCertificate )
30153022 )
30163023 case _ =>
30173024 JwtUtil .checkIfStringIsJWTValue(consentValue.getOrElse(" " )).isDefined match {
30183025 case true => // It's JWT obtained via "Consent-JWT" request header
3019- Consent .applyRules(APIUtil .getConsentJWT(reqHeaders), cc)
3026+ Consent .applyRules(APIUtil .getConsentJWT(reqHeaders), cc.copy(consumer = consumerByCertificate) )
30203027 case false => // Unrecognised consent value
30213028 Future { (Failure (ErrorMessages .ConsentHeaderValueInvalid ), None ) }
30223029 }
@@ -3115,8 +3122,7 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
31153122 }
31163123 else if (Option (cc).flatMap(_.user).isDefined) {
31173124 Future {(cc.user, Some (cc))}
3118- }
3119- else {
3125+ } else {
31203126 if (hasAuthorizationHeader(reqHeaders)) {
31213127 // We want to throw error in case of wrong or unsupported header. For instance:
31223128 // - Authorization: mF_9.B5f-4.1JqM
0 commit comments