Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove danubech dependency from credential package 1/2 #249

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package web5.sdk.credentials

import com.danubetech.verifiablecredentials.CredentialSubject
jiyoontbd marked this conversation as resolved.
Show resolved Hide resolved
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
Expand All @@ -13,6 +12,9 @@
import io.ktor.http.isSuccess
import io.ktor.serialization.jackson.jackson
import kotlinx.coroutines.runBlocking
import web5.sdk.credentials.model.BitstringStatusListEntry
import web5.sdk.credentials.model.CredentialSubject
import web5.sdk.credentials.model.VcDataModel
import web5.sdk.dids.DidResolvers
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
Expand All @@ -23,12 +25,6 @@
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream

/**
* Type alias representing the danubetech Status List 2021 Entry data model.
* This typealias simplifies the use of the [com.danubetech.verifiablecredentials.credentialstatus.StatusList2021Entry] class.
*/
public typealias StatusList2021Entry = com.danubetech.verifiablecredentials.credentialstatus.StatusList2021Entry

/**
* Status purpose of a status list credential or a credential with a credential status.
*/
Expand All @@ -47,6 +43,11 @@
*/
private const val STATUS_PURPOSE: String = "statusPurpose"

/**
* The JSON property key for a type.
*/
private const val TYPE: String = "type"

/**
* `StatusListCredential` represents a digitally verifiable status list credential according to the
* [W3C Verifiable Credentials Status List v2021](https://www.w3.org/TR/vc-status-list/).
Expand Down Expand Up @@ -104,19 +105,22 @@
throw IllegalArgumentException("issuer: $issuer not resolvable", e)
}

val claims = mapOf(STATUS_PURPOSE to statusPurpose.toString().lowercase(), ENCODED_LIST to bitString)
val credSubject = CredentialSubject.builder()
val claims = mapOf(TYPE to "StatusList2021",
STATUS_PURPOSE to statusPurpose.toString().lowercase(),
ENCODED_LIST to bitString)

val credSubject = CredentialSubject.Builder()
.id(URI.create(statusListCredentialId))
.type("StatusList2021")
.claims(claims)
.build()

val vcDataModel = VcDataModel.builder()
val vcDataModel = VcDataModel.Builder()
.id(URI.create(statusListCredentialId))
.issuer(URI.create(issuer))
.issuanceDate(Date())
.context(URI.create("https://w3id.org/vc/status-list/2021/v1"))
.type("StatusList2021Credential")
jiyoontbd marked this conversation as resolved.
Show resolved Hide resolved
.contexts(listOf(URI.create("https://www.w3.org/2018/credentials/v1"),
URI.create("https://w3id.org/vc/status-list/2021/v1")))
.type(listOf("VerifiableCredential", "BitstringStatusListCredential"))
.credentialSubject(credSubject)
.build()

Expand All @@ -141,11 +145,11 @@
credentialToValidate: VerifiableCredential,
statusListCredential: VerifiableCredential
): Boolean {
val statusListEntryValue: StatusList2021Entry =
StatusList2021Entry.fromJsonObject(credentialToValidate.vcDataModel.credentialStatus.jsonObject)
val statusListEntryValue: BitstringStatusListEntry =
BitstringStatusListEntry.fromJsonObject(credentialToValidate.vcDataModel.credentialStatus!!.toJson())

val statusListCredStatusPurpose: String? =
statusListCredential.vcDataModel.credentialSubject.jsonObject[STATUS_PURPOSE] as? String?
statusListCredential.vcDataModel.credentialSubject.toMap()[STATUS_PURPOSE] as? String?

require(statusListEntryValue.statusPurpose != null) {
"Status purpose in the credential to validate is null"
Expand All @@ -160,7 +164,7 @@
}

val compressedBitstring: String? =
statusListCredential.vcDataModel.credentialSubject.jsonObject[ENCODED_LIST] as? String?
statusListCredential.vcDataModel.credentialSubject.toMap()[ENCODED_LIST] as? String?

require(!compressedBitstring.isNullOrEmpty()) {
"Compressed bitstring is null or empty"
Expand Down Expand Up @@ -202,8 +206,8 @@
val client = httpClient ?: defaultHttpClient().also { isDefaultClient = true }

try {
val statusListEntryValue: StatusList2021Entry =
StatusList2021Entry.fromJsonObject(credentialToValidate.vcDataModel.credentialStatus.jsonObject)
val statusListEntryValue: BitstringStatusListEntry =
BitstringStatusListEntry.fromJsonObject(credentialToValidate.vcDataModel.credentialStatus!!.toJson())
val statusListCredential =
client.fetchStatusListCredential(statusListEntryValue.statusListCredential.toString())

Expand Down Expand Up @@ -260,10 +264,12 @@
for (vc in credentials) {
requireNotNull(vc.vcDataModel.credentialStatus) { "no credential status found in credential" }

val statusListEntry: StatusList2021Entry =
StatusList2021Entry.fromJsonObject(vc.vcDataModel.credentialStatus.jsonObject)
val statusListEntry: BitstringStatusListEntry =
BitstringStatusListEntry.fromJsonObject(vc.vcDataModel.credentialStatus.toJson())

require(statusListEntry.statusPurpose == statusPurpose.toString().lowercase()) { "status purpose mismatch" }
require(statusListEntry.statusPurpose == statusPurpose.toString().lowercase()) {
"status purpose mismatch"

Check warning on line 271 in credentials/src/main/kotlin/web5/sdk/credentials/StatusListCredential.kt

View check run for this annotation

Codecov / codecov/patch

credentials/src/main/kotlin/web5/sdk/credentials/StatusListCredential.kt#L271

Added line #L271 was not covered by tests
}

if (!duplicateSet.add(statusListEntry.statusListIndex)) {
throw IllegalArgumentException("duplicate entry found with index: ${statusListEntry.statusListIndex}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package web5.sdk.credentials

import com.danubetech.verifiablecredentials.CredentialSubject
import com.danubetech.verifiablecredentials.credentialstatus.CredentialStatus
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.JsonNode
Expand All @@ -13,19 +11,16 @@ import com.nfeld.jsonpathkt.extension.read
import com.nimbusds.jwt.JWTClaimsSet
import com.nimbusds.jwt.JWTParser
import com.nimbusds.jwt.SignedJWT
import web5.sdk.credentials.model.BitstringStatusListEntry
import web5.sdk.credentials.model.CredentialSubject
import web5.sdk.credentials.model.VcDataModel
import web5.sdk.credentials.util.JwtUtil
import web5.sdk.dids.Did
import java.net.URI
import java.security.SignatureException
import java.util.Date
import java.util.UUID

/**
* Type alias representing the danubetech Verifiable Credential data model.
* This typealias simplifies the use of the [com.danubetech.verifiablecredentials.VerifiableCredential] class.
*/
public typealias VcDataModel = com.danubetech.verifiablecredentials.VerifiableCredential

