From e55d95c6bc89ab1c474ca3257f5d7a5ff5ec6fa6 Mon Sep 17 00:00:00 2001 From: Tamino Date: Mon, 23 Oct 2023 15:56:07 +0200 Subject: [PATCH] refactor: verifier api endpoint names + structure --- .../src/main/kotlin/id/walt/verifier/Main.kt | 1 - .../main/kotlin/id/walt/verifier/OidcApi.kt | 93 ------------------- .../kotlin/id/walt/verifier/VerifierApi.kt | 84 ++++++++++++++--- 3 files changed, 70 insertions(+), 108 deletions(-) delete mode 100644 waltid-verifier/src/main/kotlin/id/walt/verifier/OidcApi.kt diff --git a/waltid-verifier/src/main/kotlin/id/walt/verifier/Main.kt b/waltid-verifier/src/main/kotlin/id/walt/verifier/Main.kt index e08a05b3d..92651f654 100644 --- a/waltid-verifier/src/main/kotlin/id/walt/verifier/Main.kt +++ b/waltid-verifier/src/main/kotlin/id/walt/verifier/Main.kt @@ -49,6 +49,5 @@ fun Application.configurePlugins() { fun Application.module() { configurePlugins() - oidcApi() verfierApi() } diff --git a/waltid-verifier/src/main/kotlin/id/walt/verifier/OidcApi.kt b/waltid-verifier/src/main/kotlin/id/walt/verifier/OidcApi.kt deleted file mode 100644 index c4973cad9..000000000 --- a/waltid-verifier/src/main/kotlin/id/walt/verifier/OidcApi.kt +++ /dev/null @@ -1,93 +0,0 @@ -package id.walt.verifier - - -import id.walt.oid4vc.data.dif.VCFormat -import id.walt.oid4vc.responses.TokenResponse -import id.walt.verifier.oidc.OIDCVerifierService -import io.github.oshai.kotlinlogging.KotlinLogging -import io.github.smiley4.ktorswaggerui.dsl.post -import io.github.smiley4.ktorswaggerui.dsl.route -import io.ktor.http.* -import io.ktor.server.application.* -import io.ktor.server.request.* -import io.ktor.server.response.* -import io.ktor.server.routing.* -import io.ktor.util.* -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonPrimitive - -@Serializable -data class DescriptorMappingFormParam(val id: String, val format: VCFormat, val path: String) - -@Serializable -data class PresentationSubmissionFormParam( - val id: String, val definition_id: String, val descriptor_map: List -) - -@Serializable -data class TokenResponseFormParam( - val vp_token: JsonElement, - val presentation_submission: PresentationSubmissionFormParam -) - -object OidcApi { - - val logger = KotlinLogging.logger { } - - private fun Application.oidcRoute(build: Route.() -> Unit) { - routing { - // authenticate("authenticated") { - /*route("oidc", { - tags = listOf("oidc") - }) {*/ - build.invoke(this) - /*}*/ - } - //} - } - - fun Application.oidcApi() = oidcRoute { - - route("oidc", { - tags = listOf("oidc") - }) { - post("/verify/{state}", { - summary = "Verify vp_token response, for a verification request identified by the state" - description = - "Called in direct_post response mode by the SIOP provider (holder wallet) with the verifiable presentation in the vp_token and the presentation_submission parameter, describing the submitted presentation. The presentation session is identified by the given state parameter." - request { - pathParameter("state") { - description = - "State, i.e. session ID, identifying the presentation session, this response belongs to." - required = true - } - body { - mediaType(ContentType.Application.FormUrlEncoded) - example( - "simple vp_token response", TokenResponseFormParam( - JsonPrimitive("abc.def.ghi"), PresentationSubmissionFormParam( - "1", "1", listOf( - DescriptorMappingFormParam("1", VCFormat.jwt_vc_json, "$.type") - ) - ) - ) - ) - } - } - }) { - val session = call.parameters["state"]?.let { OIDCVerifierService.getSession(it) } - val tokenResponse = TokenResponse.fromHttpParameters(context.request.call.receiveParameters().toMap()) - if (session == null) { - call.respond( - HttpStatusCode.BadRequest, - "State parameter doesn't refer to an existing session, or session expired" - ) - } else if (OIDCVerifierService.verify(tokenResponse, session).verificationResult == true) { - call.respond(HttpStatusCode.OK) - } else - call.respond(HttpStatusCode.BadRequest, "Response could not be verified.") - } - } - } -} diff --git a/waltid-verifier/src/main/kotlin/id/walt/verifier/VerifierApi.kt b/waltid-verifier/src/main/kotlin/id/walt/verifier/VerifierApi.kt index 9b3820903..7700565c3 100644 --- a/waltid-verifier/src/main/kotlin/id/walt/verifier/VerifierApi.kt +++ b/waltid-verifier/src/main/kotlin/id/walt/verifier/VerifierApi.kt @@ -5,6 +5,7 @@ import id.walt.credentials.verification.models.PolicyRequest.Companion.parsePoli import id.walt.credentials.verification.policies.JwtSignaturePolicy import id.walt.oid4vc.data.ResponseMode import id.walt.oid4vc.data.dif.* +import id.walt.oid4vc.responses.TokenResponse import id.walt.verifier.oidc.OIDCVerifierService import id.walt.verifier.oidc.PresentationSessionInfo import io.github.smiley4.ktorswaggerui.dsl.get @@ -15,11 +16,40 @@ import io.ktor.server.application.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +import io.ktor.util.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.encodeToString import kotlinx.serialization.json.* +@Serializable +data class DescriptorMappingFormParam(val id: String, val format: VCFormat, val path: String) + +@Serializable +data class PresentationSubmissionFormParam( + val id: String, val definition_id: String, val descriptor_map: List +) + +@Serializable +data class TokenResponseFormParam( + val vp_token: JsonElement, + val presentation_submission: PresentationSubmissionFormParam +) + +@Serializable +data class CredentialVerificationRequest( + @SerialName("vp_policies") + val vpPolicies: List, + + @SerialName("vc_policies") + val vcPolicies: List, + + @SerialName("request_credentials") + val requestCredentials: List +) + +const val defaultAuthorizeBaseUrl = "openid4vp://authorize" + private val prettyJson = Json { prettyPrint = true } val verifiableIdPresentationDefinitionExample = JsonObject( @@ -43,27 +73,18 @@ val verifiableIdPresentationDefinitionExample = JsonObject( ) ).let { prettyJson.encodeToString(it) } -@Serializable -data class CredentialVerificationRequest( - @SerialName("vp_policies") - val vpPolicies: List, - @SerialName("vc_policies") - val vcPolicies: List, - @SerialName("request_credentials") - val requestCredentials: List -) -const val defaultAuthorizeBaseUrl = "openid4vp://authorize" + fun Application.verfierApi() { routing { - route("vp", { - tags = listOf("Verifiable Presentation sessions") + route("openid4vc", { + tags = listOf("Credential Verification") }) { - post("initOidc", { + post("verify", { summary = "Initialize OIDC presentation session" description = "Initializes an OIDC presentation session, with the given presentation definition and parameters. The URL returned can be rendered as QR code for the holder wallet to scan, or called directly on the holder if the wallet base URL is given." @@ -138,6 +159,42 @@ fun Application.verfierApi() { context.respond(authorizeBaseUrl.plus("?").plus(session.authorizationRequest!!.toHttpQueryString())) } + post("/verify/{state}", { + summary = "Verify vp_token response, for a verification request identified by the state" + description = + "Called in direct_post response mode by the SIOP provider (holder wallet) with the verifiable presentation in the vp_token and the presentation_submission parameter, describing the submitted presentation. The presentation session is identified by the given state parameter." + request { + pathParameter("state") { + description = + "State, i.e. session ID, identifying the presentation session, this response belongs to." + required = true + } + body { + mediaType(ContentType.Application.FormUrlEncoded) + example( + "simple vp_token response", TokenResponseFormParam( + JsonPrimitive("abc.def.ghi"), PresentationSubmissionFormParam( + "1", "1", listOf( + DescriptorMappingFormParam("1", VCFormat.jwt_vc_json, "$.type") + ) + ) + ) + ) + } + } + }) { + val session = call.parameters["state"]?.let { OIDCVerifierService.getSession(it) } + val tokenResponse = TokenResponse.fromHttpParameters(context.request.call.receiveParameters().toMap()) + if (session == null) { + call.respond( + HttpStatusCode.BadRequest, + "State parameter doesn't refer to an existing session, or session expired" + ) + } else if (OIDCVerifierService.verify(tokenResponse, session).verificationResult == true) { + call.respond(HttpStatusCode.OK) + } else + call.respond(HttpStatusCode.BadRequest, "Response could not be verified.") + } get("/session/{id}", { summary = "Get info about OIDC presentation session, that was previously initialized" description = @@ -184,7 +241,6 @@ fun Application.verfierApi() { call.respond(HttpStatusCode.NotFound) } } - } } }