Added validations by type
This commit is contained in:
parent
7cd9103001
commit
4267423273
@ -1,9 +1,10 @@
|
||||
package org.oneedtech.inspect.vc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.oneedtech.inspect.schema.Catalog;
|
||||
import org.oneedtech.inspect.schema.SchemaKey;
|
||||
@ -43,6 +44,10 @@ public class Assertion extends Credential {
|
||||
.toString();
|
||||
}
|
||||
|
||||
public List<Validation> getValidations() {
|
||||
return validationMap.get(assertionType);
|
||||
}
|
||||
|
||||
private static final Map<CredentialEnum, SchemaKey> schemas = new ImmutableMap.Builder<CredentialEnum, SchemaKey>()
|
||||
.put(Type.Assertion, Catalog.OB_21_ASSERTION_JSON)
|
||||
.build();
|
||||
@ -60,8 +65,27 @@ public class Assertion extends Credential {
|
||||
public enum Type implements CredentialEnum {
|
||||
Assertion(List.of("Assertion")),
|
||||
BadgeClass(List.of("BadgeClass")),
|
||||
|
||||
AlignmentObject(List.of("AlignmentObject")),
|
||||
Criteria(List.of("Criteria")),
|
||||
CryptographicKey(List.of("CryptographicKey")),
|
||||
Endorsement(List.of("Endorsement")),
|
||||
EndorsementClaim(List.of("EndorsementClaim")),
|
||||
Evidence(List.of("Evidence")),
|
||||
ExpectedRecipientProfile(List.of("ExpectedRecipientProfile")),
|
||||
Extension(List.of("Extension")),
|
||||
IdentityObject(List.of("IdentityObject")),
|
||||
Image(List.of("Image")),
|
||||
Issuer(List.of("Issuer")),
|
||||
Profile(List.of("Profile")),
|
||||
RevocationList(List.of("RevocationList")),
|
||||
VerificationObject(List.of("VerificationObject")),
|
||||
VerificationObjectAssertion(List.of("VerificationObjectAssertion")),
|
||||
VerificationObjectIssuer(List.of("VerificationObjectIssuer")),
|
||||
Unknown(Collections.emptyList());
|
||||
|
||||
public static List<Type> primaryObjects = List.of(Assertion, BadgeClass, Issuer, Profile, Endorsement);
|
||||
|
||||
private final List<String> allowedTypeValues;
|
||||
|
||||
Type(List<String> typeValues) {
|
||||
@ -72,11 +96,12 @@ public class Assertion extends Credential {
|
||||
if(typeNode != null) {
|
||||
List<String> values = JsonNodeUtil.asStringList(typeNode);
|
||||
for (String value : values) {
|
||||
if(value.equals("Assertion")) {
|
||||
return Assertion;
|
||||
}
|
||||
if(value.equals("BadgeClass")) {
|
||||
return BadgeClass;
|
||||
Type found = Arrays.stream(Type.values())
|
||||
.filter(type -> value.equals(type.toString()))
|
||||
.findFirst()
|
||||
.orElse(Unknown);
|
||||
if (found != Unknown) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -99,5 +124,158 @@ public class Assertion extends Credential {
|
||||
}
|
||||
}
|
||||
|
||||
public enum ValueType {
|
||||
BOOLEAN,
|
||||
COMPACT_IRI,
|
||||
DATA_URI,
|
||||
DATA_URI_OR_URL,
|
||||
DATETIME,
|
||||
EMAIL,
|
||||
ID,
|
||||
IDENTITY_HASH,
|
||||
IRI,
|
||||
LANGUAGE,
|
||||
MARKDOWN_TEXT,
|
||||
RDF_TYPE,
|
||||
TELEPHONE,
|
||||
TEXT,
|
||||
TEXT_OR_NUMBER,
|
||||
URL,
|
||||
URL_AUTHORITY;
|
||||
|
||||
public static List<ValueType> primitives = List.of(BOOLEAN, DATA_URI_OR_URL, DATETIME, ID, IDENTITY_HASH, IRI, LANGUAGE, MARKDOWN_TEXT,
|
||||
TELEPHONE, TEXT, TEXT_OR_NUMBER, URL, URL_AUTHORITY);
|
||||
}
|
||||
|
||||
public static Map<Type, List<Validation>> validationMap = new ImmutableMap.Builder<Type, List<Validation>>()
|
||||
.put(Type.Assertion, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(true).build(),
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(true).mustContainOneType(List.of(Type.Assertion)).build(),
|
||||
new Validation.Builder().name("recipient").type(ValueType.ID).expectedType(Type.IdentityObject).required(true).build(),
|
||||
new Validation.Builder().name("badge").type(ValueType.ID).prerequisite("ASN_FLATTEN_BC").expectedType(Type.BadgeClass).fetch(true).required(true).build(),
|
||||
new Validation.Builder().name("verification").type(ValueType.ID).expectedTypes(List.of(Type.VerificationObjectAssertion)).required(true).build(),
|
||||
new Validation.Builder().name("issuedOn").type(ValueType.DATETIME).required(true).build(),
|
||||
new Validation.Builder().name("expires").type(ValueType.DATETIME).required(false).build(),
|
||||
new Validation.Builder().name("image").type(ValueType.ID).required(false).allowRemoteUrl(true).expectedType(Type.Image).fetch(false).allowDataUri(false).build(),
|
||||
new Validation.Builder().name("narrative").type(ValueType.MARKDOWN_TEXT).required(false).build(),
|
||||
new Validation.Builder().name("evidence").type(ValueType.ID).allowRemoteUrl(true).expectedType(Type.Evidence).many(true).fetch(false).required(false).build()
|
||||
))
|
||||
.put(Type.BadgeClass, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(true).build(),
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(true).mustContainOneType(List.of(Type.BadgeClass)).build(),
|
||||
new Validation.Builder().name("issuer").type(ValueType.ID).prerequisite("BC_FLATTEN_ISS").expectedType(Type.Profile).fetch(true).required(true).build(),
|
||||
new Validation.Builder().name("name").type(ValueType.TEXT).required(true).build(),
|
||||
new Validation.Builder().name("description").type(ValueType.TEXT).required(true).build(),
|
||||
new Validation.Builder().name("image").type(ValueType.ID).required(false).allowRemoteUrl(true).expectedType(Type.Image).fetch(false).allowDataUri(true).build(),
|
||||
new Validation.Builder().name("criteria").type(ValueType.ID).expectedType(Type.Criteria).fetch(false).required(true).allowRemoteUrl(true).build(),
|
||||
new Validation.Builder().name("alignment").type(ValueType.ID).expectedType(Type.AlignmentObject).many(true).fetch(false).required(false).build(),
|
||||
new Validation.Builder().name("tags").type(ValueType.TEXT).many(true).required(false).build()
|
||||
))
|
||||
.put(Type.AlignmentObject, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).many(true).required(false).defaultType(Type.AlignmentObject).build(),
|
||||
new Validation.Builder().name("targetName").type(ValueType.TEXT).required(true).build(),
|
||||
new Validation.Builder().name("targetUrl").type(ValueType.URL).required(true).build(),
|
||||
new Validation.Builder().name("description").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("targetFramework").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("targetCode").type(ValueType.TEXT).required(false).build()
|
||||
))
|
||||
.put(Type.Criteria, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).many(true).required(false).defaultType(Type.Criteria).build(),
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(false).build(),
|
||||
new Validation.Builder().name("narrative").type(ValueType.MARKDOWN_TEXT).required(false).build()
|
||||
))
|
||||
.put(Type.CryptographicKey, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(false).build(),
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(false).many(true).defaultType(Type.CryptographicKey).build(),
|
||||
new Validation.Builder().name("owner").type(ValueType.IRI).required(false).fetch(true).build(),
|
||||
new Validation.Builder().name("publicKeyPem").type(ValueType.TEXT).required(false).build()
|
||||
))
|
||||
.put(Type.Endorsement, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(true).build(),
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(true).mustContainOneType(List.of(Type.Endorsement)).build(),
|
||||
new Validation.Builder().name("claim").type(ValueType.ID).required(true).allowRemoteUrl(false).fetch(false).allowDataUri(false).expectedTypes(List.of(Type.EndorsementClaim, Type.Endorsement)).fullValidate(false).build(),
|
||||
new Validation.Builder().name("issuedOn").type(ValueType.DATETIME).required(true).build(),
|
||||
new Validation.Builder().name("issuer").type(ValueType.ID).expectedType(Type.Profile).fetch(true).required(true).build(),
|
||||
new Validation.Builder().name("verification").build()
|
||||
))
|
||||
.put(Type.EndorsementClaim, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(true).build(),
|
||||
new Validation.Builder().name("endorsementComment").type(ValueType.MARKDOWN_TEXT).required(false).build()
|
||||
))
|
||||
.put(Type.Evidence, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).many(true).required(false).defaultType(Type.Evidence).build(),
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(false).build(),
|
||||
new Validation.Builder().name("narrative").type(ValueType.MARKDOWN_TEXT).required(false).build(),
|
||||
new Validation.Builder().name("name").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("description").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("genre").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("audience").type(ValueType.TEXT).required(false).build()
|
||||
))
|
||||
.put(Type.ExpectedRecipientProfile, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(false).build(),
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(false).many(true).mustContainOneType(List.of(Type.Issuer, Type.Profile)).defaultType(Type.Profile).build(),
|
||||
new Validation.Builder().name("name").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("description").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("image").type(ValueType.ID).required(false).expectedType(Type.Image).fetch(false).allowDataUri(true).build(),
|
||||
new Validation.Builder().name("url").type(ValueType.URL).required(false).many(true).build(),
|
||||
new Validation.Builder().name("email").type(ValueType.EMAIL).required(false).many(true).build(),
|
||||
new Validation.Builder().name("telephone").type(ValueType.TELEPHONE).required(false).many(true).build(),
|
||||
new Validation.Builder().name("publicKey").type(ValueType.ID).many(true).expectedType(Type.CryptographicKey).fetch(false).required(false).build(),
|
||||
new Validation.Builder().name("verification").type(ValueType.ID).expectedType(Type.VerificationObjectIssuer).fetch(false).required(false).build()
|
||||
))
|
||||
.put(Type.Extension, List.of())
|
||||
.put(Type.IdentityObject, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(false).mustContainOne(List.of("id", "email", "url", "telephone")).build(),
|
||||
new Validation.Builder().name("identity").type(ValueType.IDENTITY_HASH).required(true).build(),
|
||||
new Validation.Builder().name("hashed").type(ValueType.BOOLEAN).required(true).build(),
|
||||
new Validation.Builder().name("salt").type(ValueType.TEXT).required(false).build()
|
||||
))
|
||||
.put(Type.Image, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).many(true).required(false).defaultType("schema:ImageObject").build(),
|
||||
new Validation.Builder().name("id").type(ValueType.DATA_URI_OR_URL).required(true).build(),
|
||||
new Validation.Builder().name("caption").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("author").type(ValueType.IRI).required(false).build()
|
||||
))
|
||||
.put(Type.Issuer, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(true).build(),
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(true).mustContainOneType(List.of(Type.Issuer, Type.Profile)).build(),
|
||||
new Validation.Builder().name("name").type(ValueType.TEXT).required(true).build(),
|
||||
new Validation.Builder().name("description").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("image").type(ValueType.ID).required(false).allowRemoteUrl(true).expectedType(Type.Image).fetch(false).allowDataUri(true).build(),
|
||||
new Validation.Builder().name("url").type(ValueType.URL).required(true).build(),
|
||||
new Validation.Builder().name("email").type(ValueType.EMAIL).required(true).build(),
|
||||
new Validation.Builder().name("telephone").type(ValueType.TELEPHONE).required(false).build(),
|
||||
new Validation.Builder().name("publicKey").type(ValueType.ID).expectedType(Type.CryptographicKey).fetch(true).required(false).build(),
|
||||
new Validation.Builder().name("verification").type(ValueType.ID).expectedType(Type.VerificationObjectIssuer).fetch(false).required(false).build()
|
||||
))
|
||||
.put(Type.Profile, List.of(
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(true).build(),
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(true).mustContainOneType(List.of(Type.Issuer, Type.Profile)).build(),
|
||||
new Validation.Builder().name("name").type(ValueType.TEXT).required(true).build(),
|
||||
new Validation.Builder().name("description").type(ValueType.TEXT).required(false).build(),
|
||||
new Validation.Builder().name("image").type(ValueType.ID).required(false).allowRemoteUrl(true).expectedType(Type.Image).fetch(false).allowDataUri(true).build(),
|
||||
new Validation.Builder().name("url").type(ValueType.URL).required(true).build(),
|
||||
new Validation.Builder().name("email").type(ValueType.EMAIL).required(true).build(),
|
||||
new Validation.Builder().name("telephone").type(ValueType.TELEPHONE).required(false).build(),
|
||||
new Validation.Builder().name("publicKey").type(ValueType.ID).expectedType(Type.CryptographicKey).fetch(true).required(false).build(),
|
||||
new Validation.Builder().name("verification").type(ValueType.ID).expectedType(Type.VerificationObjectIssuer).fetch(false).required(false).build()
|
||||
))
|
||||
.put(Type.RevocationList, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(true).mustContainOneType(List.of(Type.RevocationList)).build(),
|
||||
new Validation.Builder().name("id").type(ValueType.IRI).required(false).build()
|
||||
))
|
||||
.put(Type.VerificationObject, List.of())
|
||||
.put(Type.VerificationObjectAssertion, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(true).many(false).mustContainOne(List.of("HostedBadge", "SignedBadge")).build(),
|
||||
new Validation.Builder().name("creator").type(ValueType.ID).expectedType(Type.CryptographicKey).fetch(true).required(false).prerequisite("ASSERTION_VERIFICATION_DEPENDENCIES").build()
|
||||
))
|
||||
.put(Type.VerificationObjectIssuer, List.of(
|
||||
new Validation.Builder().name("type").type(ValueType.RDF_TYPE).required(false).many(true).defaultType(Type.VerificationObject).build(),
|
||||
new Validation.Builder().name("verificationProperty").type(ValueType.COMPACT_IRI).required(false).build(),
|
||||
new Validation.Builder().name("startsWith").type(ValueType.URL).required(false).build(),
|
||||
new Validation.Builder().name("allowedOrigins").type(ValueType.URL_AUTHORITY).required(false).many(true).build()
|
||||
))
|
||||
.build();
|
||||
|
||||
public static final String ID = Assertion.class.getCanonicalName();
|
||||
}
|
||||
|
@ -0,0 +1,142 @@
|
||||
package org.oneedtech.inspect.vc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Validation class for Open Badges 2.0 types
|
||||
*/
|
||||
public class Validation {
|
||||
private final String name;
|
||||
private final Assertion.ValueType type;
|
||||
private final boolean required;
|
||||
private final boolean many;
|
||||
private final List<String> mustContainOne;
|
||||
private final List<String> prerequisites;
|
||||
private final List<Assertion.Type> expectedTypes;
|
||||
private final boolean allowRemoteUrl;
|
||||
private final boolean allowDataUri;
|
||||
private final boolean fetch;
|
||||
private final String defaultType;
|
||||
private final boolean fullValidate;
|
||||
|
||||
public Validation(Builder builder) {
|
||||
this.name = builder.name;
|
||||
this.type = builder.type;
|
||||
this.required = builder.required;
|
||||
this.many = builder.many;
|
||||
this.mustContainOne = builder.mustContainOne;
|
||||
this.prerequisites = builder.prerequisites;
|
||||
this.expectedTypes = builder.expectedTypes;
|
||||
this.allowRemoteUrl = builder.allowRemoteUrl;
|
||||
this.allowDataUri = builder.allowDataUri;
|
||||
this.fetch = builder.fetch;
|
||||
this.defaultType = builder.defaultType;
|
||||
this.fullValidate = builder.fullValidate;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String name;
|
||||
private Assertion.ValueType type;
|
||||
private boolean required;
|
||||
private boolean many;
|
||||
private List<String> mustContainOne;
|
||||
private List<String> prerequisites;
|
||||
private List<Assertion.Type> expectedTypes;
|
||||
private boolean allowRemoteUrl;
|
||||
private boolean allowDataUri;
|
||||
private boolean fetch;
|
||||
private String defaultType;
|
||||
private boolean fullValidate;
|
||||
|
||||
public Builder() {
|
||||
this.mustContainOne = new ArrayList<>();
|
||||
this.prerequisites = new ArrayList<>();
|
||||
this.expectedTypes = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder type(Assertion.ValueType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder required(boolean required) {
|
||||
this.required = required;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder many(boolean many) {
|
||||
this.many = many;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder mustContainOne(List<String> elems) {
|
||||
this.mustContainOne = elems;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder mustContainOneType(List<Assertion.Type> types) {
|
||||
this.mustContainOne = types.stream().map(Assertion.Type::toString).collect(Collectors.toList());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder prerequisites(List<String> elems) {
|
||||
this.prerequisites = elems;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder prerequisite(String elem) {
|
||||
this.prerequisites = List.of(elem);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder expectedTypes(List<Assertion.Type> elems) {
|
||||
this.expectedTypes = elems;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder expectedType(Assertion.Type type) {
|
||||
this.expectedTypes = List.of(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder allowRemoteUrl(boolean allowRemoteUrl) {
|
||||
this.allowRemoteUrl = allowRemoteUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder allowDataUri(boolean allowDataUri) {
|
||||
this.allowDataUri = allowDataUri;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder fetch(boolean fetch) {
|
||||
this.fetch = fetch;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder defaultType(Assertion.Type defaultType) {
|
||||
return defaultType(defaultType.toString());
|
||||
}
|
||||
|
||||
public Builder defaultType(String defaultType) {
|
||||
this.defaultType = defaultType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder fullValidate(boolean fullValidate) {
|
||||
this.fullValidate = fullValidate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Validation build() {
|
||||
return new Validation(this);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user