/**
* `VerifiableCredential` represents a digitally verifiable credential according to the
* [W3C Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/).
Expand All @@ -39,7 +34,7 @@ public typealias VcDataModel = com.danubetech.verifiablecredentials.VerifiableCr
public class VerifiableCredential internal constructor(public val vcDataModel: VcDataModel) {

public val type: String
get() = vcDataModel.types.last()
get() = vcDataModel.type.last()
public val issuer: String
get() = vcDataModel.issuer.toString()

Expand Down Expand Up @@ -123,7 +118,7 @@ public class VerifiableCredential internal constructor(public val vcDataModel: V
issuer: String,
subject: String,
data: T,
credentialStatus: CredentialStatus? = null,
credentialStatus: BitstringStatusListEntry? = null,
issuanceDate: Date = Date(),
expirationDate: Date? = null
): VerifiableCredential {
Expand All @@ -134,13 +129,14 @@ public class VerifiableCredential internal constructor(public val vcDataModel: V
false -> throw IllegalArgumentException("expected data to be parseable into a JSON object")
}

val credentialSubject = CredentialSubject.builder()
val credentialSubject = CredentialSubject.Builder()
nitro-neal marked this conversation as resolved.
Show resolved Hide resolved
.id(URI.create(subject))
.claims(mapData)
.build()

val vcDataModel = VcDataModel.builder()
.type(type)
val vcDataModel = VcDataModel.Builder()
.contexts(listOf(URI.create("https://www.w3.org/2018/credentials/v1")))
.type(listOf("VerifiableCredential", type))
.id(URI.create("urn:uuid:${UUID.randomUUID()}"))
.issuer(URI.create(issuer))
.issuanceDate(issuanceDate)
Expand All @@ -149,7 +145,12 @@ public class VerifiableCredential internal constructor(public val vcDataModel: V
.apply {
credentialStatus?.let {
credentialStatus(it)
context(URI.create("https://w3id.org/vc/status-list/2021/v1"))
contexts(
listOf(
URI.create("https://www.w3.org/2018/credentials/v1"),
URI.create("https://w3id.org/vc/status-list/2021/v1")
)
)
}
}
.build()
Expand Down
Loading
Loading