-
Notifications
You must be signed in to change notification settings - Fork 10
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
Implement createPresentationFromCredentials #151
Changes from all commits
dfc5507
744dad6
5e1c646
7067c25
ee106e0
2d6eedc
74cd5e1
66e9e6f
6734551
c8380f7
61279a2
e095bc9
5dc2ca7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package web5.sdk.credentials.model | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude | ||
import com.fasterxml.jackson.annotation.JsonProperty | ||
|
||
/** | ||
* Represents a presentation submission object. | ||
* | ||
* @see [Presentation Submission](https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-submission) | ||
*/ | ||
public class PresentationSubmission( | ||
public val id: String, | ||
@JsonProperty("definition_id") | ||
public val definitionId: String, | ||
@JsonProperty("descriptor_map") | ||
public val descriptorMap: List<DescriptorMap> | ||
) | ||
|
||
/** | ||
* Represents descriptor map for a presentation submission. | ||
*/ | ||
@JsonInclude(JsonInclude.Include.NON_NULL) | ||
public class DescriptorMap( | ||
public val id: String, | ||
public val format: String, | ||
public val path: String, | ||
@JsonProperty("path_nested") | ||
public val pathNested: DescriptorMap? = null | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,10 +8,13 @@ import com.fasterxml.jackson.module.kotlin.registerKotlinModule | |
import org.junit.jupiter.api.Nested | ||
import org.junit.jupiter.api.assertDoesNotThrow | ||
import org.junit.jupiter.api.assertThrows | ||
import web5.sdk.credentials.model.PresentationDefinitionV2 | ||
import web5.sdk.crypto.InMemoryKeyManager | ||
import web5.sdk.dids.methods.key.DidKey | ||
import java.io.File | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
import kotlin.test.assertNotNull | ||
|
||
data class DateOfBirth(val dateOfBirth: String) | ||
data class Address(val address: String) | ||
|
@@ -326,4 +329,102 @@ class PresentationExchangeTest { | |
}.messageContains("Missing input descriptors: The presentation definition requires") | ||
} | ||
} | ||
|
||
@Nested | ||
inner class CreatePresentationFromCredentials { | ||
@Test | ||
fun `creates valid submission when VC satisfies tbdex PD`() { | ||
val pd = jsonMapper.readValue( | ||
readPd("src/test/resources/pd_sanctions.json"), | ||
PresentationDefinitionV2::class.java | ||
) | ||
|
||
val presentationSubmission = PresentationExchange.createPresentationFromCredentials(listOf(sanctionsVcJwt), pd) | ||
|
||
assertNotNull(presentationSubmission.id) | ||
assertEquals(pd.id, presentationSubmission.definitionId) | ||
|
||
assertEquals(1, presentationSubmission.descriptorMap.size) | ||
assertNotNull(presentationSubmission.descriptorMap[0].id) | ||
assertEquals("jwt_vc", presentationSubmission.descriptorMap[0].format) | ||
assertEquals("$.verifiableCredential[0]", presentationSubmission.descriptorMap[0].path) | ||
Comment on lines
+344
to
+350
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about asserting against a presentation submission loaded from a json file? Would be nice for test-vectors, I think. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have a test vector PR tee'd up after this, so we can hav ea clean PR that shows how to add test vector tests |
||
} | ||
|
||
@Test | ||
fun `creates valid submission when VC satisfies PD with no filter dob filed constraint and extra VC`() { | ||
val pd = jsonMapper.readValue( | ||
readPd("src/test/resources/pd_path_no_filter_dob.json"), | ||
PresentationDefinitionV2::class.java | ||
) | ||
|
||
val vc1 = VerifiableCredential.create( | ||
type = "DateOfBirth", | ||
issuer = issuerDid.uri, | ||
subject = holderDid.uri, | ||
data = DateOfBirth(dateOfBirth = "Data1") | ||
) | ||
val vcJwt1 = vc1.sign(issuerDid) | ||
|
||
val vc2 = VerifiableCredential.create( | ||
type = "Address", | ||
issuer = issuerDid.uri, | ||
subject = holderDid.uri, | ||
data = Address("abc street 123") | ||
) | ||
val vcJwt2 = vc2.sign(issuerDid) | ||
|
||
val presentationSubmission = PresentationExchange.createPresentationFromCredentials(listOf(vcJwt2, vcJwt1), pd) | ||
|
||
assertEquals(1, presentationSubmission.descriptorMap.size) | ||
assertEquals("$.verifiableCredential[1]", presentationSubmission.descriptorMap[0].path) | ||
} | ||
|
||
@Test | ||
fun `throws when VC does not satisfy sanctions requirements`() { | ||
val pd = jsonMapper.readValue( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the plan to read this from the hosted vectors in a follow up PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup we will be doing the same stuff we do here in this PR decentralized-identity/web5-js#344 |
||
readPd("src/test/resources/pd_sanctions.json"), | ||
PresentationDefinitionV2::class.java | ||
) | ||
val vc = VerifiableCredential.create( | ||
type = "StreetCred", | ||
issuer = issuerDid.uri, | ||
subject = holderDid.uri, | ||
data = StreetCredibility(localRespect = "high", legit = true) | ||
) | ||
val vcJwt = vc.sign(issuerDid) | ||
|
||
assertFailure { | ||
PresentationExchange.createPresentationFromCredentials(listOf(vcJwt), pd) | ||
}.messageContains("Missing input descriptors: The presentation definition requires") | ||
} | ||
|
||
@Test | ||
fun `creates valid submission when VC two vcs satisfy the same input descriptor`() { | ||
val pd = jsonMapper.readValue( | ||
readPd("src/test/resources/pd_path_no_filter_dob.json"), | ||
PresentationDefinitionV2::class.java | ||
) | ||
|
||
val vc1 = VerifiableCredential.create( | ||
type = "DateOfBirth", | ||
issuer = issuerDid.uri, | ||
subject = holderDid.uri, | ||
data = DateOfBirth(dateOfBirth = "11/11/2011") | ||
) | ||
val vcJwt1 = vc1.sign(issuerDid) | ||
|
||
val vc2 = VerifiableCredential.create( | ||
type = "DateOfBirth", | ||
issuer = issuerDid.uri, | ||
subject = holderDid.uri, | ||
data = DateOfBirth(dateOfBirth = "12/12/2012") | ||
) | ||
val vcJwt2 = vc2.sign(issuerDid) | ||
|
||
val presentationSubmission = PresentationExchange.createPresentationFromCredentials(listOf(vcJwt2, vcJwt1), pd) | ||
|
||
assertEquals(1, presentationSubmission.descriptorMap.size) | ||
assertEquals("$.verifiableCredential[0]", presentationSubmission.descriptorMap[0].path) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to use
Format
as the type here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the input to the function is vcJwts: Iterable, we know that he descriptor map will be jwt_vc mapping