Generic TypePropertyProbe
This commit is contained in:
parent
a46fcbff9a
commit
cc33dd4068
@ -1,5 +1,6 @@
|
|||||||
package org.oneedtech.inspect.vc;
|
package org.oneedtech.inspect.vc;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -64,9 +65,16 @@ public class Assertion extends Credential {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Type {
|
public enum Type implements CredentialEnum {
|
||||||
Assertion,
|
Assertion(List.of("Assertion")),
|
||||||
Unknown;
|
BadgeClass(List.of("BadgeClass")),
|
||||||
|
Unknown(Collections.emptyList());
|
||||||
|
|
||||||
|
private final List<String> allowedTypeValues;
|
||||||
|
|
||||||
|
Type(List<String> typeValues) {
|
||||||
|
this.allowedTypeValues = typeValues;
|
||||||
|
}
|
||||||
|
|
||||||
public static Assertion.Type valueOf (JsonNode typeNode) {
|
public static Assertion.Type valueOf (JsonNode typeNode) {
|
||||||
if(typeNode != null) {
|
if(typeNode != null) {
|
||||||
@ -75,10 +83,23 @@ public class Assertion extends Credential {
|
|||||||
if(value.equals("Assertion")) {
|
if(value.equals("Assertion")) {
|
||||||
return Assertion;
|
return Assertion;
|
||||||
}
|
}
|
||||||
|
if(value.equals("BadgeClass")) {
|
||||||
|
return BadgeClass;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Unknown;
|
return Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRequiredTypeValues() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getAllowedTypeValues() {
|
||||||
|
return allowedTypeValues;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String ID = Assertion.class.getCanonicalName();
|
public static final String ID = Assertion.class.getCanonicalName();
|
||||||
|
@ -74,6 +74,11 @@ public abstract class Credential extends GeneratedObject {
|
|||||||
public static final List<ResourceType> RECOGNIZED_PAYLOAD_TYPES = List.of(SVG, PNG, JSON, JWT);
|
public static final List<ResourceType> RECOGNIZED_PAYLOAD_TYPES = List.of(SVG, PNG, JSON, JWT);
|
||||||
public static final String CREDENTIAL_KEY = "CREDENTIAL_KEY";
|
public static final String CREDENTIAL_KEY = "CREDENTIAL_KEY";
|
||||||
|
|
||||||
|
public interface CredentialEnum {
|
||||||
|
List<String> getRequiredTypeValues();
|
||||||
|
List<String> getAllowedTypeValues();
|
||||||
|
}
|
||||||
|
|
||||||
public abstract static class Builder<B extends Credential> {
|
public abstract static class Builder<B extends Credential> {
|
||||||
private Resource resource;
|
private Resource resource;
|
||||||
private JsonNode jsonData;
|
private JsonNode jsonData;
|
||||||
|
@ -5,6 +5,7 @@ import static org.oneedtech.inspect.vc.VerifiableCredential.Type.ClrCredential;
|
|||||||
import static org.oneedtech.inspect.vc.VerifiableCredential.Type.EndorsementCredential;
|
import static org.oneedtech.inspect.vc.VerifiableCredential.Type.EndorsementCredential;
|
||||||
import static org.oneedtech.inspect.vc.VerifiableCredential.Type.VerifiablePresentation;
|
import static org.oneedtech.inspect.vc.VerifiableCredential.Type.VerifiablePresentation;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -72,14 +73,20 @@ public class VerifiableCredential extends Credential {
|
|||||||
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public enum Type {
|
public enum Type implements CredentialEnum {
|
||||||
AchievementCredential,
|
AchievementCredential(Collections.emptyList()),
|
||||||
OpenBadgeCredential, //treated as an alias of AchievementCredential
|
OpenBadgeCredential(List.of("OpenBadgeCredential", "AchievementCredential")), //treated as an alias of AchievementCredential
|
||||||
ClrCredential,
|
ClrCredential(List.of("ClrCredential")),
|
||||||
EndorsementCredential,
|
EndorsementCredential(List.of("EndorsementCredential")),
|
||||||
VerifiablePresentation,
|
VerifiablePresentation(Collections.emptyList()),
|
||||||
VerifiableCredential, //this is an underspecifier in our context
|
VerifiableCredential(List.of("VerifiableCredential")), //this is an underspecifier in our context
|
||||||
Unknown;
|
Unknown(Collections.emptyList());
|
||||||
|
|
||||||
|
private final List<String> allowedTypeValues;
|
||||||
|
|
||||||
|
Type(List<String> allowedTypeValues) {
|
||||||
|
this.allowedTypeValues = allowedTypeValues;
|
||||||
|
}
|
||||||
|
|
||||||
public static VerifiableCredential.Type valueOf (JsonNode typeNode) {
|
public static VerifiableCredential.Type valueOf (JsonNode typeNode) {
|
||||||
if(typeNode != null) {
|
if(typeNode != null) {
|
||||||
@ -98,6 +105,16 @@ public class VerifiableCredential extends Credential {
|
|||||||
}
|
}
|
||||||
return Unknown;
|
return Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getRequiredTypeValues() {
|
||||||
|
return List.of("VerifiableCredential");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getAllowedTypeValues() {
|
||||||
|
return allowedTypeValues;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ProofType {
|
public enum ProofType {
|
||||||
|
@ -3,10 +3,11 @@ package org.oneedtech.inspect.vc.probe;
|
|||||||
import static org.oneedtech.inspect.util.code.Defensives.checkNotNull;
|
import static org.oneedtech.inspect.util.code.Defensives.checkNotNull;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.oneedtech.inspect.core.probe.RunContext;
|
import org.oneedtech.inspect.core.probe.RunContext;
|
||||||
import org.oneedtech.inspect.core.report.ReportItems;
|
import org.oneedtech.inspect.core.report.ReportItems;
|
||||||
import org.oneedtech.inspect.vc.VerifiableCredential;
|
import org.oneedtech.inspect.vc.Credential.CredentialEnum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Probe that verifies a credential's type property.
|
* A Probe that verifies a credential's type property.
|
||||||
@ -14,38 +15,48 @@ import org.oneedtech.inspect.vc.VerifiableCredential;
|
|||||||
* @author mgylling
|
* @author mgylling
|
||||||
*/
|
*/
|
||||||
public class TypePropertyProbe extends PropertyProbe {
|
public class TypePropertyProbe extends PropertyProbe {
|
||||||
private final VerifiableCredential.Type expected;
|
private final CredentialEnum expected;
|
||||||
|
|
||||||
public TypePropertyProbe(VerifiableCredential.Type expected) {
|
public TypePropertyProbe(CredentialEnum expected) {
|
||||||
super(ID, "type");
|
super(ID, "type");
|
||||||
this.expected = checkNotNull(expected);
|
this.expected = checkNotNull(expected);
|
||||||
this.setValidations(this::validate);
|
this.setValidations(this::validate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReportItems validate(List<String> values, RunContext ctx) {
|
public ReportItems validate(List<String> values, RunContext ctx) {
|
||||||
if (!values.contains("VerifiableCredential")) {
|
List<String> requiredTypeValues = expected.getRequiredTypeValues();
|
||||||
return fatal("The type property does not contain the entry 'VerifiableCredential'", ctx);
|
if (!requiredTypeValues.isEmpty()) {
|
||||||
|
if (!requiredTypeValues.stream().allMatch(requiredValue -> values.contains(requiredValue))) {
|
||||||
|
return fatal(formatMessage(requiredTypeValues), ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expected == VerifiableCredential.Type.OpenBadgeCredential) {
|
List<String> allowedValues = expected.getAllowedTypeValues();
|
||||||
if (!values.contains("OpenBadgeCredential") && !values.contains("AchievementCredential")) {
|
if (allowedValues.isEmpty()) {
|
||||||
return fatal("The type property does not contain one of 'OpenBadgeCredential' or 'AchievementCredential'", ctx);
|
|
||||||
}
|
|
||||||
} else if (expected == VerifiableCredential.Type.ClrCredential) {
|
|
||||||
if (!values.contains("ClrCredential")) {
|
|
||||||
return fatal("The type property does not contain the entry 'ClrCredential'", ctx);
|
|
||||||
}
|
|
||||||
} else if (expected == VerifiableCredential.Type.EndorsementCredential) {
|
|
||||||
if (!values.contains("EndorsementCredential")) {
|
|
||||||
return fatal("The type property does not contain the entry 'EndorsementCredential'", ctx);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO implement
|
// TODO implement
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
if (!values.stream().anyMatch(v -> allowedValues.contains(v))) {
|
||||||
|
return fatal(formatMessage(values), ctx);
|
||||||
|
}
|
||||||
|
|
||||||
return success(ctx);
|
return success(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatMessage(List<String> values) {
|
||||||
|
StringBuffer buffer = new StringBuffer("The type property does not contain ");
|
||||||
|
if (values.size() > 1) {
|
||||||
|
buffer.append("one of");
|
||||||
|
buffer.append(values.stream()
|
||||||
|
.map(value -> "'" + value + "'")
|
||||||
|
.collect(Collectors.joining(" or "))
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
buffer.append("the entry '" + values.get(0) + "'");
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static final String ID = TypePropertyProbe.class.getSimpleName();
|
public static final String ID = TypePropertyProbe.class.getSimpleName();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user