diff --git a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredState.kt b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredState.kt index 797ee224..ee6b10a6 100644 --- a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredState.kt +++ b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredState.kt @@ -21,6 +21,7 @@ import eu.europa.ec.eudi.openid4vci.CredentialIssuerMetadata import eu.europa.ec.eudi.openid4vci.IssuedCredential import eu.europa.ec.eudi.openid4vci.Issuer import eu.europa.ec.eudi.wallet.transfer.openid4vp.ClientId +import java.io.* import java.net.URI internal data class DeferredState( @@ -29,7 +30,7 @@ internal data class DeferredState( val credentialIssuerMetadata: CredentialIssuerMetadata, val authorizedRequest: AuthorizedRequest, val deferredCredential: IssuedCredential.Deferred? = null, -) { +) : Serializable { val version = VERSION @@ -42,15 +43,26 @@ internal data class DeferredState( ) fun encode(): ByteArray { - return byteArrayOf() + return ByteArrayOutputStream().use { baos -> + ObjectOutputStream(baos).use { oos -> + oos.writeObject(this) + oos.flush() + baos.toByteArray() + } + } } companion object { - private val VERSION = 1L + const val VERSION = 1L fun decode(encoded: ByteArray): DeferredState { - TODO() + return ByteArrayInputStream(encoded).use { bais -> + ObjectInputStream(bais).use { ois -> + val obj = ois.readObject() + if (obj is DeferredState) obj + else throw IllegalArgumentException("Invalid object type") + } + } } - } } \ No newline at end of file diff --git a/wallet-core/src/test/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredStateTest.kt b/wallet-core/src/test/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredStateTest.kt index 0788d48c..c485015d 100644 --- a/wallet-core/src/test/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredStateTest.kt +++ b/wallet-core/src/test/java/eu/europa/ec/eudi/wallet/issue/openid4vci/DeferredStateTest.kt @@ -16,6 +16,95 @@ package eu.europa.ec.eudi.wallet.issue.openid4vci +import com.nimbusds.jose.JWSAlgorithm +import eu.europa.ec.eudi.openid4vci.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.net.URI +import java.time.Instant +import java.util.* + class DeferredStateTest { + @Test + fun `test encode and decode methods`() { + val deferredCredential = IssuedCredential.Deferred( + transactionId = TransactionId("transactionId"), + ) + val credentialIdentifiers = mapOf( + CredentialConfigurationIdentifier("credentialConfigurationId") to listOf( + CredentialIdentifier("credentialId") + ) + ) + val authorizedRequest = AuthorizedRequest.ProofRequired( + accessToken = AccessToken(accessToken = "accessToken", expiresInSec = 3600, useDPoP = false), + refreshToken = RefreshToken("refreshToken", expiresInSec = 3600), + cNonce = CNonce(value = "cNonce"), + credentialIdentifiers = credentialIdentifiers, + timestamp = Instant.now() + ) + + val credentialIssuerMetadata = CredentialIssuerMetadata( + credentialIssuerIdentifier = CredentialIssuerId("https://localhost:8080").getOrThrow(), + authorizationServers = listOf(HttpsUrl("https://localhost:8080").getOrThrow()), + credentialEndpoint = CredentialIssuerEndpoint("https://localhost:8080").getOrThrow(), + batchCredentialEndpoint = CredentialIssuerEndpoint("https://localhost:8080").getOrThrow(), + deferredCredentialEndpoint = CredentialIssuerEndpoint("https://localhost:8080").getOrThrow(), + notificationEndpoint = CredentialIssuerEndpoint("https://localhost:8080").getOrThrow(), + credentialResponseEncryption = CredentialResponseEncryption.NotSupported, + credentialIdentifiersSupported = true, + credentialConfigurationsSupported = mapOf( + CredentialConfigurationIdentifier("credentialConfigurationId") to MsoMdocCredential( + credentialSigningAlgorithmsSupported = listOf("alg"), + isoCredentialSigningAlgorithmsSupported = listOf(CoseAlgorithm.ES256), + isoCredentialCurvesSupported = listOf(CoseCurve.P_256), + proofTypesSupported = ProofTypesSupported( + setOf( + ProofTypeMeta.Jwt(listOf(JWSAlgorithm.ES256)), + ProofTypeMeta.Cwt(listOf(CoseAlgorithm.ES256), listOf(CoseCurve.P_256)) + ) + ), + display = listOf( + Display( + name = "name", + locale = Locale.US, + logo = Display.Logo(URI("http://localhost:8080"), "image/png"), + textColor = "#444444" + ) + ), + claims = mapOf( + "namespace" to mapOf( + "claim" to Claim( + true, "claim", listOf( + Claim.Display("name", Locale.US) + ) + ) + ) + ), + order = listOf("claim"), + docType = "docType", + isoPolicy = MsoMdocPolicy(true, 10), + scope = "scope", + cryptographicBindingMethodsSupported = listOf(CryptographicBindingMethod.JWK), + ) + ), + display = listOf( + CredentialIssuerMetadata.Display(name = "name", locale = "el_GR") + ), + ) + val state = DeferredState( + clientId = "clientId", + tokenEndpoint = URI("http://localhost:8080"), + credentialIssuerMetadata = credentialIssuerMetadata, + authorizedRequest = authorizedRequest, + deferredCredential = deferredCredential + ) + + val encoded = state.encode() + + val decoded = DeferredState.decode(encoded) + + assertEquals(state, decoded) + + } } \ No newline at end of file