Check required values for type attribute
				
					
				
			added attributes for required type and achievement return error instead of notRun
This commit is contained in:
		
							parent
							
								
									677e547add
								
							
						
					
					
						commit
						1fe23b7278
					
				@ -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){
 | 
			
		||||
 | 
			
		||||
@ -170,7 +170,7 @@ 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));
 | 
			
		||||
 | 
			
		||||
			//signatures, proofs
 | 
			
		||||
			probeCount++;
 | 
			
		||||
 | 
			
		||||
@ -1,21 +1,36 @@
 | 
			
		||||
package org.oneedtech.inspect.vc.probe;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
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.util.JsonNodeUtil;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ArrayNode;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Probe that checks credential subject specifics not capturable by schemata.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * @author mgylling
 | 
			
		||||
 */
 | 
			
		||||
public class CredentialSubjectProbe extends Probe<JsonNode> {
 | 
			
		||||
	
 | 
			
		||||
	public CredentialSubjectProbe() {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Required type to be present.
 | 
			
		||||
	 */
 | 
			
		||||
	private final String requiredType;
 | 
			
		||||
	private boolean achivementRequired;
 | 
			
		||||
 | 
			
		||||
	public CredentialSubjectProbe(String requiredType) {
 | 
			
		||||
		this(requiredType, false);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public CredentialSubjectProbe(String requiredType, boolean achivementRequired) {
 | 
			
		||||
		super(ID);
 | 
			
		||||
		this.requiredType = requiredType;
 | 
			
		||||
		this.achivementRequired = achivementRequired;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
@ -24,18 +39,86 @@ public class CredentialSubjectProbe extends Probe<JsonNode> {
 | 
			
		||||
		JsonNode subject = root.get("credentialSubject");
 | 
			
		||||
		if(subject == null) return notRun("no credentialSubject node found", ctx); //error reported by schema
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Check that we have either .id or .identifier populated 
 | 
			
		||||
		/**
 | 
			
		||||
		 * Check that type contains AchievementSubject
 | 
			
		||||
		 */
 | 
			
		||||
		if (!JsonNodeUtil.asStringList(subject.get("type")).contains(requiredType)) {
 | 
			
		||||
			return error("credentialSubject is not of type \"" + requiredType + "\"", ctx);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Check that we have either .id or .identifier populated
 | 
			
		||||
		 */
 | 
			
		||||
		if (idAndIdentifierEmpty(subject)) {
 | 
			
		||||
			return error("no id in credentialSubject", ctx);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * if .identifier is provider, check its type
 | 
			
		||||
		 */
 | 
			
		||||
		if (subject.hasNonNull("identifier")) {
 | 
			
		||||
			List<JsonNode> identifiers = JsonNodeUtil.asNodeList(subject.get("identifier"));
 | 
			
		||||
			for (JsonNode identifier : identifiers) {
 | 
			
		||||
				// check that type contains "IdentityObject"
 | 
			
		||||
				if (!JsonNodeUtil.asStringList(identifier.get("type")).contains("IdentityObject")) {
 | 
			
		||||
					return error("identifier in credentialSubject is not of type \"IdentityObject\"", ctx);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Check results
 | 
			
		||||
		 */
 | 
			
		||||
		if (subject.hasNonNull("result")) {
 | 
			
		||||
			List<JsonNode> results = JsonNodeUtil.asNodeList(subject.get("result"));
 | 
			
		||||
			for (JsonNode result : results) {
 | 
			
		||||
				// check that type contains "Result"
 | 
			
		||||
				if (!JsonNodeUtil.asStringList(result.get("type")).contains("Result")) {
 | 
			
		||||
					return error("result in credentialSubject is not of type \"Result\"", ctx);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Check achievement result description
 | 
			
		||||
		 */
 | 
			
		||||
		if (subject.hasNonNull("achievement")) {
 | 
			
		||||
			JsonNode achievement = subject.get("achievement");
 | 
			
		||||
			if (achievement.hasNonNull("resultDescription")) {
 | 
			
		||||
				List<JsonNode> resultDescriptions = JsonNodeUtil.asNodeList(achievement.get("resultDescription"));
 | 
			
		||||
				for (JsonNode resultDescription : resultDescriptions) {
 | 
			
		||||
					// check that type contains "ResultDescription"
 | 
			
		||||
					if (!JsonNodeUtil.asStringList(resultDescription.get("type")).contains("ResultDescription")) {
 | 
			
		||||
						return error("resultDescription in achievement of credentialSubject is not of type \"ResultDescription\"", ctx);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if (achivementRequired) {
 | 
			
		||||
			return error("missing required achievement in credentialSubject", ctx);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Check that source type contains "Profile"
 | 
			
		||||
		 */
 | 
			
		||||
		if (subject.hasNonNull("source")) {
 | 
			
		||||
			JsonNode source = subject.get("source");
 | 
			
		||||
			// check that type contains "Profile"
 | 
			
		||||
			if (!JsonNodeUtil.asStringList(source.get("type")).contains("Profile")) {
 | 
			
		||||
				return error("source in credentialSubject is not of type \"Profile\"", ctx);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return success(ctx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean idAndIdentifierEmpty(JsonNode root) {
 | 
			
		||||
		JsonNode id = root.get("id");
 | 
			
		||||
		if (id != null && id.textValue().strip().length() > 0) return success(ctx);
 | 
			
		||||
				
 | 
			
		||||
		JsonNode identifier = root.get("identifier");		
 | 
			
		||||
		if(identifier != null && identifier instanceof ArrayNode 
 | 
			
		||||
				&& ((ArrayNode)identifier).size() > 0) return success(ctx);
 | 
			
		||||
					
 | 
			
		||||
		return error("no id in credentialSubject", ctx);
 | 
			
		||||
				
 | 
			
		||||
		if (id != null && id.textValue().strip().length() > 0) return false;
 | 
			
		||||
 | 
			
		||||
		JsonNode identifier = root.get("identifier");
 | 
			
		||||
		if(identifier != null && identifier instanceof ArrayNode
 | 
			
		||||
				&& ((ArrayNode)identifier).size() > 0) return false;
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static final String ID = CredentialSubjectProbe.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,66 @@
 | 
			
		||||
package org.oneedtech.inspect.vc.probe;
 | 
			
		||||
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
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.util.resource.UriResource;
 | 
			
		||||
import org.oneedtech.inspect.vc.util.JsonNodeUtil;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
 | 
			
		||||
public class IssuerProbe extends Probe<JsonNode> {
 | 
			
		||||
    public IssuerProbe() {
 | 
			
		||||
		super(ID);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public ReportItems run(JsonNode root, RunContext ctx) throws Exception {
 | 
			
		||||
        JsonNode issuer = root.get("issuer");
 | 
			
		||||
        if(issuer == null) return error("no issuer node found", ctx);
 | 
			
		||||
 | 
			
		||||
        // check that type contains "Profile"
 | 
			
		||||
        if (!JsonNodeUtil.asStringList(issuer.get("type")).contains("Profile")) {
 | 
			
		||||
            return error("issuer is not of type \"Profile\"", ctx);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // check url is accessible
 | 
			
		||||
        if (issuer.hasNonNull("url")) {
 | 
			
		||||
            try {
 | 
			
		||||
                UriResource urlResource = new UriResource(new URI(issuer.get("url").asText().strip()));
 | 
			
		||||
                if (!urlResource.exists()) {
 | 
			
		||||
                    return warning("url \"" + issuer.get("url").asText().strip() + "\" in issuer is not accessible", ctx);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                return warning("url \"" + issuer.get("url").asText().strip() + "\" in issuer is not accessible", ctx);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // check other identifier
 | 
			
		||||
        if (issuer.hasNonNull("otherIdentifier")) {
 | 
			
		||||
			List<JsonNode> otherIdentifiers = JsonNodeUtil.asNodeList(issuer.get("otherIdentifier"));
 | 
			
		||||
			for (JsonNode otherIdentifier : otherIdentifiers) {
 | 
			
		||||
				// check that type contains "IdentityObject"
 | 
			
		||||
				if (!JsonNodeUtil.asStringList(otherIdentifier.get("type")).contains("IdentityObject")) {
 | 
			
		||||
					return error("otherIdentifier in issuer is not of type \"IdentityObject\"", ctx);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // check parent issuer
 | 
			
		||||
        if (issuer.hasNonNull("parentOrg")) {
 | 
			
		||||
			JsonNode parentOrg = issuer.get("parentOrg");
 | 
			
		||||
            // check that type contains "Profile"
 | 
			
		||||
            if (!JsonNodeUtil.asStringList(parentOrg.get("type")).contains("Profile")) {
 | 
			
		||||
                return error("parentOrg in issuer is not of type \"Profile\"", ctx);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return success(ctx);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final String ID = IssuerProbe.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -11,6 +11,7 @@ import org.oneedtech.inspect.core.probe.json.JsonSchemaProbe;
 | 
			
		||||
import org.oneedtech.inspect.core.report.Report;
 | 
			
		||||
import org.oneedtech.inspect.test.PrintHelper;
 | 
			
		||||
import org.oneedtech.inspect.vc.probe.ContextPropertyProbe;
 | 
			
		||||
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;
 | 
			
		||||
@ -20,51 +21,51 @@ import org.oneedtech.inspect.vc.probe.TypePropertyProbe;
 | 
			
		||||
import com.google.common.collect.Iterables;
 | 
			
		||||
 | 
			
		||||
public class OB30Tests {
 | 
			
		||||
	private static OB30Inspector validator; 
 | 
			
		||||
	private static OB30Inspector validator;
 | 
			
		||||
	private static boolean verbose = true;
 | 
			
		||||
	
 | 
			
		||||
	@BeforeAll 
 | 
			
		||||
	static void setup() {		
 | 
			
		||||
		validator = new OB30Inspector.Builder()				
 | 
			
		||||
				.set(Behavior.TEST_INCLUDE_SUCCESS, true)	
 | 
			
		||||
 | 
			
		||||
	@BeforeAll
 | 
			
		||||
	static void setup() {
 | 
			
		||||
		validator = new OB30Inspector.Builder()
 | 
			
		||||
				.set(Behavior.TEST_INCLUDE_SUCCESS, true)
 | 
			
		||||
				.set(Behavior.VALIDATOR_FAIL_FAST, true)
 | 
			
		||||
				.build();		
 | 
			
		||||
				.build();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonValid() {
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertValid(report);			
 | 
			
		||||
		});	
 | 
			
		||||
			assertValid(report);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleDidMethodJsonValid() {
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_DID_METHOD_JSON.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertValid(report);			
 | 
			
		||||
		});	
 | 
			
		||||
			assertValid(report);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimplePNGPlainValid() {
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.PNG.SIMPLE_JSON_PNG.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertValid(report);			
 | 
			
		||||
		});	
 | 
			
		||||
			assertValid(report);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimplePNGJWTValid() {
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.PNG.SIMPLE_JWT_PNG.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertValid(report);			
 | 
			
		||||
		});	
 | 
			
		||||
			assertValid(report);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
@ -72,17 +73,17 @@ public class OB30Tests {
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.SVG.SIMPLE_JSON_SVG.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertValid(report);			
 | 
			
		||||
		});	
 | 
			
		||||
			assertValid(report);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonSVGJWTValid() {
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.SVG.SIMPLE_JWT_SVG.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertValid(report);			
 | 
			
		||||
		});	
 | 
			
		||||
			assertValid(report);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
@ -94,9 +95,9 @@ public class OB30Tests {
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertFatalCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, TypePropertyProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidProofMethod() {
 | 
			
		||||
		// add some garbage chars to the verification method fragment
 | 
			
		||||
@ -107,9 +108,9 @@ public class OB30Tests {
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertErrorCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, EmbeddedProofProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidProofMethodNoScheme() {
 | 
			
		||||
		// The verificationMethod is not a URI (no scheme)
 | 
			
		||||
@ -119,9 +120,9 @@ public class OB30Tests {
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertErrorCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, EmbeddedProofProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidProofMethodUnknownScheme() {
 | 
			
		||||
		// The verificationMethod is not a URI (no scheme)
 | 
			
		||||
@ -131,9 +132,9 @@ public class OB30Tests {
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertErrorCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, EmbeddedProofProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidProofMethodUnknownDidMethod() {
 | 
			
		||||
		// The verificationMethod is an unknown DID Method
 | 
			
		||||
@ -143,9 +144,9 @@ public class OB30Tests {
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertErrorCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, EmbeddedProofProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidProofValue() {
 | 
			
		||||
		//add some garbage chars to proofValue
 | 
			
		||||
@ -155,9 +156,9 @@ public class OB30Tests {
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertErrorCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, EmbeddedProofProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonExpired() {
 | 
			
		||||
		//"expirationDate": "2020-01-20T00:00:00Z",
 | 
			
		||||
@ -166,20 +167,20 @@ public class OB30Tests {
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertHasProbeID(report, ExpirationProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonContextError() {	
 | 
			
		||||
	void testSimpleJsonContextError() {
 | 
			
		||||
		//removed one of the reqd context uris
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_ERR_CONTEXT.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertHasProbeID(report, ContextPropertyProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonSchemaError() throws Exception {
 | 
			
		||||
		//issuer removed
 | 
			
		||||
@ -187,10 +188,70 @@ public class OB30Tests {
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_ISSUER.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertHasProbeID(report, JsonSchemaProbe.ID, true);			
 | 
			
		||||
		});	
 | 
			
		||||
			assertHasProbeID(report, JsonSchemaProbe.ID, true);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidCredentialSubjectType() {
 | 
			
		||||
		//add a dumb value to .type and remove the ob type
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_TYPE.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			// assertFatalCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, CredentialSubjectProbe.ID, true);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidCredentialSubjectIdentifierType() {
 | 
			
		||||
		//add a dumb value to .type and remove the ob type
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_IDENTIFIER_TYPE.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			// assertFatalCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, CredentialSubjectProbe.ID, true);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidCredentialSubjectResultType() {
 | 
			
		||||
		//add a dumb value to .type and remove the ob type
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_RESULT_TYPE.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			// assertFatalCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, CredentialSubjectProbe.ID, true);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidCredentialSubjectAchievementResultDescriptionType() {
 | 
			
		||||
		//add a dumb value to .type and remove the ob type
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_ACHIEVEMENT_RESULT_DESCRIPTION_TYPE.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			// assertFatalCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, CredentialSubjectProbe.ID, true);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonInvalidCredentialSubjectProfileType() {
 | 
			
		||||
		//add a dumb value to .type and remove the ob type
 | 
			
		||||
		assertDoesNotThrow(()->{
 | 
			
		||||
			Report report = validator.run(Samples.OB30.JSON.SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_PROFILE_TYPE.asFileResource());
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			// assertFatalCount(report, 1);
 | 
			
		||||
			assertHasProbeID(report, CredentialSubjectProbe.ID, true);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Disabled //TODO IssuanceVerifierProbe is not run because FATAL: InvalidSignature terminates
 | 
			
		||||
	@Test
 | 
			
		||||
	void testSimpleJsonNotIssued() {
 | 
			
		||||
@ -201,9 +262,9 @@ public class OB30Tests {
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertInvalid(report);
 | 
			
		||||
			assertHasProbeID(report, IssuanceProbe.ID, true);
 | 
			
		||||
		});	
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testCompleteJsonInvalidInlineSchemaRef() throws Exception {
 | 
			
		||||
		//404 inline schema ref, and 404 refresh uri
 | 
			
		||||
@ -212,9 +273,9 @@ public class OB30Tests {
 | 
			
		||||
			if(verbose) PrintHelper.print(report, true);
 | 
			
		||||
			assertFalse(report.asBoolean());
 | 
			
		||||
			assertTrue(Iterables.size(report.getErrors()) > 0);
 | 
			
		||||
			assertTrue(Iterables.size(report.getExceptions()) > 0);			
 | 
			
		||||
			assertHasProbeID(report, InlineJsonSchemaProbe.ID, true);									
 | 
			
		||||
		});	
 | 
			
		||||
			assertTrue(Iterables.size(report.getExceptions()) > 0);
 | 
			
		||||
			assertHasProbeID(report, InlineJsonSchemaProbe.ID, true);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,11 @@ public class Samples {
 | 
			
		||||
			public final static Sample SIMPLE_DID_METHOD_JSON = new Sample("ob30/simple-did-method.json", true);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_NOPROOF = new Sample("ob30/simple-noproof.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_UNKNOWN_TYPE = new Sample("ob30/simple-err-type.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_TYPE = new Sample("ob30/simple-err-credential-subject-type.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_IDENTIFIER_TYPE = new Sample("ob30/simple-err-credential-subject-identifier-type.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_RESULT_TYPE = new Sample("ob30/simple-err-credential-subject-result-type.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_ACHIEVEMENT_RESULT_DESCRIPTION_TYPE = new Sample("ob30/simple-err-credential-subject-achievement-result-description-type.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_UNKNOWN_CREDENTIAL_SUBJECT_PROFILE_TYPE = new Sample("ob30/simple-err-credential-subject-profile-type.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_PROOF_METHOD_ERROR = new Sample("ob30/simple-err-proof-method.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_PROOF_METHOD_NO_SCHEME_ERROR = new Sample("ob30/simple-err-proof-method-no-scheme.json", false);
 | 
			
		||||
			public final static Sample SIMPLE_JSON_PROOF_METHOD_UNKNOWN_SCHEME_ERROR = new Sample("ob30/simple-err-proof-method-unknown-scheme.json", false);
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,188 @@
 | 
			
		||||
{
 | 
			
		||||
    "@context": [
 | 
			
		||||
        "https://www.w3.org/2018/credentials/v1",
 | 
			
		||||
        "https://purl.imsglobal.org/spec/ob/v3p0/context.json",
 | 
			
		||||
        "https://w3id.org/security/suites/ed25519-2020/v1"
 | 
			
		||||
    ],
 | 
			
		||||
    "id": "http://example.com/credentials/3527",
 | 
			
		||||
    "type": [
 | 
			
		||||
        "VerifiableCredential",
 | 
			
		||||
        "OpenBadgeCredential"
 | 
			
		||||
    ],
 | 
			
		||||
    "issuer": {
 | 
			
		||||
        "id": "https://example.com/issuers/876543",
 | 
			
		||||
        "type": [
 | 
			
		||||
            "Profile"
 | 
			
		||||
        ],
 | 
			
		||||
        "name": "Example Corp"
 | 
			
		||||
    },
 | 
			
		||||
    "issuanceDate": "2010-01-01T00:00:00Z",
 | 
			
		||||
    "name": "Teamwork Badge",
 | 
			
		||||
    "credentialSubject": {
 | 
			
		||||
        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
 | 
			
		||||
        "type": [
 | 
			
		||||
            "AchievementSubject"
 | 
			
		||||
        ],
 | 
			
		||||
        "achievement": {
 | 
			
		||||
            "id": "https://example.com/achievements/21st-century-skills/teamwork",
 | 
			
		||||
            "type": [
 | 
			
		||||
                "Achievement"
 | 
			
		||||
            ],
 | 
			
		||||
            "criteria": {
 | 
			
		||||
                "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
 | 
			
		||||
            },
 | 
			
		||||
            "description": "This badge recognizes the development of the capacity to collaborate within a group environment.",
 | 
			
		||||
            "name": "Teamwork",
 | 
			
		||||
            "resultDescription": [
 | 
			
		||||
                {
 | 
			
		||||
                    "id": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
 | 
			
		||||
                    "type": "ResultDescription",
 | 
			
		||||
                    "alignment": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "type": "Alignment",
 | 
			
		||||
                            "targetCode": "project",
 | 
			
		||||
                            "targetDescription": "Project description",
 | 
			
		||||
                            "targetName": "Final Project",
 | 
			
		||||
                            "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                            "targetType": "CFItem",
 | 
			
		||||
                            "targetUrl": "https://1edtech.edu/catalog/degree/project"
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    "allowedValue": [
 | 
			
		||||
                        "D",
 | 
			
		||||
                        "C",
 | 
			
		||||
                        "B",
 | 
			
		||||
                        "A"
 | 
			
		||||
                    ],
 | 
			
		||||
                    "name": "Final Project Grade",
 | 
			
		||||
                    "requiredValue": "C",
 | 
			
		||||
                    "resultType": "LetterGrade"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "id": "urn:uuid:a70ddc6a-4c4a-4bd8-8277-cb97c79f40c5",
 | 
			
		||||
                    "type": "ResultDescription",
 | 
			
		||||
                    "alignment": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "type": "Alignment",
 | 
			
		||||
                            "targetCode": "project",
 | 
			
		||||
                            "targetDescription": "Project description",
 | 
			
		||||
                            "targetName": "Final Project",
 | 
			
		||||
                            "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                            "targetType": "CFItem",
 | 
			
		||||
                            "targetUrl": "https://1edtech.edu/catalog/degree/project"
 | 
			
		||||
                        }
 | 
			
		||||
                    ],
 | 
			
		||||
                    "allowedValue": [
 | 
			
		||||
                        "D",
 | 
			
		||||
                        "C",
 | 
			
		||||
                        "B",
 | 
			
		||||
                        "A"
 | 
			
		||||
                    ],
 | 
			
		||||
                    "name": "Final Project Grade",
 | 
			
		||||
                    "requiredLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
 | 
			
		||||
                    "resultType": "RubricCriterionLevel",
 | 
			
		||||
                    "rubricCriterionLevel": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "id": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
 | 
			
		||||
                            "type": "RubricCriterionLevel",
 | 
			
		||||
                            "alignment": [
 | 
			
		||||
                                {
 | 
			
		||||
                                    "type": "Alignment",
 | 
			
		||||
                                    "targetCode": "project",
 | 
			
		||||
                                    "targetDescription": "Project description",
 | 
			
		||||
                                    "targetName": "Final Project",
 | 
			
		||||
                                    "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                                    "targetType": "CFRubricCriterionLevel",
 | 
			
		||||
                                    "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/mastered"
 | 
			
		||||
                                }
 | 
			
		||||
                            ],
 | 
			
		||||
                            "description": "The author demonstrated...",
 | 
			
		||||
                            "level": "Mastered",
 | 
			
		||||
                            "name": "Mastery",
 | 
			
		||||
                            "points": "4"
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                            "id": "urn:uuid:6b84b429-31ee-4dac-9d20-e5c55881f80e",
 | 
			
		||||
                            "type": "RubricCriterionLevel",
 | 
			
		||||
                            "alignment": [
 | 
			
		||||
                                {
 | 
			
		||||
                                    "type": "Alignment",
 | 
			
		||||
                                    "targetCode": "project",
 | 
			
		||||
                                    "targetDescription": "Project description",
 | 
			
		||||
                                    "targetName": "Final Project",
 | 
			
		||||
                                    "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                                    "targetType": "CFRubricCriterionLevel",
 | 
			
		||||
                                    "targetUrl": "https://1edtech.edu/catalog/degree/project/rubric/levels/basic"
 | 
			
		||||
                                }
 | 
			
		||||
                            ],
 | 
			
		||||
                            "description": "The author demonstrated...",
 | 
			
		||||
                            "level": "Basic",
 | 
			
		||||
                            "name": "Basic",
 | 
			
		||||
                            "points": "4"
 | 
			
		||||
                        }
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "id": "urn:uuid:b07c0387-f2d6-4b65-a3f4-f4e4302ea8f7",
 | 
			
		||||
                    "type": "InvalidResultDescription",
 | 
			
		||||
                    "name": "Project Status",
 | 
			
		||||
                    "resultType": "Status"
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        "result": [
 | 
			
		||||
            {
 | 
			
		||||
                "type": [
 | 
			
		||||
                    "Result"
 | 
			
		||||
                ],
 | 
			
		||||
                "alignment": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "Alignment",
 | 
			
		||||
                        "targetCode": "project",
 | 
			
		||||
                        "targetDescription": "Project description",
 | 
			
		||||
                        "targetName": "Final Project",
 | 
			
		||||
                        "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                        "targetType": "CFItem",
 | 
			
		||||
                        "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
 | 
			
		||||
                "value": "A"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "type": [
 | 
			
		||||
                    "Result"
 | 
			
		||||
                ],
 | 
			
		||||
                "achievedLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
 | 
			
		||||
                "alignment": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "Alignment",
 | 
			
		||||
                        "targetCode": "project",
 | 
			
		||||
                        "targetDescription": "Project description",
 | 
			
		||||
                        "targetName": "Final Project",
 | 
			
		||||
                        "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                        "targetType": "CFItem",
 | 
			
		||||
                        "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "type": [
 | 
			
		||||
                    "Result"
 | 
			
		||||
                ],
 | 
			
		||||
                "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
 | 
			
		||||
                "status": "Completed"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "proof": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "Ed25519Signature2020",
 | 
			
		||||
            "created": "2022-11-16T18:54:22Z",
 | 
			
		||||
            "verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv",
 | 
			
		||||
            "proofPurpose": "assertionMethod",
 | 
			
		||||
            "proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,52 @@
 | 
			
		||||
{
 | 
			
		||||
    "@context": [
 | 
			
		||||
      "https://www.w3.org/2018/credentials/v1",
 | 
			
		||||
      "https://purl.imsglobal.org/spec/ob/v3p0/context.json",
 | 
			
		||||
      "https://w3id.org/security/suites/ed25519-2020/v1"
 | 
			
		||||
    ],
 | 
			
		||||
    "id": "http://example.com/credentials/3527",
 | 
			
		||||
    "type": [
 | 
			
		||||
      "VerifiableCredential",
 | 
			
		||||
      "OpenBadgeCredential"
 | 
			
		||||
    ],
 | 
			
		||||
    "issuer": {
 | 
			
		||||
      "id": "https://example.com/issuers/876543",
 | 
			
		||||
      "type": [
 | 
			
		||||
        "Profile"
 | 
			
		||||
      ],
 | 
			
		||||
      "name": "Example Corp"
 | 
			
		||||
    },
 | 
			
		||||
    "issuanceDate": "2010-01-01T00:00:00Z",
 | 
			
		||||
    "name": "Teamwork Badge",
 | 
			
		||||
    "credentialSubject": {
 | 
			
		||||
      "identifier": [{
 | 
			
		||||
        "type": "InvalidIdentityObject",
 | 
			
		||||
        "hashed": true,
 | 
			
		||||
        "identityHash": "asdjhsadas",
 | 
			
		||||
        "identityType": "lisSourcedId"
 | 
			
		||||
      }],
 | 
			
		||||
      "type": [
 | 
			
		||||
        "AchievementSubject"
 | 
			
		||||
      ],
 | 
			
		||||
      "achievement": {
 | 
			
		||||
        "id": "https://example.com/achievements/21st-century-skills/teamwork",
 | 
			
		||||
        "type": [
 | 
			
		||||
          "Achievement"
 | 
			
		||||
        ],
 | 
			
		||||
        "criteria": {
 | 
			
		||||
          "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
 | 
			
		||||
        },
 | 
			
		||||
        "description": "This badge recognizes the development of the capacity to collaborate within a group environment.",
 | 
			
		||||
        "name": "Teamwork"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "proof": [
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Ed25519Signature2020",
 | 
			
		||||
        "created": "2022-11-16T18:54:22Z",
 | 
			
		||||
        "verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv",
 | 
			
		||||
        "proofPurpose": "assertionMethod",
 | 
			
		||||
        "proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
@ -0,0 +1,52 @@
 | 
			
		||||
{
 | 
			
		||||
    "@context": [
 | 
			
		||||
        "https://www.w3.org/2018/credentials/v1",
 | 
			
		||||
        "https://purl.imsglobal.org/spec/ob/v3p0/context.json",
 | 
			
		||||
        "https://w3id.org/security/suites/ed25519-2020/v1"
 | 
			
		||||
    ],
 | 
			
		||||
    "id": "http://example.com/credentials/3527",
 | 
			
		||||
    "type": [
 | 
			
		||||
        "VerifiableCredential",
 | 
			
		||||
        "OpenBadgeCredential"
 | 
			
		||||
    ],
 | 
			
		||||
    "issuer": {
 | 
			
		||||
        "id": "https://example.com/issuers/876543",
 | 
			
		||||
        "type": [
 | 
			
		||||
            "Profile"
 | 
			
		||||
        ],
 | 
			
		||||
        "name": "Example Corp"
 | 
			
		||||
    },
 | 
			
		||||
    "issuanceDate": "2010-01-01T00:00:00Z",
 | 
			
		||||
    "name": "Teamwork Badge",
 | 
			
		||||
    "credentialSubject": {
 | 
			
		||||
        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
 | 
			
		||||
        "type": [
 | 
			
		||||
            "AchievementSubject"
 | 
			
		||||
        ],
 | 
			
		||||
        "achievement": {
 | 
			
		||||
            "id": "https://example.com/achievements/21st-century-skills/teamwork",
 | 
			
		||||
            "type": [
 | 
			
		||||
                "Achievement"
 | 
			
		||||
            ],
 | 
			
		||||
            "criteria": {
 | 
			
		||||
                "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
 | 
			
		||||
            },
 | 
			
		||||
            "description": "This badge recognizes the development of the capacity to collaborate within a group environment.",
 | 
			
		||||
            "name": "Teamwork"
 | 
			
		||||
        },
 | 
			
		||||
        "source": {
 | 
			
		||||
            "id": "https://school.edu/issuers/201234",
 | 
			
		||||
            "type": "InvalidProfile",
 | 
			
		||||
            "name": "1EdTech College of Arts"
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    "proof": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "Ed25519Signature2020",
 | 
			
		||||
            "created": "2022-11-16T18:54:22Z",
 | 
			
		||||
            "verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv",
 | 
			
		||||
            "proofPurpose": "assertionMethod",
 | 
			
		||||
            "proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,92 @@
 | 
			
		||||
{
 | 
			
		||||
    "@context": [
 | 
			
		||||
        "https://www.w3.org/2018/credentials/v1",
 | 
			
		||||
        "https://purl.imsglobal.org/spec/ob/v3p0/context.json",
 | 
			
		||||
        "https://w3id.org/security/suites/ed25519-2020/v1"
 | 
			
		||||
    ],
 | 
			
		||||
    "id": "http://example.com/credentials/3527",
 | 
			
		||||
    "type": [
 | 
			
		||||
        "VerifiableCredential",
 | 
			
		||||
        "OpenBadgeCredential"
 | 
			
		||||
    ],
 | 
			
		||||
    "issuer": {
 | 
			
		||||
        "id": "https://example.com/issuers/876543",
 | 
			
		||||
        "type": [
 | 
			
		||||
            "Profile"
 | 
			
		||||
        ],
 | 
			
		||||
        "name": "Example Corp"
 | 
			
		||||
    },
 | 
			
		||||
    "issuanceDate": "2010-01-01T00:00:00Z",
 | 
			
		||||
    "name": "Teamwork Badge",
 | 
			
		||||
    "credentialSubject": {
 | 
			
		||||
        "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
 | 
			
		||||
        "type": [
 | 
			
		||||
            "AchievementSubject"
 | 
			
		||||
        ],
 | 
			
		||||
        "achievement": {
 | 
			
		||||
            "id": "https://example.com/achievements/21st-century-skills/teamwork",
 | 
			
		||||
            "type": [
 | 
			
		||||
                "Achievement"
 | 
			
		||||
            ],
 | 
			
		||||
            "criteria": {
 | 
			
		||||
                "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
 | 
			
		||||
            },
 | 
			
		||||
            "description": "This badge recognizes the development of the capacity to collaborate within a group environment.",
 | 
			
		||||
            "name": "Teamwork"
 | 
			
		||||
        },
 | 
			
		||||
        "result": [
 | 
			
		||||
            {
 | 
			
		||||
                "type": [
 | 
			
		||||
                    "Result"
 | 
			
		||||
                ],
 | 
			
		||||
                "alignment": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "Alignment",
 | 
			
		||||
                        "targetCode": "project",
 | 
			
		||||
                        "targetDescription": "Project description",
 | 
			
		||||
                        "targetName": "Final Project",
 | 
			
		||||
                        "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                        "targetType": "CFItem",
 | 
			
		||||
                        "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
 | 
			
		||||
                "value": "A"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "type": [
 | 
			
		||||
                    "InvalidResult"
 | 
			
		||||
                ],
 | 
			
		||||
                "achievedLevel": "urn:uuid:d05a0867-d0ad-4b03-bdb5-28fb5d2aab7a",
 | 
			
		||||
                "alignment": [
 | 
			
		||||
                    {
 | 
			
		||||
                        "type": "Alignment",
 | 
			
		||||
                        "targetCode": "project",
 | 
			
		||||
                        "targetDescription": "Project description",
 | 
			
		||||
                        "targetName": "Final Project",
 | 
			
		||||
                        "targetFramework": "1EdTech University Program and Course Catalog",
 | 
			
		||||
                        "targetType": "CFItem",
 | 
			
		||||
                        "targetUrl": "https://1edtech.edu/catalog/degree/project/result/1"
 | 
			
		||||
                    }
 | 
			
		||||
                ],
 | 
			
		||||
                "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "type": [
 | 
			
		||||
                    "Result"
 | 
			
		||||
                ],
 | 
			
		||||
                "resultDescription": "urn:uuid:f6ab24cd-86e8-4eaf-b8c6-ded74e8fd41c",
 | 
			
		||||
                "status": "Completed"
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
    "proof": [
 | 
			
		||||
        {
 | 
			
		||||
            "type": "Ed25519Signature2020",
 | 
			
		||||
            "created": "2022-11-16T18:54:22Z",
 | 
			
		||||
            "verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv",
 | 
			
		||||
            "proofPurpose": "assertionMethod",
 | 
			
		||||
            "proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK"
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,47 @@
 | 
			
		||||
{
 | 
			
		||||
    "@context": [
 | 
			
		||||
      "https://www.w3.org/2018/credentials/v1",
 | 
			
		||||
      "https://purl.imsglobal.org/spec/ob/v3p0/context.json",
 | 
			
		||||
      "https://w3id.org/security/suites/ed25519-2020/v1"
 | 
			
		||||
    ],
 | 
			
		||||
    "id": "http://example.com/credentials/3527",
 | 
			
		||||
    "type": [
 | 
			
		||||
      "VerifiableCredential",
 | 
			
		||||
      "OpenBadgeCredential"
 | 
			
		||||
    ],
 | 
			
		||||
    "issuer": {
 | 
			
		||||
      "id": "https://example.com/issuers/876543",
 | 
			
		||||
      "type": [
 | 
			
		||||
        "Profile"
 | 
			
		||||
      ],
 | 
			
		||||
      "name": "Example Corp"
 | 
			
		||||
    },
 | 
			
		||||
    "issuanceDate": "2010-01-01T00:00:00Z",
 | 
			
		||||
    "name": "Teamwork Badge",
 | 
			
		||||
    "credentialSubject": {
 | 
			
		||||
      "id": "did:example:ebfeb1f712ebc6f1c276e12ec21",
 | 
			
		||||
      "type": [
 | 
			
		||||
        "InvalidAchievementSubject"
 | 
			
		||||
      ],
 | 
			
		||||
      "achievement": {
 | 
			
		||||
        "id": "https://example.com/achievements/21st-century-skills/teamwork",
 | 
			
		||||
        "type": [
 | 
			
		||||
          "Achievement"
 | 
			
		||||
        ],
 | 
			
		||||
        "criteria": {
 | 
			
		||||
          "narrative": "Team members are nominated for this badge by their peers and recognized upon review by Example Corp management."
 | 
			
		||||
        },
 | 
			
		||||
        "description": "This badge recognizes the development of the capacity to collaborate within a group environment.",
 | 
			
		||||
        "name": "Teamwork"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "proof": [
 | 
			
		||||
      {
 | 
			
		||||
        "type": "Ed25519Signature2020",
 | 
			
		||||
        "created": "2022-11-16T18:54:22Z",
 | 
			
		||||
        "verificationMethod": "https://example.com/issuers/876543#z6MknNHHrBzPytzu6CUBP9Lg7fg4KSBjzimc2Frh693YbMiv",
 | 
			
		||||
        "proofPurpose": "assertionMethod",
 | 
			
		||||
        "proofValue": "z5gJZKchSJEYPGeq6bsqiLKuxT6mXqAovPbqYX66CB7u9CSNFdV41vHtysjHFiitvoyhfPxsaZnWftrZZZW2txPQK"
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user