mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 15:27:01 +00:00
feature/Add endpoint mtlsClientCertificateInfo v5.1.0
This commit is contained in:
parent
007c9d4351
commit
d7b28ec535
@ -11,7 +11,7 @@ import code.api.dynamic.endpoint.helper.practise.PractiseEndpoint
|
||||
import code.api.util.APIUtil.{defaultJValue, _}
|
||||
import code.api.util.ApiRole._
|
||||
import code.api.util.ExampleValue._
|
||||
import code.api.util.{ApiTrigger, ExampleValue}
|
||||
import code.api.util.{APIUtil, ApiTrigger, ExampleValue}
|
||||
import code.api.v2_2_0.JSONFactory220.{AdapterImplementationJson, MessageDocJson, MessageDocsJson}
|
||||
import code.api.v3_0_0.JSONFactory300.createBranchJsonV300
|
||||
import code.api.v3_0_0.custom.JSONFactoryCustom300
|
||||
@ -36,6 +36,7 @@ import com.openbankproject.commons.util.{ApiVersion, FieldNameApiVersions, Refle
|
||||
import net.liftweb.json
|
||||
import java.net.URLEncoder
|
||||
|
||||
import code.api.v5_1_0.CertificateInfoJsonV510
|
||||
import code.endpointMapping.EndpointMappingCommons
|
||||
|
||||
import scala.collection.immutable.List
|
||||
@ -4154,6 +4155,15 @@ object SwaggerDefinitionsJSON {
|
||||
val oAuth2ServerJWKURIJson = OAuth2ServerJWKURIJson("https://www.googleapis.com/oauth2/v3/certs")
|
||||
|
||||
val oAuth2ServerJwksUrisJson = OAuth2ServerJwksUrisJson(List(oAuth2ServerJWKURIJson))
|
||||
|
||||
val certificateInfoJsonV510 = CertificateInfoJsonV510(
|
||||
subject_dn = "OID.2.5.4.41=VPN, EMAILADDRESS=admin@tesobe.com, CN=TESOBE CA, OU=TESOBE Operations, O=TESOBE, L=Berlin, ST=Berlin, C=DE",
|
||||
issuer_dn = "CN=localhost, O=TESOBE GmbH, ST=Berlin, C=DE",
|
||||
not_before = "2022-04-01T10:13:00.000Z",
|
||||
not_after = "2032-04-01T10:13:00.000Z",
|
||||
roles = None,
|
||||
roles_info = Some("PEM Encoded Certificate does not contain PSD2 roles.")
|
||||
)
|
||||
|
||||
val updateAccountRequestJsonV310 = UpdateAccountRequestJsonV310(
|
||||
label = "Label",
|
||||
|
||||
@ -5,6 +5,7 @@ import java.security.PublicKey
|
||||
import java.security.cert.{CertificateExpiredException, CertificateNotYetValidException, X509Certificate}
|
||||
import java.security.interfaces.{ECPublicKey, RSAPublicKey}
|
||||
|
||||
import code.api.v5_1_0.CertificateInfoJsonV510
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.github.dwickern.macros.NameOf
|
||||
import com.nimbusds.jose.jwk.RSAKey
|
||||
@ -202,5 +203,48 @@ object X509 extends MdcLoggable {
|
||||
val rsaJWK = RSAKey.parse(cert)
|
||||
rsaJWK
|
||||
}
|
||||
|
||||
|
||||
private def extractCertificateInfo(pem: String): Box[CertificateInfoJsonV510] = {
|
||||
// Parse X.509 certificate
|
||||
val cert: X509Certificate = X509CertUtils.parse(pem)
|
||||
if (cert == null) {
|
||||
// Parsing failed
|
||||
Failure(ErrorMessages.X509ParsingFailed)
|
||||
} else {
|
||||
val subjectDN = cert.getSubjectDN().getName()
|
||||
val issuerDN = cert.getIssuerDN().getName()
|
||||
val notBefore = cert.getNotBefore()
|
||||
val notAfter = cert.getNotAfter()
|
||||
var roles: Option[List[String]] = None
|
||||
var rolesInfo: Option[String] = None
|
||||
try {
|
||||
val qcstatements = extractQcStatements(cert)
|
||||
val asn1encodable = extractPsd2QcStatements(qcstatements)
|
||||
roles = Some(getPsd2Roles(asn1encodable: Array[ASN1Encodable]))
|
||||
}
|
||||
catch {
|
||||
case _: Throwable =>
|
||||
Failure(ErrorMessages.X509ThereAreNoPsd2Roles)
|
||||
rolesInfo = Some("PEM Encoded Certificate does not contain PSD2 roles.")
|
||||
}
|
||||
val result = CertificateInfoJsonV510(
|
||||
subject_dn = subjectDN,
|
||||
issuer_dn = issuerDN,
|
||||
not_before = APIUtil.formatDate(notBefore),
|
||||
not_after = APIUtil.formatDate(notAfter),
|
||||
roles = roles,
|
||||
roles_info = rolesInfo
|
||||
)
|
||||
Full(result)
|
||||
}
|
||||
}
|
||||
|
||||
def getCertificateInfo(pem: Option[String]): Box[CertificateInfoJsonV510] = {
|
||||
pem match {
|
||||
case Some(value) => extractCertificateInfo(value)
|
||||
case None => Failure(ErrorMessages.X509CannotGetCertificate)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import code.api.util.APIUtil._
|
||||
import code.api.util.ApiRole._
|
||||
import code.api.util.ApiTag._
|
||||
import code.api.util.ErrorMessages.{$UserNotLoggedIn, BankNotFound, ConsentNotFound, InvalidJsonFormat, UnknownError, UserNotFoundByUserId, UserNotLoggedIn, _}
|
||||
import code.api.util.{ApiRole, NewStyle}
|
||||
import code.api.util.{APIUtil, ApiRole, NewStyle, X509}
|
||||
import code.api.util.NewStyle.HttpCode
|
||||
import code.api.v3_0_0.JSONFactory300.createAggregateMetricJson
|
||||
import code.api.v3_1_0.ConsentJsonV310
|
||||
@ -208,6 +208,43 @@ trait APIMethods510 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
mtlsClientCertificateInfo,
|
||||
implementedInApiVersion,
|
||||
nameOf(mtlsClientCertificateInfo),
|
||||
"GET",
|
||||
"/my/mtls/certificate/info",
|
||||
"Provide client's certificate info of a current call",
|
||||
s"""
|
||||
|Provide client's certificate info of a current call specified by PSD2-CERT value at Request Header
|
||||
|
|
||||
|${authenticationRequiredMessage(true)}
|
||||
|
|
||||
""".stripMargin,
|
||||
EmptyBody,
|
||||
certificateInfoJsonV510,
|
||||
List(
|
||||
UserNotLoggedIn,
|
||||
BankNotFound,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2, apiTagNewStyle)
|
||||
)
|
||||
lazy val mtlsClientCertificateInfo: OBPEndpoint = {
|
||||
case "my" :: "mtls" :: "certificate" :: "info" :: Nil JsonGet _ => {
|
||||
cc =>
|
||||
for {
|
||||
(Full(_), callContext) <- authenticatedAccess(cc)
|
||||
info <- Future(X509.getCertificateInfo(APIUtil.`getPSD2-CERT`(cc.requestHeaders))) map {
|
||||
unboxFullOrFail(_, callContext, X509GeneralError)
|
||||
}
|
||||
} yield {
|
||||
(info, HttpCode.`200`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
|
||||
@ -47,6 +47,15 @@ case class APIInfoJsonV510(
|
||||
resource_docs_requires_role: Boolean
|
||||
)
|
||||
|
||||
case class CertificateInfoJsonV510(
|
||||
subject_dn: String,
|
||||
issuer_dn: String,
|
||||
not_before: String,
|
||||
not_after: String,
|
||||
roles: Option[List[String]],
|
||||
roles_info: Option[String] = None
|
||||
)
|
||||
|
||||
object JSONFactory510 {
|
||||
def getApiInfoJSON(apiVersion : ApiVersion, apiVersionStatus: String) = {
|
||||
val organisation = APIUtil.getPropsValue("hosted_by.organisation", "TESOBE")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user