add @context value check probe

This commit is contained in:
Markus Gylling
2022-08-31 20:30:10 +02:00
parent 5e6a277185
commit bbcfac14fc
5 changed files with 122 additions and 8 deletions
@@ -30,6 +30,8 @@ import org.oneedtech.inspect.util.resource.ResourceType;
import org.oneedtech.inspect.util.resource.UriResource;
import org.oneedtech.inspect.util.resource.context.ResourceContext;
import org.oneedtech.inspect.util.spec.Specification;
import org.oneedtech.inspect.vc.Credential.Type;
import org.oneedtech.inspect.vc.probe.ContextPropertyProbe;
import org.oneedtech.inspect.vc.probe.CredentialParseProbe;
import org.oneedtech.inspect.vc.probe.ExpirationVerifierProbe;
import org.oneedtech.inspect.vc.probe.InlineJsonSchemaProbe;
@@ -89,16 +91,17 @@ public class OB30Inspector extends VCInspector {
//we expect the above to place a generated object in the context
Credential crd = ctx.getGeneratedObject(Credential.ID);
//TODO check context IRIs? the schema doesnt do this
//TODO new check: that subject @id or IdentityObject is available (at least one is the req)
//context and type properties
Credential.Type type = Type.OpenBadgeCredential;
for(Probe<JsonNode> probe : List.of(new ContextPropertyProbe(type), new TypePropertyProbe(type))) {
probeCount++;
accumulator.add(probe.run(crd.getJson(), ctx));
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
}
//type property
probeCount++;
accumulator.add(new TypePropertyProbe(OpenBadgeCredential).run(crd.getJson(), ctx));
if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
//canonical schema and inline schemata
SchemaKey schema = crd.getSchemaKey().orElseThrow();
for(Probe<JsonNode> probe : List.of(new JsonSchemaProbe(schema), new InlineJsonSchemaProbe(schema))) {
@@ -0,0 +1,63 @@
package org.oneedtech.inspect.vc.probe;
import static org.oneedtech.inspect.util.code.Defensives.checkNotNull;
import java.util.List;
import java.util.Map;
import org.oneedtech.inspect.core.probe.Probe;
import org.oneedtech.inspect.core.probe.RunContext;
import org.oneedtech.inspect.core.report.ReportItems;
import org.oneedtech.inspect.vc.Credential;
import org.oneedtech.inspect.vc.util.JsonNodeUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.collect.ImmutableMap;
/**
* A Probe that verifies a credential's context property.
*
* @author mgylling
*/
public class ContextPropertyProbe extends Probe<JsonNode> {
private final Credential.Type type;
public ContextPropertyProbe(Credential.Type type) {
super(ID);
this.type = checkNotNull(type);
}
@Override
public ReportItems run(JsonNode root, RunContext ctx) throws Exception {
ArrayNode contextNode = (ArrayNode) root.get("@context");
if (contextNode == null) {
return fatal("No @context property", ctx);
}
List<String> expected = values.get(type);
if(expected == null) {
return fatal(type.name() + " not recognized", ctx);
}
List<String> given = JsonNodeUtil.asStringList(contextNode);
int pos = 0;
for(String uri : expected) {
if((given.size() < pos+1) || !given.get(pos).equals(uri)) {
return error("missing required @context uri " + uri + " at position " + (pos+1), ctx);
}
pos++;
}
return success(ctx);
}
private final static Map<Credential.Type, List<String>> values = new ImmutableMap.Builder<Credential.Type, List<String>>()
.put(Credential.Type.OpenBadgeCredential,
List.of("https://www.w3.org/2018/credentials/v1",
"https://imsglobal.github.io/openbadges-specification/context.json")) //TODO will change (https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld)
.build();
public static final String ID = ContextPropertyProbe.class.getSimpleName();
}