From 329bbc25a3c2eda7ea4b0a5b2f32aaca578de29a Mon Sep 17 00:00:00 2001 From: waltkb <68587968+waltkb@users.noreply.github.com> Date: Wed, 22 Nov 2023 16:13:12 +0100 Subject: [PATCH] Add disclosure selection and map VPSession attributes outside of openid4vc lib for now --- .../id/walt/service/SSIKit2WalletService.kt | 8 +- .../id/walt/service/SessionAttributes.kt | 10 +++ .../id/walt/service/WalletKitWalletService.kt | 2 +- .../kotlin/id/walt/service/WalletService.kt | 2 +- .../service/oidc4vc/TestCredentialWallet.kt | 10 ++- .../web/controllers/ExchangeController.kt | 2 +- web/src/composables/disclosures.ts | 6 +- .../[wallet]/credentials/[credentialId].vue | 4 +- .../wallet/[wallet]/exchange/presentation.vue | 89 ++++++++++++++----- 9 files changed, 104 insertions(+), 29 deletions(-) create mode 100644 src/main/kotlin/id/walt/service/SessionAttributes.kt diff --git a/src/main/kotlin/id/walt/service/SSIKit2WalletService.kt b/src/main/kotlin/id/walt/service/SSIKit2WalletService.kt index 7150d67..78b0b24 100644 --- a/src/main/kotlin/id/walt/service/SSIKit2WalletService.kt +++ b/src/main/kotlin/id/walt/service/SSIKit2WalletService.kt @@ -178,10 +178,12 @@ class SSIKit2WalletService(accountId: UUID, walletId: UUID) : WalletService(acco ) : IllegalArgumentException(message) + + /** * @return redirect uri */ - override suspend fun usePresentationRequest(request: String, did: String, selectedCredentialIds: List): Result { + override suspend fun usePresentationRequest(request: String, did: String, selectedCredentialIds: List, disclosures: Map>): Result { val credentialWallet = getCredentialWallet(did) val authReq = AuthorizationRequest.fromHttpQueryString(Url(request).encodedQuery) @@ -189,7 +191,11 @@ class SSIKit2WalletService(accountId: UUID, walletId: UUID) : WalletService(acco println("USING PRESENTATION REQUEST, SELECTED CREDENTIALS: $selectedCredentialIds") + SessionAttributes.HACK_outsideMappedSelectedCredentialsPerSession[authReq.state + authReq.presentationDefinition] = selectedCredentialIds + SessionAttributes.HACK_outsideMappedSelectedDisclosuresPerSession[authReq.state + authReq.presentationDefinition] = disclosures + val presentationSession = credentialWallet.initializeAuthorization(authReq, 60.seconds, selectedCredentialIds.toSet()) + println("Initialized authorization (VPPresentationSession): $presentationSession") println("Resolved presentation definition: ${presentationSession.authorizationRequest!!.presentationDefinition!!.toJSONString()}") diff --git a/src/main/kotlin/id/walt/service/SessionAttributes.kt b/src/main/kotlin/id/walt/service/SessionAttributes.kt new file mode 100644 index 0000000..d5ab206 --- /dev/null +++ b/src/main/kotlin/id/walt/service/SessionAttributes.kt @@ -0,0 +1,10 @@ +package id.walt.service + +object SessionAttributes { + + // TODO FIXME: openid4vc lib drops VPresentationSession attributes + val HACK_outsideMappedSelectedCredentialsPerSession = HashMap>() + // TODO FIXME: openid4vc lib drops VPresentationSession attributes + val HACK_outsideMappedSelectedDisclosuresPerSession = HashMap>>() + +} diff --git a/src/main/kotlin/id/walt/service/WalletKitWalletService.kt b/src/main/kotlin/id/walt/service/WalletKitWalletService.kt index ba22ba7..8813ecd 100644 --- a/src/main/kotlin/id/walt/service/WalletKitWalletService.kt +++ b/src/main/kotlin/id/walt/service/WalletKitWalletService.kt @@ -200,7 +200,7 @@ class WalletKitWalletService(accountId: UUID, walletId: UUID) : WalletService(ac val state: String? ) - override suspend fun usePresentationRequest(request: String, did: String, selectedCredentialIds: List): Result { + override suspend fun usePresentationRequest(request: String, did: String, selectedCredentialIds: List, disclosures: Map>): Result { val decoded = URLDecoder.decode(request, Charset.defaultCharset()) val queryParams = getQueryParams(decoded) val redirectUri = queryParams["redirect_uri"]?.first() diff --git a/src/main/kotlin/id/walt/service/WalletService.kt b/src/main/kotlin/id/walt/service/WalletService.kt index 499431b..b2b8db4 100644 --- a/src/main/kotlin/id/walt/service/WalletService.kt +++ b/src/main/kotlin/id/walt/service/WalletService.kt @@ -22,7 +22,7 @@ abstract class WalletService(val accountId: UUID, val walletId: UUID) { abstract fun matchCredentialsByPresentationDefinition(presentationDefinition: PresentationDefinition): List // SIOP - abstract suspend fun usePresentationRequest(request: String, did: String, selectedCredentialIds: List): Result + abstract suspend fun usePresentationRequest(request: String, did: String, selectedCredentialIds: List, disclosures: Map>): Result abstract suspend fun resolvePresentationRequest(request: String): String abstract suspend fun useOfferRequest(offer: String, did: String) diff --git a/src/main/kotlin/id/walt/service/oidc4vc/TestCredentialWallet.kt b/src/main/kotlin/id/walt/service/oidc4vc/TestCredentialWallet.kt index c6dfcee..1f4ed8a 100644 --- a/src/main/kotlin/id/walt/service/oidc4vc/TestCredentialWallet.kt +++ b/src/main/kotlin/id/walt/service/oidc4vc/TestCredentialWallet.kt @@ -17,6 +17,8 @@ import id.walt.oid4vc.providers.TokenTarget import id.walt.oid4vc.requests.AuthorizationRequest import id.walt.oid4vc.requests.TokenRequest import id.walt.service.SSIKit2WalletService +import id.walt.service.SessionAttributes.HACK_outsideMappedSelectedCredentialsPerSession +import id.walt.service.SessionAttributes.HACK_outsideMappedSelectedDisclosuresPerSession import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.engine.cio.* @@ -105,9 +107,13 @@ class TestCredentialWallet( override fun generatePresentationForVPToken(session: VPresentationSession, tokenRequest: TokenRequest): PresentationResult { println("=== GENERATING PRESENTATION FOR VP TOKEN - Session: $session") - val selectedCredential = session.selectedCredentialIds.toList() - val matchedCredentials = walletService.getCredentialsByIds(selectedCredential) + val selectedCredentials = + HACK_outsideMappedSelectedCredentialsPerSession[session.authorizationRequest!!.state + session.authorizationRequest.presentationDefinition]!! + val selectedDisclosures = + HACK_outsideMappedSelectedDisclosuresPerSession[session.authorizationRequest!!.state + session.authorizationRequest.presentationDefinition]!! + + val matchedCredentials = walletService.getCredentialsByIds(selectedCredentials) val vp = Json.encodeToString( mapOf( diff --git a/src/main/kotlin/id/walt/web/controllers/ExchangeController.kt b/src/main/kotlin/id/walt/web/controllers/ExchangeController.kt index 9228c41..715bd22 100644 --- a/src/main/kotlin/id/walt/web/controllers/ExchangeController.kt +++ b/src/main/kotlin/id/walt/web/controllers/ExchangeController.kt @@ -108,7 +108,7 @@ fun Application.exchange() = walletRoute { // TODO -> ?: auto matching - val result = wallet.usePresentationRequest(request, did, selectedCredentialIds) + val result = wallet.usePresentationRequest(request, did, selectedCredentialIds, emptyMap()) // TODO add disclosures here if (result.isSuccess) { wallet.addOperationHistory( diff --git a/web/src/composables/disclosures.ts b/web/src/composables/disclosures.ts index b1a2fbd..c47fe93 100644 --- a/web/src/composables/disclosures.ts +++ b/web/src/composables/disclosures.ts @@ -1,4 +1,4 @@ -import { decodeBase64ToUtf8 } from "~/composables/base64"; +import { decodeBase64ToUtf8, encodeUtf8ToBase64 } from "~/composables/base64"; export function parseDisclosures(disclosureString: string) { try { @@ -8,3 +8,7 @@ export function parseDisclosures(disclosureString: string) { return []; } } + +export function encodeDisclosure(disclosure: any[]): string { + return encodeUtf8ToBase64(JSON.stringify(disclosure)) +} diff --git a/web/src/pages/wallet/[wallet]/credentials/[credentialId].vue b/web/src/pages/wallet/[wallet]/credentials/[credentialId].vue index 6624044..07d13b1 100644 --- a/web/src/pages/wallet/[wallet]/credentials/[credentialId].vue +++ b/web/src/pages/wallet/[wallet]/credentials/[credentialId].vue @@ -220,14 +220,14 @@

-
Selectively disclosure-able attributes
+
Selectively disclosable attributes
  • Attribute "{{ disclosure[1] }}"
    {{ disclosure[2] }}
-
No disclosure-able attributes!
+
No disclosable attributes!

diff --git a/web/src/pages/wallet/[wallet]/exchange/presentation.vue b/web/src/pages/wallet/[wallet]/exchange/presentation.vue index b5c4d45..aa14dac 100644 --- a/web/src/pages/wallet/[wallet]/exchange/presentation.vue +++ b/web/src/pages/wallet/[wallet]/exchange/presentation.vue @@ -60,33 +60,68 @@ >
-
@@ -207,6 +242,20 @@ const selectedCredentialIds = computed(() => { return _selectedCredentialIds; }); +const disclosures = ref({}); + +function addDisclosure(credentialId: string, disclosure: string) { + if (disclosures.value[credentialId] === undefined) { + disclosures.value[credentialId] = [] + } + + disclosures.value[credentialId].push(disclosure) +} + +function removeDisclosure(credentialId: string, disclosure: string) { + disclosures.value[credentialId] = disclosures.value[credentialId].filter((elem) => elem[0] != disclosure[0]) +} + async function acceptPresentation() { const req = { //did: String,