Skip to content
This repository has been archived by the owner on Nov 20, 2023. It is now read-only.

Commit

Permalink
Synchronized with waltid-identity
Browse files Browse the repository at this point in the history
  • Loading branch information
waltkb committed Nov 20, 2023
1 parent fe59220 commit 1fdc64c
Show file tree
Hide file tree
Showing 29 changed files with 683 additions and 576 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package id.walt
package id.walt.oid4vc

object Values {
const val version = "1.SNAPSHOT"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package id.walt.oid4vc.data

import id.walt.oid4vc.definitions.OPENID_CREDENTIAL_AUTHORIZATION_TYPE
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
Expand All @@ -26,7 +23,7 @@ import kotlinx.serialization.json.jsonObject
* @param credentialDefinition REQUIRED (W3C ldp_vc, jwt_vc_json-ld credential formats). JSON object containing (and isolating) the detailed description of the credential type. This object MUST be processed using full JSON-LD processing.
*/
@Serializable
data class AuthorizationDetails(
data class AuthorizationDetails @OptIn(ExperimentalSerializationApi::class) constructor(
@EncodeDefault val type: String = OPENID_CREDENTIAL_AUTHORIZATION_TYPE,
val format: CredentialFormat? = null,
val types: List<String>? = null,
Expand Down
2 changes: 2 additions & 0 deletions src/commonMain/kotlin/id/walt/oid4vc/data/CredentialFormat.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package id.walt.oid4vc.data

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
Expand All @@ -25,6 +26,7 @@ enum class CredentialFormat(val value: String) {
}
}

@OptIn(ExperimentalSerializationApi::class)
@Serializer(CredentialFormat::class)
object CredentialFormatSerializer : KSerializer<CredentialFormat> {
override fun serialize(encoder: Encoder, value: CredentialFormat) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@ import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonTransformingSerializer
import kotlinx.serialization.json.jsonPrimitive
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

object DurationInSecondsSerializer: KSerializer<Duration> {
override val descriptor: SerialDescriptor
get() = Duration.serializer().descriptor
object DurationInSecondsSerializer : KSerializer<Duration> {
override val descriptor: SerialDescriptor
get() = Duration.serializer().descriptor

override fun deserialize(decoder: Decoder): Duration {
return decoder.decodeLong().seconds
}
override fun deserialize(decoder: Decoder): Duration {
return decoder.decodeLong().seconds
}

override fun serialize(encoder: Encoder, value: Duration) {
encoder.encodeLong(value.inWholeSeconds)
}
override fun serialize(encoder: Encoder, value: Duration) {
encoder.encodeLong(value.inWholeSeconds)
}

}
}
2 changes: 2 additions & 0 deletions src/commonMain/kotlin/id/walt/oid4vc/data/GrantType.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package id.walt.oid4vc.data

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
Expand All @@ -21,6 +22,7 @@ enum class GrantType(val value: String) {
}
}

@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = GrantType::class)
object GrantTypeSerializer : KSerializer<GrantType> {
override fun serialize(encoder: Encoder, value: GrantType) {
Expand Down
3 changes: 3 additions & 0 deletions src/commonMain/kotlin/id/walt/oid4vc/data/JsonDataObject.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package id.walt.oid4vc.data

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.elementNames
Expand All @@ -21,6 +22,8 @@ abstract class JsonDataObjectSerializer<T : JsonDataObject>(serializer: KSeriali
JsonTransformingSerializer<T>(serializer) {

private val customParametersName = "customParameters"

@OptIn(ExperimentalSerializationApi::class)
private val knownElementNames get() = descriptor.elementNames.filter { it != customParametersName }.toSet()

open fun serializeKnownElement(name: String, element: JsonElement, builderMap: MutableMap<String, JsonElement>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package id.walt.oid4vc.data
import id.walt.oid4vc.*
import id.walt.oid4vc.definitions.*
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
Expand Down Expand Up @@ -59,7 +60,7 @@ import kotlinx.serialization.json.jsonObject
* @param opTosUri OPTIONAL. URL that the OpenID Provider provides to the person registering the Client to read about OpenID Provider's terms of service. The registration process SHOULD display this URL to the person registering the Client if it is given.
*/
@Serializable
data class OpenIDProviderMetadata(
data class OpenIDProviderMetadata @OptIn(ExperimentalSerializationApi::class) constructor(
@SerialName("issuer") val issuer: String? = null,
@SerialName("authorization_endpoint") val authorizationEndpoint: String? = null,
@SerialName("pushed_authorization_request_endpoint") val pushedAuthorizationRequestEndpoint: String? = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package id.walt.oid4vc.data

import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
Expand All @@ -9,7 +10,7 @@ import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject

@Serializable
data class ProofOfPossession(
data class ProofOfPossession @OptIn(ExperimentalSerializationApi::class) constructor(
@EncodeDefault @SerialName("proof_type") val proofType: ProofType = ProofType.jwt,
val jwt: String?,
override val customParameters: Map<String, JsonElement> = mapOf()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import id.walt.oid4vc.data.JsonDataObjectFactory
import id.walt.oid4vc.data.JsonDataObjectSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.*

@Serializable
data class PresentationDefinition(
Expand All @@ -22,11 +19,85 @@ data class PresentationDefinition(
) : JsonDataObject() {
override fun toJSON() = Json.encodeToJsonElement(PresentationDefinitionSerializer, this).jsonObject


/**
* https://identity.foundation/presentation-exchange/spec/v1.0.0/#input-descriptor
*/
// FIXME: proper PresentationDefinition checker
fun primitiveVerificationGetTypeList(): List<String> {
val fields = inputDescriptors.mapNotNull { it.constraints?.fields }.flatten()
.filter { field -> field.path.any { "type" in it } && field.filter?.get("type")?.jsonPrimitive?.contentOrNull == "string" }

val types = fields.mapNotNull { it.filter?.get("pattern")?.jsonPrimitive?.contentOrNull }

return types
}

companion object : JsonDataObjectFactory<PresentationDefinition>() {
override fun fromJSON(jsonObject: JsonObject) =
Json.decodeFromJsonElement(PresentationDefinitionSerializer, jsonObject)

fun primitiveGenerationFromVcTypes(types: List<String>): PresentationDefinition {
return PresentationDefinition(inputDescriptors = types.map { type ->
InputDescriptor(
id = type,
format = mapOf(VCFormat.jwt_vc_json to VCFormatDefinition(alg = setOf("EdDSA"))),
constraints = InputDescriptorConstraints(
listOf(
InputDescriptorField(
path = listOf("$.type"), filter = JsonObject(
mapOf(
"type" to JsonPrimitive("string"), "pattern" to JsonPrimitive(type)
)
)
)
)
)
)
})
}


}
}

object PresentationDefinitionSerializer :
JsonDataObjectSerializer<PresentationDefinition>(PresentationDefinition.serializer())

fun main() {
//language=json
val presDef = Json.parseToJsonElement(
"""
{
"id": "\u003cautomatically assigned\u003e",
"input_descriptors": [
{
"id": "VerifiableId",
"format": {
"jwt_vc_json": {
"alg": [
"EdDSA"
]
}
},
"constraints": {
"fields": [
{
"path": [
"${'$'}.type"
],
"filter": {
"type": "string",
"pattern": "VerifiableId"
}
}
]
}
}
]
}
""".trimIndent()
)

println(Json.decodeFromJsonElement<PresentationDefinition>(presDef).primitiveVerificationGetTypeList())
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package id.walt.oid4vc.errors

import id.walt.oid4vc.requests.AuthorizationRequest
import id.walt.oid4vc.requests.IAuthorizationRequest
import id.walt.oid4vc.responses.AuthorizationCodeResponse
import id.walt.oid4vc.responses.AuthorizationErrorCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import id.walt.oid4vc.responses.CredentialResponse
import kotlin.time.Duration

class CredentialError(
credentialRequest: CredentialRequest?, val errorCode: CredentialErrorCode,
credentialRequest: CredentialRequest?,
val errorCode: CredentialErrorCode,
val errorUri: String? = null, val cNonce: String? = null, val cNonceExpiresIn: Duration? = null,
override val message: String? = null
) : Exception() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package id.walt.oid4vc.errors

import id.walt.oid4vc.data.CredentialOffer
import id.walt.oid4vc.requests.CredentialOfferRequest
import id.walt.oid4vc.requests.TokenRequest
import id.walt.oid4vc.responses.TokenErrorCode

class CredentialOfferError(
val credentialOfferRequest: CredentialOfferRequest?, val credentialOffer: CredentialOffer?, val errorCode: CredentialOfferErrorCode, override val message: String? = null
): Exception() {
}
val credentialOfferRequest: CredentialOfferRequest?,
val credentialOffer: CredentialOffer?,
val errorCode: CredentialOfferErrorCode,
override val message: String? = null
) : Exception()

enum class CredentialOfferErrorCode {
invalid_request,
invalid_issuer
}
invalid_request,
invalid_issuer
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package id.walt.oid4vc.errors

import id.walt.oid4vc.data.dif.PresentationDefinition
import id.walt.oid4vc.requests.TokenRequest
import id.walt.oid4vc.responses.AuthorizationErrorCode
import id.walt.oid4vc.responses.TokenErrorCode

class PresentationError(
Expand Down
19 changes: 9 additions & 10 deletions src/commonMain/kotlin/id/walt/oid4vc/interfaces/IHttpClient.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package id.walt.oid4vc.interfaces

import io.ktor.http.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject

data class SimpleHttpResponse (
val status: HttpStatusCode,
val headers: Headers,
val body: String?
data class SimpleHttpResponse(
val status: HttpStatusCode,
val headers: Headers,
val body: String?
)

interface IHttpClient {
fun httpGet(url: Url, headers: Headers? = null): SimpleHttpResponse
fun httpPostObject(url: Url, jsonObject: JsonObject, headers: Headers? = null): SimpleHttpResponse
fun httpSubmitForm(url: Url, formParameters: Parameters, headers: Headers? = null): SimpleHttpResponse
}
fun httpGet(url: Url, headers: Headers? = null): SimpleHttpResponse
fun httpPostObject(url: Url, jsonObject: JsonObject, headers: Headers? = null): SimpleHttpResponse
fun httpSubmitForm(url: Url, formParameters: Parameters, headers: Headers? = null): SimpleHttpResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import id.walt.oid4vc.providers.SIOPSession
import id.walt.oid4vc.requests.TokenRequest
import kotlinx.serialization.json.JsonElement

interface IVPTokenProvider<S: SIOPSession> {
interface IVPTokenProvider<S : SIOPSession> {

/**
* Generates and signs the verifiable presentation as requested in the presentation definition for the vp_token response of the given TokenRequest.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,14 @@ abstract class OpenIDCredentialIssuer(
* Override, to use custom path, by default, the path will be: "$baseUrl/credential_offer/<session_id>, e.g.: "https://issuer.myhost.com/api/credential_offer/1234-4567-8900"
* @param issuanceSession The issuance session for which the credential offer uri is created
*/
open protected fun getCredentialOfferByReferenceUri(issuanceSession: IssuanceSession): String {
protected open fun getCredentialOfferByReferenceUri(issuanceSession: IssuanceSession): String {
return URLBuilder(baseUrl).appendPathSegments("credential_offer", issuanceSession.id).buildString()
}

open fun getCredentialOfferRequest(
issuanceSession: IssuanceSession, byReference: Boolean = false
): CredentialOfferRequest {
return if(byReference) {
return if (byReference) {
CredentialOfferRequest(null, getCredentialOfferByReferenceUri(issuanceSession))
} else {
CredentialOfferRequest(issuanceSession.credentialOffer)
Expand Down
Loading

0 comments on commit 1fdc64c

Please sign in to comment.