diff --git a/inspector-vc/pom.xml b/inspector-vc/pom.xml
index 141cdc1..f00dd1e 100644
--- a/inspector-vc/pom.xml
+++ b/inspector-vc/pom.xml
@@ -5,7 +5,7 @@
org.1edtech
inspector
- 0.9.10
+ 0.9.11
inspector-vc
diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Assertion.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Assertion.java
index 76e75d8..9769561 100644
--- a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Assertion.java
+++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Assertion.java
@@ -148,6 +148,14 @@ public class Assertion extends Credential {
public List getValidations() {
return validationMap.get(this);
}
+ @Override
+ public Map> getContextAliases() {
+ return Collections.emptyMap();
+ }
+ @Override
+ public Map> getContextVersionPatterns() {
+ return Collections.emptyMap();
+ }
}
public enum ValueType {
diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java
index 84e1c9b..d33b3fd 100644
--- a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java
+++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/Credential.java
@@ -92,6 +92,8 @@ public abstract class Credential extends GeneratedObject {
List getAllowedTypeValues();
boolean isAllowedTypeValuesRequired();
List getContextUris();
+ Map> getContextAliases();
+ Map> getContextVersionPatterns();
String toString();
}
diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java
index 1e8efab..ce1b10a 100644
--- a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java
+++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/EndorsementInspector.java
@@ -188,8 +188,8 @@ public class EndorsementInspector extends VCInspector implements SubInspector {
//credentialSubject
probeCount++;
- accumulator.add(new CredentialSubjectProbe().run(endorsement.getJson(), ctx));
-
+ accumulator.add(new CredentialSubjectProbe("EndorsementSubject").run(endorsement.getJson(), ctx));
+
//signatures, proofs
probeCount++;
if(endorsement.getProofType() == EXTERNAL){
diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java
index 163b9ec..e616709 100644
--- a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java
+++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/OB30Inspector.java
@@ -6,6 +6,7 @@ import static org.oneedtech.inspect.core.report.ReportUtil.onProbeException;
import static org.oneedtech.inspect.util.code.Defensives.*;
import static org.oneedtech.inspect.util.json.ObjectMapperCache.Config.DEFAULT;
import static org.oneedtech.inspect.vc.Credential.CREDENTIAL_KEY;
+import static org.oneedtech.inspect.vc.VerifiableCredential.REFRESH_SERVICE_MIME_TYPES;
import static org.oneedtech.inspect.vc.VerifiableCredential.ProofType.EXTERNAL;
import static org.oneedtech.inspect.vc.payload.PayloadParser.fromJwt;
import static org.oneedtech.inspect.vc.util.JsonNodeUtil.asNodeList;
@@ -43,7 +44,9 @@ import org.oneedtech.inspect.vc.probe.CredentialSubjectProbe;
import org.oneedtech.inspect.vc.probe.ExpirationProbe;
import org.oneedtech.inspect.vc.probe.InlineJsonSchemaProbe;
import org.oneedtech.inspect.vc.probe.IssuanceProbe;
+import org.oneedtech.inspect.vc.probe.IssuerProbe;
import org.oneedtech.inspect.vc.probe.EmbeddedProofProbe;
+import org.oneedtech.inspect.vc.probe.EvidenceProbe;
import org.oneedtech.inspect.vc.probe.RevocationListProbe;
import org.oneedtech.inspect.vc.probe.ExternalProofProbe;
import org.oneedtech.inspect.vc.probe.TypePropertyProbe;
@@ -170,7 +173,17 @@ public class OB30Inspector extends VCInspector implements SubInspector {
//credentialSubject
probeCount++;
- accumulator.add(new CredentialSubjectProbe().run(ob.getJson(), ctx));
+ accumulator.add(new CredentialSubjectProbe("AchievementSubject", true).run(ob.getJson(), ctx));
+
+ // evidence
+ probeCount++;
+ accumulator.add(new EvidenceProbe().run(ob.getJson(), ctx));
+ if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
+
+ // issuer
+ probeCount++;
+ accumulator.add(new IssuerProbe().run(ob.getJson(), ctx));
+ if(broken(accumulator)) return abort(ctx, accumulator, probeCount);
//signatures, proofs
probeCount++;
@@ -188,9 +201,11 @@ public class OB30Inspector extends VCInspector implements SubInspector {
if(resource.getContext().get(REFRESHED) != TRUE) {
Optional newID = checkRefreshService(ob, ctx);
if(newID.isPresent()) {
- return this.run(
- new UriResource(new URI(newID.get()))
- .setContext(new ResourceContext(REFRESHED, TRUE)));
+ // If the refresh is not successful, continue the verification process using the original OpenBadgeCredential.
+ UriResource uriResource = new UriResource(new URI(newID.get()), null, REFRESH_SERVICE_MIME_TYPES);
+ if (uriResource.exists()) {
+ return this.run(uriResource.setContext(new ResourceContext(REFRESHED, TRUE)));
+ }
}
}
diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/VerifiableCredential.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/VerifiableCredential.java
index 2b29f9f..ae7daab 100644
--- a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/VerifiableCredential.java
+++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/VerifiableCredential.java
@@ -9,10 +9,10 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
import org.oneedtech.inspect.schema.Catalog;
import org.oneedtech.inspect.schema.SchemaKey;
+import org.oneedtech.inspect.util.resource.MimeType;
import org.oneedtech.inspect.util.resource.Resource;
import org.oneedtech.inspect.vc.util.JsonNodeUtil;
@@ -53,17 +53,24 @@ public class VerifiableCredential extends Credential {
private static final Map, List> contextMap = new ImmutableMap.Builder, List>()
.put(Set.of(Type.OpenBadgeCredential, AchievementCredential, EndorsementCredential),
List.of("https://www.w3.org/2018/credentials/v1",
- //"https://purl.imsglobal.org/spec/ob/v3p0/context.json")) //dev legacy
"https://purl.imsglobal.org/spec/ob/v3p0/context.json"))
.put(Set.of(ClrCredential),
List.of("https://www.w3.org/2018/credentials/v1",
- // "https://dc.imsglobal.org/draft/clr/v2p0/context", //dev legacy
- // "https://purl.imsglobal.org/spec/ob/v3p0/context.json")) //dev legacy
"https://purl.imsglobal.org/spec/clr/v2p0/context.json",
"https://purl.imsglobal.org/spec/ob/v3p0/context.json"))
.build();
+ private static final Map> contextAliasesMap = new ImmutableMap.Builder>()
+ .put("https://purl.imsglobal.org/spec/ob/v3p0/context.json",
+ List.of("https://purl.imsglobal.org/spec/ob/v3p0/context/ob_v3p0.jsonld"))
+ .build();
+
+ private static final Map> contextVersioningPatternMap = new ImmutableMap.Builder>()
+ .put("https://purl.imsglobal.org/spec/ob/v3p0/context.json",
+ List.of("https:\\/\\/purl\\.imsglobal\\.org\\/spec\\/ob\\/v3p0\\/context(-\\d+\\.\\d+\\.\\d+)*\\.json"))
+ .build();
+
public enum Type implements CredentialEnum {
AchievementCredential(Collections.emptyList()),
OpenBadgeCredential(List.of("OpenBadgeCredential", "AchievementCredential")), //treated as an alias of AchievementCredential
@@ -119,6 +126,14 @@ public class VerifiableCredential extends Credential {
.findFirst()
.orElseThrow(()-> new IllegalArgumentException(this.name() + " not recognized")));
}
+ @Override
+ public Map> getContextAliases() {
+ return contextAliasesMap;
+ }
+ @Override
+ public Map> getContextVersionPatterns() {
+ return contextVersioningPatternMap;
+ }
}
public enum ProofType {
@@ -145,4 +160,5 @@ public class VerifiableCredential extends Credential {
private static final String ISSUED_ON_PROPERTY_NAME = "issuanceDate";
private static final String EXPIRES_AT_PROPERTY_NAME = "expirationDate";
public static final String JWT_NODE_NAME = "vc";
+ public static final List REFRESH_SERVICE_MIME_TYPES = List.of(MimeType.JSON, MimeType.JSON_LD, MimeType.TEXT_PLAIN);
}
diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/W3CVCHolder.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/W3CVCHolder.java
new file mode 100644
index 0000000..36a3849
--- /dev/null
+++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/W3CVCHolder.java
@@ -0,0 +1,39 @@
+package org.oneedtech.inspect.vc;
+
+import java.util.List;
+
+import org.oneedtech.inspect.vc.jsonld.JsonLDObjectUtils;
+
+import com.danubetech.verifiablecredentials.VerifiableCredential;
+
+import foundation.identity.jsonld.ConfigurableDocumentLoader;
+import info.weboftrust.ldsignatures.LdProof;
+
+/**
+ * Holder for W3C's Verifiable Credential
+ */
+public class W3CVCHolder {
+ private VerifiableCredential credential;
+
+ public W3CVCHolder(VerifiableCredential credential) {
+ this.credential = credential;
+ ConfigurableDocumentLoader documentLoader = new ConfigurableDocumentLoader();
+ documentLoader.setEnableHttp(true);
+ documentLoader.setEnableHttps(true);
+ credential.setDocumentLoader(documentLoader);
+ }
+
+ /**
+ * Get the list of proofs in the credential.
+ * {@link VerifiableCredential} contains the method getLdProof(), but only works with one proof. This methods
+ * returns a list of all proofs defined in the credential.
+ * @return proofs defined in the credential
+ */
+ public List getProofs() {
+ return JsonLDObjectUtils.getListFromJsonLDObject(LdProof.class, credential);
+ }
+
+ public VerifiableCredential getCredential() {
+ return credential;
+ }
+}
diff --git a/inspector-vc/src/main/java/org/oneedtech/inspect/vc/jsonld/JsonLDObjectUtils.java b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/jsonld/JsonLDObjectUtils.java
new file mode 100644
index 0000000..398ccc2
--- /dev/null
+++ b/inspector-vc/src/main/java/org/oneedtech/inspect/vc/jsonld/JsonLDObjectUtils.java
@@ -0,0 +1,45 @@
+package org.oneedtech.inspect.vc.jsonld;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import foundation.identity.jsonld.JsonLDObject;
+
+public class JsonLDObjectUtils {
+ @SuppressWarnings("unchecked")
+ public static List getListFromJsonLDObject(Class cl, JsonLDObject jsonLdObject) {
+ String term = JsonLDObject.getDefaultJsonLDPredicate(cl);
+ List