clean up endorsementinspector
This commit is contained in:
parent
ef74f679fc
commit
5e6a277185
@ -1,10 +1,10 @@
|
|||||||
package org.oneedtech.inspect.vc;
|
package org.oneedtech.inspect.vc;
|
||||||
|
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
import static org.oneedtech.inspect.core.probe.RunContext.Key.*;
|
import static org.oneedtech.inspect.core.probe.RunContext.Key.*;
|
||||||
import static org.oneedtech.inspect.util.json.ObjectMapperCache.Config.DEFAULT;
|
|
||||||
import static org.oneedtech.inspect.core.report.ReportUtil.onProbeException;
|
import static org.oneedtech.inspect.core.report.ReportUtil.onProbeException;
|
||||||
|
import static org.oneedtech.inspect.util.code.Defensives.checkNotNull;
|
||||||
|
import static org.oneedtech.inspect.util.json.ObjectMapperCache.Config.DEFAULT;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -17,19 +17,17 @@ import org.oneedtech.inspect.core.probe.GeneratedObject;
|
|||||||
import org.oneedtech.inspect.core.probe.Probe;
|
import org.oneedtech.inspect.core.probe.Probe;
|
||||||
import org.oneedtech.inspect.core.probe.RunContext;
|
import org.oneedtech.inspect.core.probe.RunContext;
|
||||||
import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator;
|
import org.oneedtech.inspect.core.probe.json.JsonPathEvaluator;
|
||||||
import org.oneedtech.inspect.core.probe.json.JsonSchemaProbe;
|
|
||||||
import org.oneedtech.inspect.core.report.Report;
|
import org.oneedtech.inspect.core.report.Report;
|
||||||
import org.oneedtech.inspect.core.report.ReportItems;
|
import org.oneedtech.inspect.core.report.ReportItems;
|
||||||
import org.oneedtech.inspect.schema.SchemaKey;
|
|
||||||
import org.oneedtech.inspect.util.json.ObjectMapperCache;
|
import org.oneedtech.inspect.util.json.ObjectMapperCache;
|
||||||
import org.oneedtech.inspect.util.resource.Resource;
|
import org.oneedtech.inspect.util.resource.Resource;
|
||||||
import org.oneedtech.inspect.util.resource.UriResource;
|
import org.oneedtech.inspect.util.resource.UriResource;
|
||||||
import org.oneedtech.inspect.util.resource.context.ResourceContext;
|
import org.oneedtech.inspect.util.resource.context.ResourceContext;
|
||||||
import org.oneedtech.inspect.vc.Credential.Type;
|
import org.oneedtech.inspect.vc.Credential.Type;
|
||||||
import org.oneedtech.inspect.vc.probe.CredentialParseProbe;
|
|
||||||
import org.oneedtech.inspect.vc.probe.ExpirationVerifierProbe;
|
import org.oneedtech.inspect.vc.probe.ExpirationVerifierProbe;
|
||||||
import org.oneedtech.inspect.vc.probe.InlineJsonSchemaProbe;
|
import org.oneedtech.inspect.vc.probe.InlineJsonSchemaProbe;
|
||||||
import org.oneedtech.inspect.vc.probe.IssuanceVerifierProbe;
|
import org.oneedtech.inspect.vc.probe.IssuanceVerifierProbe;
|
||||||
|
import org.oneedtech.inspect.vc.probe.ProofVerifierProbe;
|
||||||
import org.oneedtech.inspect.vc.probe.RevocationListProbe;
|
import org.oneedtech.inspect.vc.probe.RevocationListProbe;
|
||||||
import org.oneedtech.inspect.vc.probe.SignatureVerifierProbe;
|
import org.oneedtech.inspect.vc.probe.SignatureVerifierProbe;
|
||||||
import org.oneedtech.inspect.vc.probe.TypePropertyProbe;
|
import org.oneedtech.inspect.vc.probe.TypePropertyProbe;
|
||||||
@ -49,63 +47,47 @@ public class EndorsementInspector extends VCInspector implements SubInspector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Report run(Resource resource, Map<String, GeneratedObject> parentObjects) {
|
public Report run(Resource resource, Map<String, GeneratedObject> parentObjects) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The resource param is the top-level credential that embeds the endorsement, we
|
* The resource param is the top-level credential that embeds the endorsement, we
|
||||||
* expect parentObjects to provide a pointer to the JsonNode we should check
|
* expect parentObjects to provide a pointer to the JsonNode we should check.
|
||||||
|
*
|
||||||
|
* The parent inspector is responsible to decode away possible jwt-ness, so that
|
||||||
|
* what we get here is a verbatim json node.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
Credential verifiableCredential = (Credential) parentObjects.get(ENDORSEMENT_KEY);
|
|
||||||
|
|
||||||
|
Credential endorsement = (Credential) checkNotNull(parentObjects.get(ENDORSEMENT_KEY));
|
||||||
|
|
||||||
ObjectMapper mapper = ObjectMapperCache.get(DEFAULT);
|
ObjectMapper mapper = ObjectMapperCache.get(DEFAULT);
|
||||||
JsonPathEvaluator jsonPath = new JsonPathEvaluator(mapper);
|
JsonPathEvaluator jsonPath = new JsonPathEvaluator(mapper);
|
||||||
|
|
||||||
RunContext ctx = new RunContext.Builder()
|
RunContext ctx = new RunContext.Builder()
|
||||||
.put(this)
|
.put(this)
|
||||||
.put(resource)
|
|
||||||
.put(JACKSON_OBJECTMAPPER, mapper)
|
.put(JACKSON_OBJECTMAPPER, mapper)
|
||||||
.put(JSONPATH_EVALUATOR, jsonPath)
|
.put(JSONPATH_EVALUATOR, jsonPath)
|
||||||
.put(ENDORSEMENT_KEY, verifiableCredential)
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
List<ReportItems> accumulator = new ArrayList<>();
|
List<ReportItems> accumulator = new ArrayList<>();
|
||||||
int probeCount = 0;
|
int probeCount = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//detect type (png, svg, json, jwt) and extract json data
|
|
||||||
probeCount++;
|
|
||||||
accumulator.add(new CredentialParseProbe().run(resource, ctx));
|
|
||||||
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
|
||||||
|
|
||||||
//we expect the above to place a generated object in the context
|
|
||||||
Credential crd = ctx.getGeneratedObject(Credential.ID);
|
|
||||||
|
|
||||||
//type property
|
//type property
|
||||||
probeCount++;
|
probeCount++;
|
||||||
accumulator.add(new TypePropertyProbe(Type.ClrCredential).run(crd.getJson(), ctx));
|
accumulator.add(new TypePropertyProbe(Type.EndorsementCredential).run(endorsement.getJson(), ctx));
|
||||||
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
||||||
|
|
||||||
//canonical schema and inline schema
|
//inline schema (parent inspector has already validated against canonical)
|
||||||
SchemaKey schema = crd.getSchemaKey().orElseThrow();
|
accumulator.add(new InlineJsonSchemaProbe().run(endorsement.getJson(), ctx));
|
||||||
for(Probe<JsonNode> probe : List.of(new JsonSchemaProbe(schema), new InlineJsonSchemaProbe(schema))) {
|
|
||||||
probeCount++;
|
|
||||||
accumulator.add(probe.run(crd.getJson(), ctx));
|
|
||||||
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
//signatures, proofs
|
//signatures, proofs
|
||||||
probeCount++;
|
probeCount++;
|
||||||
if(crd.getJwt().isPresent()){
|
if(endorsement.getJwt().isPresent()){
|
||||||
//The credential originally contained in a JWT, validate the jwt and external proof.
|
//The credential originally contained in a JWT, validate the jwt and external proof.
|
||||||
accumulator.add(new SignatureVerifierProbe().run(crd, ctx));
|
accumulator.add(new SignatureVerifierProbe().run(endorsement, ctx));
|
||||||
} else {
|
} else {
|
||||||
//The credential not contained in a jwt, must have an internal proof.
|
//The credential not contained in a jwt, must have an internal proof.
|
||||||
//TODO: @Miles Need to fix the issuer, Same as with outer CLR
|
accumulator.add(new ProofVerifierProbe().run(endorsement, ctx));
|
||||||
//Swap -> "verificationMethod": "https://example.edu/issuers/565049#z6MkwA1498JfoCS3y4y3zggBDAosQEoCi5gsYH2PMXh1cFWK",
|
|
||||||
//To be like -> "verificationMethod": "did:key:z6MkkUD3J14nkYzn46QeuaVSnp7dF85QJKwKvJvfsjx79aXj",
|
|
||||||
//...but also work properly which old record seems not be doing...
|
|
||||||
|
|
||||||
/*
|
|
||||||
accumulator.add(new ProofVerifierProbe().run(crd, ctx));
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
||||||
@ -113,7 +95,7 @@ public class EndorsementInspector extends VCInspector implements SubInspector {
|
|||||||
//check refresh service if we are not already refreshed (check just like in external CLR)
|
//check refresh service if we are not already refreshed (check just like in external CLR)
|
||||||
probeCount++;
|
probeCount++;
|
||||||
if(resource.getContext().get(REFRESHED) != TRUE) {
|
if(resource.getContext().get(REFRESHED) != TRUE) {
|
||||||
Optional<String> newID = checkRefreshService(crd, ctx);
|
Optional<String> newID = checkRefreshService(endorsement, ctx);
|
||||||
if(newID.isPresent()) {
|
if(newID.isPresent()) {
|
||||||
//TODO resource.type
|
//TODO resource.type
|
||||||
return this.run(
|
return this.run(
|
||||||
@ -122,11 +104,11 @@ public class EndorsementInspector extends VCInspector implements SubInspector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//revocation, expiration and issuance (check just like in external CLR)
|
//revocation, expiration and issuance
|
||||||
for(Probe<Credential> probe : List.of(new RevocationListProbe(),
|
for(Probe<Credential> probe : List.of(new RevocationListProbe(),
|
||||||
new ExpirationVerifierProbe(), new IssuanceVerifierProbe())) {
|
new ExpirationVerifierProbe(), new IssuanceVerifierProbe())) {
|
||||||
probeCount++;
|
probeCount++;
|
||||||
accumulator.add(probe.run(crd, ctx));
|
accumulator.add(probe.run(endorsement, ctx));
|
||||||
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ public class OB30Inspector extends VCInspector {
|
|||||||
//embedded endorsements
|
//embedded endorsements
|
||||||
EndorsementInspector endorsementInspector = new EndorsementInspector.Builder().build();
|
EndorsementInspector endorsementInspector = new EndorsementInspector.Builder().build();
|
||||||
|
|
||||||
List<JsonNode> endorsements = asNodeList(crd.getJson(), "$..endorsement", jsonPath);
|
List<JsonNode> endorsements = asNodeList(crd.getJson(), "$..endorsement", jsonPath);
|
||||||
for(JsonNode node : endorsements) {
|
for(JsonNode node : endorsements) {
|
||||||
probeCount++;
|
probeCount++;
|
||||||
Credential endorsement = new Credential(resource, node);
|
Credential endorsement = new Credential(resource, node);
|
||||||
@ -149,7 +149,7 @@ public class OB30Inspector extends VCInspector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//embedded jwt endorsements
|
//embedded jwt endorsements
|
||||||
endorsements = asNodeList(crd.getJson(), "$..endorsementJwt", jsonPath);
|
endorsements = asNodeList(crd.getJson(), "$..endorsementJwt", jsonPath);
|
||||||
for(JsonNode node : endorsements) {
|
for(JsonNode node : endorsements) {
|
||||||
probeCount++;
|
probeCount++;
|
||||||
String jwt = node.asText();
|
String jwt = node.asText();
|
||||||
|
@ -51,7 +51,7 @@ public class ProofVerifierProbe extends Probe<Credential> {
|
|||||||
} catch (DocumentError e) {
|
} catch (DocumentError e) {
|
||||||
return error(e.getType() + " " + e.getSubject(), ctx);
|
return error(e.getType() + " " + e.getSubject(), ctx);
|
||||||
} catch (VerificationError e) {
|
} catch (VerificationError e) {
|
||||||
System.err.println(e.getCode());
|
//System.err.println(e.getCode() + " (ProofVerifierProbe)");
|
||||||
if(e.getCode() == Code.Internal) {
|
if(e.getCode() == Code.Internal) {
|
||||||
return exception(e.getMessage(), ctx.getResource());
|
return exception(e.getMessage(), ctx.getResource());
|
||||||
} else if(e.getCode().equals(Code.Expired)) {
|
} else if(e.getCode().equals(Code.Expired)) {
|
||||||
|
@ -15,49 +15,50 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Probe that verifies a credential's type property.
|
* A Probe that verifies a credential's type property.
|
||||||
|
*
|
||||||
* @author mgylling
|
* @author mgylling
|
||||||
*/
|
*/
|
||||||
public class TypePropertyProbe extends Probe<JsonNode> {
|
public class TypePropertyProbe extends Probe<JsonNode> {
|
||||||
private final Credential.Type expected;
|
private final Credential.Type expected;
|
||||||
|
|
||||||
public TypePropertyProbe(Credential.Type expected) {
|
public TypePropertyProbe(Credential.Type expected) {
|
||||||
super(ID);
|
super(ID);
|
||||||
this.expected = checkNotNull(expected);
|
this.expected = checkNotNull(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReportItems run(JsonNode root, RunContext ctx) throws Exception {
|
public ReportItems run(JsonNode root, RunContext ctx) throws Exception {
|
||||||
|
|
||||||
ArrayNode typeNode = (ArrayNode)root.get("type");
|
ArrayNode typeNode = (ArrayNode) root.get("type");
|
||||||
if(typeNode == null) return fatal("No type property", ctx);
|
if (typeNode == null)
|
||||||
|
return fatal("No type property", ctx);
|
||||||
|
|
||||||
List<String> values = JsonNodeUtil.asStringList(typeNode);
|
List<String> values = JsonNodeUtil.asStringList(typeNode);
|
||||||
|
|
||||||
if(!values.contains("VerifiableCredential")) {
|
if (!values.contains("VerifiableCredential")) {
|
||||||
return fatal("The type property does not contain the entry 'VerifiableCredential'", ctx);
|
return fatal("The type property does not contain the entry 'VerifiableCredential'", ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(expected == Credential.Type.OpenBadgeCredential) {
|
if (expected == Credential.Type.OpenBadgeCredential) {
|
||||||
if(!values.contains("OpenBadgeCredential") && !values.contains("AchievementCredential")) {
|
if (!values.contains("OpenBadgeCredential") && !values.contains("AchievementCredential")) {
|
||||||
return fatal(
|
return fatal("The type property does not contain one of 'OpenBadgeCredential' or 'AchievementCredential'", ctx);
|
||||||
"The type property does not contain one of 'OpenBadgeCredential' or 'AchievementCredential'",
|
}
|
||||||
ctx);
|
} else if (expected == Credential.Type.ClrCredential) {
|
||||||
}
|
if (!values.contains("ClrCredential")) {
|
||||||
}
|
return fatal("The type property does not contain the entry 'ClrCredential'", ctx);
|
||||||
else if(expected == Credential.Type.ClrCredential){
|
}
|
||||||
if(!values.contains("ClrCredential")) {
|
} else if (expected == Credential.Type.EndorsementCredential) {
|
||||||
return fatal(
|
if (!values.contains("EndorsementCredential")) {
|
||||||
"The type property does not contain the entry 'ClrCredential'",
|
return fatal("The type property does not contain the entry 'EndorsementCredential'", ctx);
|
||||||
ctx);
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//TODO implement
|
// TODO implement
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return success(ctx);
|
return success(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String ID = TypePropertyProbe.class.getSimpleName();
|
public static final String ID = TypePropertyProbe.class.getSimpleName();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user