Skip to content

Commit

Permalink
Fix select credentials and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
diehuxx committed May 15, 2024
1 parent ad10f27 commit f58dff8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 35 deletions.
23 changes: 11 additions & 12 deletions packages/web5/lib/src/pexv2/presentation_definition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:collection/collection.dart';
import 'package:convert/convert.dart';
import 'package:json_path/json_path.dart';
import 'package:json_schema/json_schema.dart';
import 'package:web5/web5.dart';

class _JsonSchema {
String schema = 'http://json-schema.org/draft-07/schema#';
Expand All @@ -21,7 +22,7 @@ class _JsonSchema {

Map<String, dynamic> toJson() {
return {
'/$schema': schema,
'\$schema': schema,
'type': type,
'properties': properties,
'required': required,
Expand Down Expand Up @@ -147,21 +148,19 @@ class InputDescriptor {

// Tokenize each vcJwt and validate it against the JSON schema
for (var vcJwt in vcJwts) {
final decoded = json.decode(vcJwt);
final decodedVcJwt = DecodedVcJwt.decode(vcJwt);
final payloadJsonString =
utf8.decode(Base64Url.decode(decodedVcJwt.jwt.parts[1]));
final payloadJson = json.decode(payloadJsonString);

final selectionCandidate = <String, dynamic>{};

for (final tokenizedPath in tokenizedPaths) {
selectionCandidate[tokenizedPath.token] ??=
JsonPath(tokenizedPath.path).read(decoded).firstOrNull;
JsonPath(tokenizedPath.path).read(payloadJson).firstOrNull?.value;
}
selectionCandidate.removeWhere((_, value) => value == null);

if (selectionCandidate.keys.length < tokenizedPaths.length) {
// Did not find values for all `field`s in the input desciptor
continue;
}

final validationResult = jsonSchema.validate(selectionCandidate);
if (validationResult.isValid) {
answer.add(vcJwt);
Expand Down Expand Up @@ -258,9 +257,9 @@ class Filter {
);

Map<String, dynamic> toJson() => {
'type': type,
'pattern': pattern,
'const': constValue,
'contains': contains?.toJson(),
if (type != null) 'type': type,
if (pattern != null) 'pattern': pattern,
if (constValue != null) 'const': constValue,
if (contains != null) 'contains': contains?.toJson(),
};
}
9 changes: 6 additions & 3 deletions packages/web5/lib/src/vc/vc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,12 @@ class VerifiableCredential {
factory VerifiableCredential.fromJson(Map<String, dynamic> json) {
final credentialSubject = json['credentialSubject'] as Map<String, dynamic>;
final subject = credentialSubject.remove('id');
final credentialSchema = (json['credentialSchema'] as List<dynamic>)
.map((e) => CredentialSchema(id: e['id'], type: e['type']))
.toList();
var credentialSchema = null as List<CredentialSchema>?;
if (json['credentialSchema'] != null) {
credentialSchema = (json['credentialSchema'] as List<dynamic>)
.map((e) => CredentialSchema(id: e['id'], type: e['type']))
.toList();
}
final context = (json['@context'] as List<dynamic>).cast<String>();
final type = (json['type'] as List<dynamic>).cast<String>();

Expand Down
52 changes: 32 additions & 20 deletions packages/web5/test/pexv2/presentation_definition_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,46 @@ class SelectCredentialTestVector {
void main() {
group('select credentials', () {
group('vectors', () {
final vectorsJson =
getJsonVectors('presentation_exchange/select_credentials.json');
late List<SelectCredentialTestVector> vectors;
setUp(() {
final vectorsJson =
getJsonVectors('presentation_exchange/select_credentials.json');
final vectorsDynamic = vectorsJson['vectors'] as List<dynamic>;

final vectors = vectorsJson['vectors']
.map((e) => SelectCredentialTestVector.fromJson(e))
.toList();
vectors = vectorsDynamic
.map((e) => SelectCredentialTestVector.fromJson(e))
.toList();
});

test('web5 test vectors', () async {
for (final vector in vectors) {
late List<String> matchingVcJwts;

for (final vector in vectors) {
test(vector.description, () async {
try {
final matchingVcJwts = vector.inputPresentationDefinition
matchingVcJwts = vector.inputPresentationDefinition
.selectCredentials(vector.inputVcJwts);

if (vector.errors == true) {
fail('Expected an error but none was thrown');
} catch (e) {
if (vector.errors != true) {
fail(
'Expected no error for vector (${vector.description}) but got: $e',
);
}
return;
}

expect(
Set.from(matchingVcJwts),
Set.from(vector.outputSelectedCredentials),
if (vector.errors == true) {
fail(
'Expected an error for vector (${vector.description}) but none was thrown ',
);
} catch (e) {
if (vector.errors == false) {
fail('Expected no error but got: $e');
}
}
});
}

expect(
Set.from(matchingVcJwts),
Set.from(vector.outputSelectedCredentials),
reason: 'Test vector (${vector.description}) has mismatched output',
);
}
});
});
});
}

0 comments on commit f58dff8

Please sign in to comment.