Generic TypePropertyProbe

This commit is contained in:
Xavi Aracil 2022-11-25 12:48:11 +01:00
parent a46fcbff9a
commit cc33dd4068
4 changed files with 83 additions and 29 deletions

View File

@ -1,5 +1,6 @@
package org.oneedtech.inspect.vc;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -64,9 +65,16 @@ public class Assertion extends Credential {
}
}
public enum Type {
Assertion,
Unknown;
public enum Type implements CredentialEnum {
Assertion(List.of("Assertion")),
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) {
if(typeNode != null) {
@ -75,10 +83,23 @@ public class Assertion extends Credential {
if(value.equals("Assertion")) {
return Assertion;
}
if(value.equals("BadgeClass")) {
return BadgeClass;
}
}
}
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();

View File

@ -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 String CREDENTIAL_KEY = "CREDENTIAL_KEY";
public interface CredentialEnum {
List<String> getRequiredTypeValues();
List<String> getAllowedTypeValues();
}
public abstract static class Builder<B extends Credential> {
private Resource resource;
private JsonNode jsonData;

View File

@ -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.VerifiablePresentation;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -72,14 +73,20 @@ public class VerifiableCredential extends Credential {
.build();
public enum Type {
AchievementCredential,
OpenBadgeCredential, //treated as an alias of AchievementCredential
ClrCredential,
EndorsementCredential,
VerifiablePresentation,
VerifiableCredential, //this is an underspecifier in our context
Unknown;
public enum Type implements CredentialEnum {
AchievementCredential(Collections.emptyList()),
OpenBadgeCredential(List.of("OpenBadgeCredential", "AchievementCredential")), //treated as an alias of AchievementCredential
ClrCredential(List.of("ClrCredential")),
EndorsementCredential(List.of("EndorsementCredential")),
VerifiablePresentation(Collections.emptyList()),
VerifiableCredential(List.of("VerifiableCredential")), //this is an underspecifier in our context
Unknown(Collections.emptyList());
private final List<String> allowedTypeValues;
Type(List<String> allowedTypeValues) {
this.allowedTypeValues = allowedTypeValues;
}
public static VerifiableCredential.Type valueOf (JsonNode typeNode) {
if(typeNode != null) {
@ -98,6 +105,16 @@ public class VerifiableCredential extends Credential {
}
return Unknown;
}
@Override
public List<String> getRequiredTypeValues() {
return List.of("VerifiableCredential");
}
@Override
public List<String> getAllowedTypeValues() {
return allowedTypeValues;
}
}
public enum ProofType {

View File

@ -3,10 +3,11 @@ package org.oneedtech.inspect.vc.probe;
import static org.oneedtech.inspect.util.code.Defensives.checkNotNull;
import java.util.List;
import java.util.stream.Collectors;
import org.oneedtech.inspect.core.probe.RunContext;
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.
@ -14,38 +15,48 @@ import org.oneedtech.inspect.vc.VerifiableCredential;
* @author mgylling
*/
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");
this.expected = checkNotNull(expected);
this.setValidations(this::validate);
}
public ReportItems validate(List<String> values, RunContext ctx) {
if (!values.contains("VerifiableCredential")) {
return fatal("The type property does not contain the entry 'VerifiableCredential'", ctx);
List<String> requiredTypeValues = expected.getRequiredTypeValues();
if (!requiredTypeValues.isEmpty()) {
if (!requiredTypeValues.stream().allMatch(requiredValue -> values.contains(requiredValue))) {
return fatal(formatMessage(requiredTypeValues), ctx);
}
}
if (expected == VerifiableCredential.Type.OpenBadgeCredential) {
if (!values.contains("OpenBadgeCredential") && !values.contains("AchievementCredential")) {
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 {
List<String> allowedValues = expected.getAllowedTypeValues();
if (allowedValues.isEmpty()) {
// TODO implement
throw new IllegalStateException();
}
if (!values.stream().anyMatch(v -> allowedValues.contains(v))) {
return fatal(formatMessage(values), 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();
}