-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change: Move DCQL primitives to oidc module
- Loading branch information
1 parent
75667d4
commit 1a007d9
Showing
52 changed files
with
1,001 additions
and
1,263 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
...id-data-classes/src/commonMain/kotlin/at/asitplus/openid/dcql/DCQLClaimQueryIdentifier.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package at.asitplus.openid.dcql | ||
|
||
import kotlinx.serialization.Serializable | ||
import kotlin.jvm.JvmInline | ||
|
||
/** | ||
* A string identifying the particular claim. The value MUST be a non-empty string consisting of | ||
* alphanumeric, underscore (_) or hyphen (-) characters. Within the particular claims array, the | ||
* same id MUST NOT be present more than once. | ||
*/ | ||
@Serializable | ||
@JvmInline | ||
value class DCQLClaimQueryIdentifier(val string: String) { | ||
init { | ||
validate() | ||
} | ||
|
||
private fun validate() { | ||
if(string.isEmpty()) { | ||
throw IllegalArgumentException("Value must not be the empty string.") | ||
} | ||
string.forEach { | ||
if(it != '_' && it != '-' && !it.isLetterOrDigit()) { | ||
throw IllegalArgumentException("Value must only consist of alphanumeric, underscore (_) or hyphen (-) characters.") | ||
} | ||
} | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
openid-data-classes/src/commonMain/kotlin/at/asitplus/openid/dcql/DCQLClaimsPathPointer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package at.asitplus.openid.dcql | ||
|
||
import at.asitplus.catching | ||
import at.asitplus.jsonpath.core.NodeList | ||
import at.asitplus.jsonpath.core.NodeListEntry | ||
import at.asitplus.jsonpath.core.NormalizedJsonPath | ||
import at.asitplus.jsonpath.core.NormalizedJsonPathSegment | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.json.JsonElement | ||
import kotlinx.serialization.json.jsonArray | ||
import kotlinx.serialization.json.jsonObject | ||
import kotlin.jvm.JvmInline | ||
|
||
/** | ||
* 6.4. Claims Path Pointer | ||
* | ||
* A claims path pointer is a pointer into the JSON structure of the Verifiable Credential, | ||
* identifying one or more claims. A claims path pointer MUST be a non-empty array of strings and | ||
* non-negative integers. A string value indicates that the respective key is to be selected, a | ||
* null value indicates that all elements of the currently selected array(s) are to be selected; | ||
* and a non-negative integer indicates that the respective index in an array is to be selected. | ||
* The path is formed as follows: | ||
* Start with an empty array and repeat the following until the full path is formed. | ||
* To address a particular claim within an object, append the key (claim name) to the array. | ||
* To address an element within an array, append the index to the array (as a non-negative, 0-based | ||
* integer).To address all elements within an array, append a null value to the array. Verifiers | ||
* MUST NOT point to the same claim more than once in a single query. Wallets SHOULD ignore such | ||
* duplicate claim queries. | ||
*/ | ||
@Serializable | ||
@JvmInline | ||
value class DCQLClaimsPathPointer( | ||
val segments: List<DCQLClaimsPathPointerSegment?>, | ||
) { | ||
init { | ||
validate() | ||
} | ||
|
||
constructor(startSegment: String) : this( | ||
listOf(DCQLClaimsPathPointerSegment.DCQLClaimsPathPointerClaimSegment(startSegment)) | ||
) | ||
|
||
constructor(startSegment: UInt?) : this( | ||
listOf(startSegment?.let { | ||
DCQLClaimsPathPointerSegment.DCQLClaimsPathPointerIndexSegment(it) | ||
}) | ||
) | ||
|
||
operator fun plus(key: String) = DCQLClaimsPathPointer( | ||
segments + DCQLClaimsPathPointerSegment.DCQLClaimsPathPointerClaimSegment(key) | ||
) | ||
|
||
operator fun plus(index: UInt?) = DCQLClaimsPathPointer( | ||
segments + index?.let { | ||
DCQLClaimsPathPointerSegment.DCQLClaimsPathPointerIndexSegment(it) | ||
} | ||
) | ||
|
||
/** | ||
* 6.4.1. Processing | ||
* | ||
* In detail, the array is processed by the Wallet from left to right as follows: | ||
* Select the root element of the Credential, i.e., the top-level JSON object. | ||
* | ||
* Process the query of the claims path pointer array from left to right: | ||
* If the component is a string, select the element in the respective key in the currently | ||
* selected element(s). If any of the currently selected element(s) is not an object, abort | ||
* processing and return an error. If the key does not exist in any element currently selected, | ||
* remove that element from the selection. | ||
* | ||
* If the component is null, select all elements of the currently selected array(s). If any of | ||
* the currently selected element(s) is not an array, abort processing and return an error.If | ||
* the component is a non-negative integer, select the element at the respective index in the | ||
* currently selected array(s). If any of the currently selected element(s) is not an array, | ||
* abort processing and return an error. If the index does not exist in a selected array, | ||
* remove that array from the selection.If the set of elements currently selected is empty, | ||
* abort processing and return an error.The result of the processing is the set of elements | ||
* which is requested for presentation. | ||
*/ | ||
fun query(jsonElement: JsonElement): NodeList { | ||
var claims = listOf(NodeListEntry(NormalizedJsonPath(), jsonElement)) | ||
for(segment in segments) { | ||
claims = when(segment) { | ||
is DCQLClaimsPathPointerSegment.DCQLClaimsPathPointerClaimSegment -> claims.mapNotNull { | ||
catching { | ||
NodeListEntry( | ||
normalizedJsonPath = it.normalizedJsonPath + segment.key, | ||
value = it.value.jsonObject[segment.key]!! | ||
) | ||
}.getOrNull() | ||
} | ||
is DCQLClaimsPathPointerSegment.DCQLClaimsPathPointerIndexSegment -> claims.mapNotNull { | ||
catching { | ||
NodeListEntry( | ||
normalizedJsonPath = it.normalizedJsonPath + segment.index, | ||
value = it.value.jsonArray[segment.index.toInt()] | ||
) | ||
}.getOrNull() | ||
} | ||
null -> claims.mapNotNull { claimQueryResult -> | ||
catching { | ||
claimQueryResult.value.jsonArray.mapIndexed { index, jsonElement -> | ||
NodeListEntry( | ||
normalizedJsonPath = claimQueryResult.normalizedJsonPath + index.toUInt(), | ||
value = jsonElement | ||
) | ||
} | ||
}.getOrNull() | ||
}.flatten() | ||
} | ||
} | ||
return claims | ||
} | ||
|
||
private fun validate() { | ||
if (segments.isEmpty()) { | ||
throw IllegalArgumentException("Value must not be the empty list.") | ||
} | ||
} | ||
} | ||
|
||
private operator fun NormalizedJsonPath.plus(name: String) = NormalizedJsonPath(segments + NormalizedJsonPathSegment.NameSegment(name)) | ||
private operator fun NormalizedJsonPath.plus(index: UInt) = NormalizedJsonPath(segments + NormalizedJsonPathSegment.IndexSegment(index)) |
2 changes: 1 addition & 1 deletion
2
...d4vp/dcql/DCQLClaimsPathPointerSegment.kt → ...enid/dcql/DCQLClaimsPathPointerSegment.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...DCQLClaimsPathPointerSegmentSerializer.kt → ...DCQLClaimsPathPointerSegmentSerializer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
openid-data-classes/src/commonMain/kotlin/at/asitplus/openid/dcql/DCQLClaimsQuery.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package at.asitplus.openid.dcql | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable(with = DCQLClaimsQuerySerializer::class) | ||
interface DCQLClaimsQuery { | ||
/** | ||
* OID4VP draft 23: id: REQUIRED if claim_sets is present in the Credential Query; OPTIONAL | ||
* otherwise. A string identifying the particular claim. The value MUST be a non-empty string | ||
* consisting of alphanumeric, underscore (_) or hyphen (-) characters. Within the particular | ||
* claims array, the same id MUST NOT be present more than once. | ||
*/ | ||
val id: DCQLClaimQueryIdentifier? | ||
|
||
/** | ||
* OID4VP draft 23: values: OPTIONAL. An array of strings, integers or boolean values that | ||
* specifies the expected values of the claim. If the values property is present, the Wallet | ||
* SHOULD return the claim only if the type and value of the claim both match for at least one | ||
* of the elements in the array. Details of the processing rules are defined in Section 6.3.1.1. | ||
*/ | ||
val values: List<DCQLExpectedClaimValue>? | ||
|
||
object SerialNames { | ||
const val ID = "id" | ||
const val VALUES = "values" | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...ta-classes/src/commonMain/kotlin/at/asitplus/openid/dcql/DCQLClaimsQueryMatchingResult.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package at.asitplus.openid.dcql | ||
|
||
import at.asitplus.jsonpath.core.NodeList | ||
|
||
sealed interface DCQLClaimsQueryMatchingResult { | ||
class JsonClaimsMatchingResult( | ||
val nodeList: NodeList | ||
) : DCQLClaimsQueryMatchingResult | ||
|
||
class IsoMdocClaimsMatchingResult( | ||
val namespace: String, | ||
val claimName: String, | ||
val claimValue: Any, | ||
) : DCQLClaimsQueryMatchingResult | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
...ata-classes/src/commonMain/kotlin/at/asitplus/openid/dcql/DCQLCredentialClaimStructure.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package at.asitplus.openid.dcql | ||
|
||
import kotlinx.serialization.json.JsonElement | ||
import kotlin.jvm.JvmInline | ||
|
||
sealed interface DCQLCredentialClaimStructure { | ||
@JvmInline | ||
value class JsonBasedDCQLCredentialClaimStructure(val jsonElement: JsonElement) : DCQLCredentialClaimStructure | ||
|
||
@JvmInline | ||
value class IsoMdocDCQLCredentialClaimStructure(val namespaceClaimValueMap: Map<String, Map<String, Any?>>) : | ||
DCQLCredentialClaimStructure | ||
} |
20 changes: 20 additions & 0 deletions
20
...a-classes/src/commonMain/kotlin/at/asitplus/openid/dcql/DCQLCredentialFormatIdentifier.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package at.asitplus.openid.dcql | ||
|
||
import kotlinx.serialization.Serializable | ||
import kotlin.jvm.JvmInline | ||
|
||
@Serializable | ||
@JvmInline | ||
value class DCQLCredentialFormatIdentifier(val string: String) { | ||
companion object { | ||
val SD_JWT = DCQLCredentialFormatIdentifier(Constants.SD_JWT) | ||
val MSO_MDOC = DCQLCredentialFormatIdentifier(Constants.MSO_MDOC) | ||
val ANONCREDS = DCQLCredentialFormatIdentifier(Constants.ANONCREDS) | ||
} | ||
|
||
object Constants { | ||
val SD_JWT = "dc+sd-jwt" | ||
val MSO_MDOC = "mso_mdoc" | ||
val ANONCREDS = "ac_vc" | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
...commonMain/kotlin/at/asitplus/openid/dcql/DCQLCredentialMetadataAndValidityConstraints.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package at.asitplus.openid.dcql | ||
|
||
import kotlinx.serialization.Serializable | ||
|
||
@Serializable(with = DCQLCredentialMetadataAndValidityConstraintsSerializer::class) | ||
interface DCQLCredentialMetadataAndValidityConstraints | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.