diff --git a/modules/openapi/build.gradle.kts b/modules/openapi/build.gradle.kts index ce5f5fef..7d913327 100644 --- a/modules/openapi/build.gradle.kts +++ b/modules/openapi/build.gradle.kts @@ -4,6 +4,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile plugins { kotlin("multiplatform") version "2.0.0" + kotlin("plugin.serialization") version "2.0.0" id("org.openapi.generator") version "7.7.0" id("maven-publish") } @@ -23,11 +24,26 @@ repositories { kotlin { tasks { + // Temporary fix for this issue: https://github.com/OpenAPITools/openapi-generator/issues/17658 + register("fixOpenApiGeneratorIssue") { + from( + "$projectDir/build/generated/src/commonMain/kotlin/com/sphereon/oid/fed/openapi" + ) + into( + "$projectDir/build/copy/src/commonMain/kotlin/com/sphereon/oid/fed/openapi" + ) + filter { line: String -> + line.replace( + "kotlin.collections.Map", + "kotlinx.serialization.json.JsonObject") + } + } + withType { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } named("sourcesJar") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } } jvm { @@ -58,19 +74,23 @@ kotlin { } } - named("compileKotlinJvm") { + named("fixOpenApiGeneratorIssue") { dependsOn("openApiGenerate") + } + + named("compileKotlinJvm") { + dependsOn("fixOpenApiGeneratorIssue") compilerOptions { jvmTarget.set(JvmTarget.JVM_11) } } named("jvmSourcesJar") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } named("jvmJar") { - dependsOn("compileKotlinJvm") + dependsOn("fixOpenApiGeneratorIssue") archiveBaseName.set("openapi") duplicatesStrategy = DuplicatesStrategy.EXCLUDE from(configurations.kotlinCompilerClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) @@ -82,10 +102,10 @@ kotlin { js { tasks { named("compileKotlinJs") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } named("jsSourcesJar") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } } nodejs() @@ -94,37 +114,37 @@ kotlin { iosX64 { tasks { named("compileKotlinIosX64") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } named("iosX64SourcesJar") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } } } iosArm64 { tasks { named("compileKotlinIosArm64") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } named("iosArm64SourcesJar") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } } } iosSimulatorArm64 { tasks { named("compileKotlinIosSimulatorArm64") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } named("iosSimulatorArm64SourcesJar") { - dependsOn("openApiGenerate") + dependsOn("fixOpenApiGeneratorIssue") } } } sourceSets { val commonMain by getting { - kotlin.srcDir("build/generated/src/commonMain/kotlin") + kotlin.srcDir("build/copy/src/commonMain/kotlin") dependencies { implementation("io.ktor:ktor-client-core:$ktorVersion") implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion") diff --git a/modules/openapi/gradle.properties b/modules/openapi/gradle.properties index 33cf166a..08d60d78 100644 --- a/modules/openapi/gradle.properties +++ b/modules/openapi/gradle.properties @@ -1,2 +1,2 @@ kotlin.code.style=official -profiles=models-only +#profiles=models-only diff --git a/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/logic/EntityLogic.kt b/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/logic/EntityLogic.kt new file mode 100644 index 00000000..ac937fa1 --- /dev/null +++ b/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/logic/EntityLogic.kt @@ -0,0 +1,33 @@ +package com.sphereon.oid.fed.common.logic + +import com.sphereon.oid.fed.openapi.models.EntityStatement + +class EntityLogic { + + fun getEntityType(entityStatement: EntityStatement): EntityType { + if (isFederationListEndpointPresent(entityStatement) == true && isAuthorityHintPresent(entityStatement) == false) { + return EntityType.TRUST_ANCHOR + } else if (isFederationListEndpointPresent(entityStatement) == true && isAuthorityHintPresent(entityStatement) == true) { + return EntityType.INTERMEDIATE + } else if (isFederationListEndpointPresent(entityStatement) == false && isAuthorityHintPresent(entityStatement) == true) { + return EntityType.LEAF + } else { + return EntityType.UNDEFINED + } + } + + private fun isAuthorityHintPresent(entityStatement: EntityStatement): Boolean { + return entityStatement.authorityHints?.isEmpty() == false + } + + private fun isFederationListEndpointPresent(entityStatement: EntityStatement): Boolean { + return entityStatement.metadata?.federationEntity?.federationListEndpoint?.isNotEmpty() == true + } +} + +enum class EntityType { + LEAF, + INTERMEDIATE, + TRUST_ANCHOR, + UNDEFINED +} \ No newline at end of file diff --git a/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/mapper/JsonMapper.kt b/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/mapper/JsonMapper.kt index 192ae769..bc504a52 100644 --- a/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/mapper/JsonMapper.kt +++ b/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/mapper/JsonMapper.kt @@ -7,7 +7,7 @@ import kotlinx.serialization.json.decodeFromJsonElement class JsonMapper { /* - * Used for mapping JWT token to EntityStatement object + * Used for mapping JWT token to EntityStatement object */ fun mapEntityStatement(jwtToken: String): EntityStatement? { val data = decodeJWTComponents(jwtToken) @@ -17,4 +17,15 @@ class JsonMapper { null } } + + /* + * Used for mapping trust chain + */ + fun mapTrustChain(jwtTokenList: List): List { + val list: MutableList = mutableListOf() + jwtTokenList.forEach { jwtToken -> + list.add(mapEntityStatement(jwtToken)) + } + return list + } } \ No newline at end of file diff --git a/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/model/JWTHeader.kt b/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/model/JWTHeader.kt index 1cdd0f26..b1937f06 100644 --- a/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/model/JWTHeader.kt +++ b/modules/openid-federation-common/src/commonMain/kotlin/com/sphereon/oid/fed/common/model/JWTHeader.kt @@ -8,5 +8,6 @@ import kotlinx.serialization.SerialName data class JWTHeader( @SerialName("alg") val alg: String, // RS256 @SerialName("kid") val kid: String, // B6EB8488CC84C41017134BC77F4132A0467CCC0E - @SerialName("typ") val typ: String // entity-statement+jwt + @SerialName("typ") val typ: String? = null, // entity-statement+jwt + @SerialName("trust_chain") val trustChain: List? = null // ["eyJhbGciOiJSUzI1NiIsImtpZCI6IlpXRlRRbWhmVFdaSVRuRlRZM0ZTV2pKdU5HMWZWV05hZWxkNmNtUjFRa0pEYlhaWlRYQm1hM1JWUVEiLCJ0eXAiOiJlbnRpdHktc3RhdGVtZW50K2p3dCJ9.eyJleHAiOjE2OTY1ODMzMzQsImlhdCI6MTY5NjI4MzMzNCwiaXNzIjoiaHR0cHM6Ly90cnVzdC1hbmNob3IuZXhhbXBsZS5vcmciLCJzdWIiOiJodHRwczovL2ludGVybWVkaWF0ZS5laWRhcy5leGFtcGxlLm9yZyIsImp3a3MiOnsia2V5cyI6W3sia3R5IjoiUlNBIiwia2lkIjoiWmxKd05tNDVUMmxVY1hsSFRHZzFaV2hsYmxkalVXbGxjbVF0U1VsUVdYcEhTMUpFUTA4eVRXVnZOQSIsImUiOiJBUUFCIiwibiI6ImtSQUlzLVRBblF6T29lc195RW9oaDNUeGlaWFlPRC1xekI2T25JalZCaVI0WFNGbkw4djhRQ0IxamJiSlZTQ1hBZmdObTlBZjdVRDNBX0E2T1pQOUtacldSUk00NEp0TVAzZmxVSU5CQ2xzNFBrdVd2RklmWEtaaWVUNGhBMzNYdUlTSndqT2NlNnRrbUZTUl9wQmI3S0JHbnB4d3dnRlJjeUM2RU1VQWtWUGdQRl9mbXM3NEEyTF83TGVaNzh2X053VUhsY2VxVHB1OUx6VTRuTTd1RTZQY0JPSmJweXI2SFFuUTR1VHN6WThsWHVmT3pHZ2IzVXNDNmRnQWVVVERIZlFROE4xYXV2bkJUNmR0SHNHNWMxS2NCT2QzLVp6ZTZ5WVE5c2JLUlUtWVoydDZKdUJIbS1xLTVOamxiRWVwNDAwbFgxSXlKdG9Tc3F0d3lCX1djdyJ9XX19.CvBvN0aG-r13UG4uITH72tC5CbAG0rT4qYQ5wwHOtGE021etZFQd40RFnQT5e-Gy_Y8Wiin-Zmc1hWW2rVyZ1RRInjYGUt26QI6ujR-5w9Y_LHVp-6RzYEF0lg9otpAyszQE4hf5qBZYAj8t39FvCYWTYVci6mtpovJQ380ha8I4QL__fZtEgDLQ-7VKS58nN1DOVdcIICMMfxpDR81bkY5i5Qxcy7AaZTN6xxE2SlCO-pKKub0jBUtnug20-BL2YgcPhLFOYWfj2cuyapOA9Omwu6CPhmZHgsL1P2oK_f4jA9JxNDYcV0losDbD86r8Wg3anM2lVM5BTHkiUr2grg"] ) \ No newline at end of file diff --git a/modules/openid-federation-common/src/commonTest/kotlin/com/sphereon/oid/fed/common/logic/EntityLogicTest.kt b/modules/openid-federation-common/src/commonTest/kotlin/com/sphereon/oid/fed/common/logic/EntityLogicTest.kt new file mode 100644 index 00000000..7ba05790 --- /dev/null +++ b/modules/openid-federation-common/src/commonTest/kotlin/com/sphereon/oid/fed/common/logic/EntityLogicTest.kt @@ -0,0 +1,56 @@ +package com.sphereon.oid.fed.common.logic + +import com.sphereon.oid.fed.openapi.models.EntityStatement +import com.sphereon.oid.fed.openapi.models.Metadata +import kotlinx.serialization.json.Json +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals + +class EntityLogicTest { + + private val leafEntityString = """{"metadata":{"openid_relying_party":{"client_registration_types":["automatic"],"client_name":"JESISERVIZI SRL","grant_types":["authorization_code","refresh_token"],"jwks":{"keys":[{"kty":"RSA","use":"sig","n":"yF7zakG7N8G2meDjsgqFowtxE51FtG8HacCDxA_qiMGp5lrcC4CggEdHkpdI3RrYTZ9WvADMWZEdIwydbIPn1HsPNCEy1UpsWQEZ-_8mHXGVz6p7ePrPXjIKl2eGqyQG_iCdAjqVpQ43Fqe3Mg17V-Phnn3gN_zMS7-eOXwuhWPiLZn7mFkiGin2LKECok4aaOcxIWRhsiNJdT5j0T1ORuk9y-gfJ-ljauVLh4hn5cwz7nj2lKBA0e-FOBTDSbpL_jYCj0NkvCrgFJSPDitne4M_M6YM1GpSNuBNNCOGYzjmynGpqu3btgdd5ONh2Ym4Kzwspu_RnLY3lyWR6lC_ad7q4fl4Zjlhp6murcKt15OkvijFVILraFqglugP6lHb89j1QQKKeBRNj_k93YQ5o1cT3iV-j-2BMcgB5Rfp-1sKlz10QQlMWXnbN7ruKs6Q2M5XNOGu8fJ9ohYM9rECmPmmVQI5vzoH65JfbKT0Mgfer59QY1s4IEgn5csGEw2p","e":"AQAB","kid":"B6EB8488CC84C41017134BC77F4132A0467CCC0E"},{"kty":"RSA","use":"enc","n":"yF7zakG7N8G2meDjsgqFowtxE51FtG8HacCDxA_qiMGp5lrcC4CggEdHkpdI3RrYTZ9WvADMWZEdIwydbIPn1HsPNCEy1UpsWQEZ-_8mHXGVz6p7ePrPXjIKl2eGqyQG_iCdAjqVpQ43Fqe3Mg17V-Phnn3gN_zMS7-eOXwuhWPiLZn7mFkiGin2LKECok4aaOcxIWRhsiNJdT5j0T1ORuk9y-gfJ-ljauVLh4hn5cwz7nj2lKBA0e-FOBTDSbpL_jYCj0NkvCrgFJSPDitne4M_M6YM1GpSNuBNNCOGYzjmynGpqu3btgdd5ONh2Ym4Kzwspu_RnLY3lyWR6lC_ad7q4fl4Zjlhp6murcKt15OkvijFVILraFqglugP6lHb89j1QQKKeBRNj_k93YQ5o1cT3iV-j-2BMcgB5Rfp-1sKlz10QQlMWXnbN7ruKs6Q2M5XNOGu8fJ9ohYM9rECmPmmVQI5vzoH65JfbKT0Mgfer59QY1s4IEgn5csGEw2p","e":"AQAB","kid":"B6EB8488CC84C41017134BC77F4132A0467CCC0E_enc"}]},"redirect_uris":["https://cohesion2.regione.marche.it/oidc/sa/2BLS82OD/callback"],"response_types":["code"],"client_id":"https://cohesion2.regione.marche.it/oidc/sa/2BLS82OD/","id_token_signed_response_alg":"RS256","id_token_encrypted_response_alg":"RSA-OAEP","id_token_encrypted_response_enc":"A256CBC-HS512","userinfo_signed_response_alg":"RS256","userinfo_encrypted_response_alg":"RSA-OAEP","userinfo_encrypted_response_enc":"A256CBC-HS512","token_endpoint_auth_method":"private_key_jwt"},"federation_entity":{"contacts":["jesiservizi@pec.it"],"organization_name":"JESISERVIZI SRL","homepage_uri":"https://cohesion2.regione.marche.it","policy_uri":"https://www.regione.marche.it/Privacy","logo_uri":"https://cohesion2.regione.marche.it/Common/assets/images/cohesion.svg","federation_resolve_endpoint":"https://cohesion2.regione.marche.it/oidc/sa/2BLS82OD/resolve"}},"trust_marks":[{"id":"https://oidc.registry.servizicie.interno.gov.it/openid_relying_party/public","iss":"https://cohesion2.regione.marche.it/oidc/sa/","trust_mark":"eyJ0eXAiOiJ0cnVzdC1tYXJrXHUwMDJCand0Iiwia2lkIjoiQjZFQjg0ODhDQzg0QzQxMDE3MTM0QkM3N0Y0MTMyQTA0NjdDQ0MwRSIsImFsZyI6IlJTMjU2In0.eyJpZCI6Imh0dHBzOi8vb2lkYy5yZWdpc3RyeS5zZXJ2aXppY2llLmludGVybm8uZ292Lml0L29wZW5pZF9yZWx5aW5nX3BhcnR5L3B1YmxpYyIsImlzcyI6Imh0dHBzOi8vY29oZXNpb24yLnJlZ2lvbmUubWFyY2hlLml0L29pZGMvc2EvIiwic3ViIjoiaHR0cHM6Ly9jb2hlc2lvbjIucmVnaW9uZS5tYXJjaGUuaXQvb2lkYy9zYS8yQkxTODJPRC8iLCJpYXQiOjE3MDMyNTA0MDYsIm9yZ2FuaXphdGlvbl90eXBlIjoicHVibGljIiwiaWRfY29kZSI6eyJpcGFfY29kZSI6IjJCTFM4Mk9EIn0sImVtYWlsIjoiamVzaXNlcnZpemlAcGVjLml0IiwiZXhwIjoxODYxMTAzMjA2LCJvcmdhbml6YXRpb25fbmFtZSI6Ikplc2kgc2Vydml6aSBzcmwiLCJyZWYiOiJodHRwczovL2NvaGVzaW9uMi5yZWdpb25lLm1hcmNoZS5pdC90ZXN0Y29oZXNpb24ifQ.KYhjjcTXWsymdXJpkOoB4NcsZPAFxCbRa1jsFKqJrimxTlwMB05uOtZxOntiy1Qyu9eTu2pujnh-tNI0gMqHn81lgoSYCbrKZ-nip4ya-Tu-lGa5ocN_3ngcgOge-EeBVCrmBXIIVCx83o0ML_bKVsDCgTM2-1BqI_Vix6UAV_tZMOCkM6s6lAkwkZ_Ub-TayPCjLYEYoslRK7Hvi6vhpX2a1N6-Af8u7VkB2Iq8u-hHHioXgOKEo4ZbD72goOO1ZDOmoE0X3JrJhd7yYaOIaOEwnUFlZnvsILm8OAn-bFSBr-uzkoB-qe6U35dtQPw2adZOTnxEu-6bq-5PrNPwc2vn-UBInQUuws2OymmpT3N-QVvt472ER_EYXoJX2egI46d4SJ3edF9kvi3FZy0jH0lE9hfEdXwAyqsfu4RjD9WKNsn35kbxfC62u8sHKF3DXJG2YmEUct5KQMeBlMmsnqrMfDYeRDdKhl1bOCjFrPL8JEUladLcoViBNCOnAT4q"}],"authority_hints":["https://cohesion2.regione.marche.it/oidc/sa/","https://oidc.registry.servizicie.interno.gov.it"],"iss":"https://cohesion2.regione.marche.it/oidc/sa/2BLS82OD/","sub":"https://cohesion2.regione.marche.it/oidc/sa/2BLS82OD/","iat":1721029952,"exp":1721202752,"jwks":{"keys":[{"kty":"RSA","use":"sig","n":"yF7zakG7N8G2meDjsgqFowtxE51FtG8HacCDxA_qiMGp5lrcC4CggEdHkpdI3RrYTZ9WvADMWZEdIwydbIPn1HsPNCEy1UpsWQEZ-_8mHXGVz6p7ePrPXjIKl2eGqyQG_iCdAjqVpQ43Fqe3Mg17V-Phnn3gN_zMS7-eOXwuhWPiLZn7mFkiGin2LKECok4aaOcxIWRhsiNJdT5j0T1ORuk9y-gfJ-ljauVLh4hn5cwz7nj2lKBA0e-FOBTDSbpL_jYCj0NkvCrgFJSPDitne4M_M6YM1GpSNuBNNCOGYzjmynGpqu3btgdd5ONh2Ym4Kzwspu_RnLY3lyWR6lC_ad7q4fl4Zjlhp6murcKt15OkvijFVILraFqglugP6lHb89j1QQKKeBRNj_k93YQ5o1cT3iV-j-2BMcgB5Rfp-1sKlz10QQlMWXnbN7ruKs6Q2M5XNOGu8fJ9ohYM9rECmPmmVQI5vzoH65JfbKT0Mgfer59QY1s4IEgn5csGEw2p","e":"AQAB","kid":"B6EB8488CC84C41017134BC77F4132A0467CCC0E"},{"kty":"RSA","use":"enc","n":"yF7zakG7N8G2meDjsgqFowtxE51FtG8HacCDxA_qiMGp5lrcC4CggEdHkpdI3RrYTZ9WvADMWZEdIwydbIPn1HsPNCEy1UpsWQEZ-_8mHXGVz6p7ePrPXjIKl2eGqyQG_iCdAjqVpQ43Fqe3Mg17V-Phnn3gN_zMS7-eOXwuhWPiLZn7mFkiGin2LKECok4aaOcxIWRhsiNJdT5j0T1ORuk9y-gfJ-ljauVLh4hn5cwz7nj2lKBA0e-FOBTDSbpL_jYCj0NkvCrgFJSPDitne4M_M6YM1GpSNuBNNCOGYzjmynGpqu3btgdd5ONh2Ym4Kzwspu_RnLY3lyWR6lC_ad7q4fl4Zjlhp6murcKt15OkvijFVILraFqglugP6lHb89j1QQKKeBRNj_k93YQ5o1cT3iV-j-2BMcgB5Rfp-1sKlz10QQlMWXnbN7ruKs6Q2M5XNOGu8fJ9ohYM9rECmPmmVQI5vzoH65JfbKT0Mgfer59QY1s4IEgn5csGEw2p","e":"AQAB","kid":"B6EB8488CC84C41017134BC77F4132A0467CCC0E_enc"}]}}""" + private val intermediateEntityString = """{"metadata":{"federation_entity":{"organization_name":"Regione Marche","homepage_uri":"https://cohesion2.regione.marche.it","policy_uri":"https://www.regione.marche.it/Privacy","logo_uri":"https://cohesion2.regione.marche.it/Common/assets/images/cohesion.svg","contacts":["regione.marche.protocollogiunta@emarche.it"],"federation_resolve_endpoint":"https://cohesion2.regione.marche.it/oidc/sa/resolve","federation_fetch_endpoint":"https://cohesion2.regione.marche.it/oidc/sa/fetch","federation_list_endpoint":"https://cohesion2.regione.marche.it/oidc/sa/list","federation_trust_mark_status_endpoint":"https://cohesion2.regione.marche.it/oidc/sa/trust_mark_status"}},"trust_marks":[{"id":"https://oidc.registry.servizicie.interno.gov.it/intermediate/public","iss":"https://oidc.registry.servizicie.interno.gov.it","trust_mark":"eyJraWQiOiJkZWZhdWx0UlNBU2lnbiIsInR5cCI6InRydXN0LW1hcmsrand0IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJodHRwczovL2NvaGVzaW9uMi5yZWdpb25lLm1hcmNoZS5pdC9vaWRjL3NhLyIsInNhX3Byb2ZpbGUiOiJbXCJmdWxsXCJdIiwiaXNzIjoiaHR0cHM6Ly9vaWRjLnJlZ2lzdHJ5LnNlcnZpemljaWUuaW50ZXJuby5nb3YuaXQiLCJvcmdhbml6YXRpb25fdHlwZSI6InB1YmxpYyIsImlkIjoiaHR0cHM6Ly9vaWRjLnJlZ2lzdHJ5LnNlcnZpemljaWUuaW50ZXJuby5nb3YuaXQvaW50ZXJtZWRpYXRlL3B1YmxpYyIsImV4cCI6MTczNDc5NTEyMCwiaWF0IjoxNzAzMTcyNzIwfQ.QoOpnGZS2UxwhMLkIgCQ7jhWK8BcS6Mukez8VEGpNUf6CgCUxto4xx7XC4p9mxLCP_xikUJpWqlVBW0WFPqLyf8-HK6Z9YEfo5mAuZ4_fPUXnTkKmHi_gKHtwOXaB8QT8qTWwRlhk2wAjepeIl9E0FLKO4GLYNzlQlZPByxVIAXav2WmIE3VrwIWRD-Fn8W_hX0EhS-t4lxaf2w88ZEJcdHfDn-9HSbm7QaVpYSIT5FXpbkunO9FpjdzBzMK_GyWpgWKdZiVwKKJDvSC5dYAssg4NEynoLg_vhhj4_hvhGI2bIFiPZoyxmgKKp8LnTIeJnmH4a2VBF_DDfnGq4TfzQ"}],"authority_hints":["https://oidc.registry.servizicie.interno.gov.it"],"iss":"https://cohesion2.regione.marche.it/oidc/sa/","sub":"https://cohesion2.regione.marche.it/oidc/sa/","iat":1721027703,"exp":1721200503,"jwks":{"keys":[{"kty":"RSA","use":"sig","n":"yF7zakG7N8G2meDjsgqFowtxE51FtG8HacCDxA_qiMGp5lrcC4CggEdHkpdI3RrYTZ9WvADMWZEdIwydbIPn1HsPNCEy1UpsWQEZ-_8mHXGVz6p7ePrPXjIKl2eGqyQG_iCdAjqVpQ43Fqe3Mg17V-Phnn3gN_zMS7-eOXwuhWPiLZn7mFkiGin2LKECok4aaOcxIWRhsiNJdT5j0T1ORuk9y-gfJ-ljauVLh4hn5cwz7nj2lKBA0e-FOBTDSbpL_jYCj0NkvCrgFJSPDitne4M_M6YM1GpSNuBNNCOGYzjmynGpqu3btgdd5ONh2Ym4Kzwspu_RnLY3lyWR6lC_ad7q4fl4Zjlhp6murcKt15OkvijFVILraFqglugP6lHb89j1QQKKeBRNj_k93YQ5o1cT3iV-j-2BMcgB5Rfp-1sKlz10QQlMWXnbN7ruKs6Q2M5XNOGu8fJ9ohYM9rECmPmmVQI5vzoH65JfbKT0Mgfer59QY1s4IEgn5csGEw2p","e":"AQAB","kid":"B6EB8488CC84C41017134BC77F4132A0467CCC0E"},{"kty":"RSA","use":"enc","n":"yF7zakG7N8G2meDjsgqFowtxE51FtG8HacCDxA_qiMGp5lrcC4CggEdHkpdI3RrYTZ9WvADMWZEdIwydbIPn1HsPNCEy1UpsWQEZ-_8mHXGVz6p7ePrPXjIKl2eGqyQG_iCdAjqVpQ43Fqe3Mg17V-Phnn3gN_zMS7-eOXwuhWPiLZn7mFkiGin2LKECok4aaOcxIWRhsiNJdT5j0T1ORuk9y-gfJ-ljauVLh4hn5cwz7nj2lKBA0e-FOBTDSbpL_jYCj0NkvCrgFJSPDitne4M_M6YM1GpSNuBNNCOGYzjmynGpqu3btgdd5ONh2Ym4Kzwspu_RnLY3lyWR6lC_ad7q4fl4Zjlhp6murcKt15OkvijFVILraFqglugP6lHb89j1QQKKeBRNj_k93YQ5o1cT3iV-j-2BMcgB5Rfp-1sKlz10QQlMWXnbN7ruKs6Q2M5XNOGu8fJ9ohYM9rECmPmmVQI5vzoH65JfbKT0Mgfer59QY1s4IEgn5csGEw2p","e":"AQAB","kid":"B6EB8488CC84C41017134BC77F4132A0467CCC0E_enc"}]}}""" + private val trustAnchorEntityString = """{"sub":"https://oidc.registry.servizicie.interno.gov.it","metadata":{"federation_entity":{"federation_fetch_endpoint":"https://oidc.registry.servizicie.interno.gov.it/fetch","federation_resolve_endpoint":"https://oidc.registry.servizicie.interno.gov.it/resolve","federation_trust_mark_status_endpoint":"https://oidc.registry.servizicie.interno.gov.it/trust_mark_status","federation_list_endpoint":"https://oidc.registry.servizicie.interno.gov.it/list"}},"jwks":{"keys":[{"kty":"RSA","e":"AQAB","use":"sig","kid":"defaultRSASign","n":"qRTJHQgb2f8cln9dJb-Wgik4qEL5GG__sPzlAU4i69S6yHxeMg32YgLfUzpNBx_8kX2ndzYXM_RKmo3jhjQxuxCK1IHSQcMkg1hGii-xRw8x45t8SGlWcSHi7_6RaAY1SyFcEElNAqHi5oeBaB3FGvfrV-EP-cNkUvGEVbys_CbxyGDQ9QM0NErsilVlMARDErENZcrY0rNKt52WoZgy3psVcd8U5D0LqfC77bPjG35PaVhwYAnlP0ez0Hf6tuyWJHeA52dCde-na3WjmParkclpFr-KjXeIC8BwfjEpAXbKcp8NmuQFj9fD9KnR6vCdO91RyBIbDluL5LH8s0qDCQ"},{"kty":"EC","use":"sig","crv":"P-256","kid":"defaultECSign","x":"xMkWIa1EZyjgmk3JQLtHDA9p0TpP9wMSbJK0oAitgck","y":"CVLFstOwKwtQrut_voHjYO6Jz1K0NXRu8OLCTmKosLg"},{"kty":"RSA","e":"AQAB","use":"enc","kid":"defaultRSAEnc","n":"wew22xcpfASkQQp7SOo_Gs6cKj2Xy7xVZK_tgZxzAyQxLSxm5sU4ZGs6mdIAHdEvQ91SnEHTtjpeAS9wCvNXVmVxNIjFAPJzCYpsfFxGzW1PR3SCBeKPYzUjSyBSel5-mSwU80yYAqOlZ1QRZNQI5ESUvNPoePFjGCofxnFRsmqy_mAwZynd2NrrsT2Ayp0L6PQwz-EkOhjEBpzsyq0pMujnZEfvPy9P-Xv2SUFLeJPrmcDye64Z2Y9WPh2jpknhOxDK8RML-2YTvb4uSOjZ0XZOW9mVogNJRJm2zePTeeLPqGluLcDzplby0nLbLjdX7K3oLbqhDaewj7VraKemsQ"}]},"trust_mark_issuers":{"https://oidc.registry.servizicie.interno.gov.it/oauth_resource/private":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_provider/private":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/oauth_resource/public":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/intermediate/public":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_relying_party/public":["https://oidc.registry.servizicie.interno.gov.it","https://cohesion2.regione.marche.it/oidc/sa/","https://auth.toscana.it/auth/realms/enti/federation-entity/r_toscan_sa_enti","https://oidcsa.webloom.it","https://secure.eremind.it/identita-digitale-oidc/oidc-fed","https://cie-oidc.comune-online.it/AuthServiceOIDC/oidc/sa","https://php-cie.andxor.it","https://oidc.studioamica.com","https://idp.entranext.it/services/oidc/sa/sso","https://cwolsso.nuvolapalitalsoft.it/services/oidc/sa/sso","https://federa.lepida.it/gw/OidcSaFull/","https://www.eurocontab.it/api"],"https://oidc.registry.servizicie.interno.gov.it/intermediate/private":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_provider/public":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_relying_party/private":["https://oidc.registry.servizicie.interno.gov.it","https://oidcsa.webloom.it","https://secure.eremind.it/identita-digitale-oidc/oidc-fed","https://cie-oidc.comune-online.it/AuthServiceOIDC/oidc/sa","https://php-cie.andxor.it","https://oidc.studioamica.com","https://idp.entranext.it/services/oidc/sa/sso","https://cwolsso.nuvolapalitalsoft.it/services/oidc/sa/sso","https://federa.lepida.it/gw/OidcSaFull/","https://www.eurocontab.it/api"]},"iss":"https://oidc.registry.servizicie.interno.gov.it","exp":1720878673,"iat":1720792273,"constraints":{"max_path_length":1},"trust_marks_issuers":{"https://oidc.registry.servizicie.interno.gov.it/oauth_resource/private":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_provider/private":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/oauth_resource/public":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/intermediate/public":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_relying_party/public":["https://oidc.registry.servizicie.interno.gov.it","https://cohesion2.regione.marche.it/oidc/sa/","https://auth.toscana.it/auth/realms/enti/federation-entity/r_toscan_sa_enti","https://oidcsa.webloom.it","https://secure.eremind.it/identita-digitale-oidc/oidc-fed","https://cie-oidc.comune-online.it/AuthServiceOIDC/oidc/sa","https://php-cie.andxor.it","https://oidc.studioamica.com","https://idp.entranext.it/services/oidc/sa/sso","https://cwolsso.nuvolapalitalsoft.it/services/oidc/sa/sso","https://federa.lepida.it/gw/OidcSaFull/","https://www.eurocontab.it/api"],"https://oidc.registry.servizicie.interno.gov.it/intermediate/private":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_provider/public":["https://oidc.registry.servizicie.interno.gov.it"],"https://oidc.registry.servizicie.interno.gov.it/openid_relying_party/private":["https://oidc.registry.servizicie.interno.gov.it","https://oidcsa.webloom.it","https://secure.eremind.it/identita-digitale-oidc/oidc-fed","https://cie-oidc.comune-online.it/AuthServiceOIDC/oidc/sa","https://php-cie.andxor.it","https://oidc.studioamica.com","https://idp.entranext.it/services/oidc/sa/sso","https://cwolsso.nuvolapalitalsoft.it/services/oidc/sa/sso","https://federa.lepida.it/gw/OidcSaFull/","https://www.eurocontab.it/api"]}}""" + + private val entityLogic = EntityLogic() + + private lateinit var leafEntityStatement: EntityStatement + private lateinit var intermediateEntityStatement: EntityStatement + private lateinit var trustAnchorEntityStatement: EntityStatement + + + @BeforeTest + fun setUp() { + // ignoreUnknownKeys added because OpenAPI model misses few objects + // Need to fix OpenAPI model + val json = Json { ignoreUnknownKeys = true } + leafEntityStatement = json.decodeFromString(leafEntityString) + intermediateEntityStatement = json.decodeFromString(intermediateEntityString) + trustAnchorEntityStatement = json.decodeFromString(trustAnchorEntityString) + } + + @Test + fun shouldReturnTrustAnchor() { + assertEquals(EntityType.TRUST_ANCHOR, entityLogic.getEntityType(trustAnchorEntityStatement)) + } + + @Test + fun shouldReturnIntermediate() { + assertEquals(EntityType.INTERMEDIATE, entityLogic.getEntityType(intermediateEntityStatement)) + } + + @Test + fun shouldReturnLeafEntity() { + assertEquals(EntityType.LEAF, entityLogic.getEntityType(leafEntityStatement)) + } + + @Test + fun shouldReturnUndefined() { + val entityStatement = EntityStatement( + metadata = Metadata(federationEntity = null), + authorityHints = emptyList() + ) + assertEquals(EntityType.UNDEFINED, entityLogic.getEntityType(entityStatement)) + } +} \ No newline at end of file