Skip to content

Commit

Permalink
implement TrustChainResolveResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
jcmelati committed Nov 14, 2024
1 parent 49c7542 commit 952c5f0
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.sphereon.oid.fed.client.crypto.cryptoService
import com.sphereon.oid.fed.client.fetch.IFetchService
import com.sphereon.oid.fed.client.fetch.fetchService
import com.sphereon.oid.fed.client.trustchain.TrustChain
import com.sphereon.oid.fed.client.trustchain.TrustChainResolveResponse
import kotlin.js.JsExport

@JsExport.Ignore
Expand All @@ -28,7 +29,7 @@ class FederationClient(
entityIdentifier: String,
trustAnchors: Array<String>,
maxDepth: Int = 5
): MutableList<String>? {
): TrustChainResolveResponse {
return trustChainService.resolve(entityIdentifier, trustAnchors, maxDepth)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,31 @@ import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlin.collections.set
import kotlin.js.JsExport
import kotlin.js.JsName

/**
* Response object for the resolve operation.
*/
@JsExport
@JsName("TrustChainResolveResponse")
data class TrustChainResolveResponse(
/**
* A list of strings representing the resolved trust chain.
* Each string contains a JWT.
*/
val trustChain: List<String>? = null,

/**
* Indicates whether the resolve operation was successful.
*/
val error: Boolean = false,

/**
* Error message in case of a failure, if any.
*/
val errorMessage: String? = null
)

/*
* TrustChain is a class that implements the logic to resolve and validate a trust chain.
Expand All @@ -26,15 +51,19 @@ class TrustChain
) {
suspend fun resolve(
entityIdentifier: String, trustAnchors: Array<String>, maxDepth: Int
): MutableList<String>? {
): TrustChainResolveResponse {
val cache = SimpleCache<String, String>()
val chain: MutableList<String> = arrayListOf()
return try {
buildTrustChainRecursive(entityIdentifier, trustAnchors, chain, cache, 0, maxDepth)
val trustChain = buildTrustChainRecursive(entityIdentifier, trustAnchors, chain, cache, 0, maxDepth)
if (trustChain != null) {
TrustChainResolveResponse(trustChain, false, null)
} else {
TrustChainResolveResponse(null, true, "A Trust chain could not be established")
}
} catch (e: Exception) {
TrustChainConst.LOG.error("buildTrustChainRecursive failed", e)
// Log error
null
TrustChainResolveResponse(null, true, e.message)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.sphereon.oid.fed.openapi.models.Jwk
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertFalse

object FetchService : IFetchService {
override suspend fun fetchStatement(endpoint: String): String {
Expand All @@ -26,59 +26,59 @@ class TrustChainTest {
fun buildTrustChain() = runTest {
val client = FederationClient(FetchService, CryptoService)

val trustChain = client.resolveTrustChain(
val response = client.resolveTrustChain(
"https://spid.wbss.it/Spid/oidc/rp/ipasv_lt",
arrayOf("https://oidc.registry.servizicie.interno.gov.it")
)

assertNotNull(trustChain)
assertFalse(response.error)

assertEquals(4, trustChain.size)
assertEquals(4, response.trustChain?.size)

assertEquals(
trustChain[0],
response.trustChain?.get(0),
mockResponses.find { it[0] == "https://spid.wbss.it/Spid/oidc/rp/ipasv_lt/.well-known/openid-federation" }
?.get(1)
)

assertEquals(
trustChain[1],
response.trustChain?.get(1),
mockResponses.find { it[0] == "https://spid.wbss.it/Spid/oidc/sa/fetch?sub=https://spid.wbss.it/Spid/oidc/rp/ipasv_lt" }
?.get(1)
)

assertEquals(
trustChain[2],
response.trustChain?.get(2),
mockResponses.find { it[0] == "https://oidc.registry.servizicie.interno.gov.it/fetch?sub=https://spid.wbss.it/Spid/oidc/sa" }
?.get(1)
)

assertEquals(
trustChain[3],
response.trustChain?.get(3),
mockResponses.find { it[0] == "https://oidc.registry.servizicie.interno.gov.it/.well-known/openid-federation" }
?.get(1)
)

val trustChain2 = client.resolveTrustChain(
val response2 = client.resolveTrustChain(
"https://spid.wbss.it/Spid/oidc/sa",
arrayOf("https://oidc.registry.servizicie.interno.gov.it")
)

assertNotNull(trustChain2)
assertEquals(3, trustChain2.size)
assertFalse(response2.error)
assertEquals(3, response2.trustChain?.size)
assertEquals(
trustChain2[0],
response2.trustChain?.get(0),
mockResponses.find { it[0] == "https://spid.wbss.it/Spid/oidc/sa/.well-known/openid-federation" }?.get(1)
)

assertEquals(
trustChain2[1],
response2.trustChain?.get(1),
mockResponses.find { it[0] == "https://oidc.registry.servizicie.interno.gov.it/fetch?sub=https://spid.wbss.it/Spid/oidc/sa" }
?.get(1)
)

assertEquals(
trustChain2[2],
response2.trustChain?.get(2),
mockResponses.find { it[0] == "https://oidc.registry.servizicie.interno.gov.it/.well-known/openid-federation" }
?.get(1)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.sphereon.oid.fed.client.fetch.FetchServiceAdapter
import com.sphereon.oid.fed.client.fetch.IFetchService
import com.sphereon.oid.fed.client.fetch.fetchService
import com.sphereon.oid.fed.client.trustchain.TrustChain
import com.sphereon.oid.fed.client.trustchain.TrustChainResolveResponse
import com.sphereon.oid.fed.openapi.models.Jwk
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -47,13 +48,9 @@ class FederationClientJS(
entityIdentifier: String,
trustAnchors: Array<String>,
maxDepth: Int = 10
): Promise<Array<String>?> {
): Promise<TrustChainResolveResponse> {
return scope.promise {
try {
trustChainService.resolve(entityIdentifier, trustAnchors, maxDepth)?.toTypedArray()
} catch (e: Exception) {
throw RuntimeException("Failed to resolve trust chain: ${e.message}", e)
}
trustChainService.resolve(entityIdentifier, trustAnchors, maxDepth)
}
}
}

0 comments on commit 952c5f0

Please sign in to comment.