diff --git a/script/JSON_validator/presentation_definition_validator.py b/script/JSON_validator/presentation_definition_validator.py new file mode 100644 index 000000000..fd9bfdcad --- /dev/null +++ b/script/JSON_validator/presentation_definition_validator.py @@ -0,0 +1,100 @@ +# generated by datamodel-codegen: +# filename: schema.json +# timestamp: 2024-06-13T12:20:17+00:00 + +from __future__ import annotations + +from enum import Enum +from typing import Any, Dict, List, Optional, Union +import re + +from pydantic import BaseModel, Extra, Field, conint, constr, root_validator, ValidationError, RootModel + +# Enum for LimitDisclosure with two possible values: 'required' and 'preferred' +class LimitDisclosure(Enum): + required = 'required' + preferred = 'preferred' + +# Constraints model that includes optional fields for limit_disclosure and fields +class Constraints(BaseModel): + class Config: + extra = Extra.forbid + + limit_disclosure: Optional[LimitDisclosure] = None + fields: Optional[List[Any]] = None + +# Model for PresentationDefinitionClaimFormatDesignations with alg field having minimum one item +class PresentationDefinitionClaimFormatDesignations1(BaseModel): + class Config: + extra = Extra.forbid + + alg: Optional[List[str]] = Field(None, min_items=1) + +# Model for PresentationDefinitionClaimFormatDesignations with proof_type field having minimum one item +class PresentationDefinitionClaimFormatDesignations2(BaseModel): + class Config: + extra = Extra.forbid + + proof_type: Optional[List[str]] = Field(None, min_items=1) + +# Define the regular expressions separately +JWT_REGEX = re.compile(r'^jwt$|^jwt_vc$|^jwt_vp$') +LDP_REGEX = re.compile(r'^ldp_vc$|^ldp_vp$|^ldp$') + +# Root model to handle multiple types of claim format designations with a validator for keys +class PresentationDefinitionClaimFormatDesignations(RootModel[Union[ + Dict[str, PresentationDefinitionClaimFormatDesignations1], + Dict[str, PresentationDefinitionClaimFormatDesignations2] +]]): + + @root_validator(pre=True) + def check_keys(cls, values): + if isinstance(values, dict): + for key in values.keys(): + if not (JWT_REGEX.match(key) or LDP_REGEX.match(key)): + raise ValueError(f"Invalid key: {key}") + return values + +# Enum for Rule with a single possible value: 'pick' +class Rule(Enum): + pick = 'pick' + +# Model for SubmissionRequirement with required rule field and optional count, name, and from fields +class SubmissionRequirement1(BaseModel): + class Config: + extra = Extra.forbid + + name: Optional[str] = None + rule: Rule + count: Optional[conint(ge=1)] = None + from_: str = Field(..., alias='from') + +# Root model for SubmissionRequirement +class SubmissionRequirement(RootModel[SubmissionRequirement1]): + pass + +# Model for InputDescriptor with required id field and optional name, purpose, format, group, and constraints fields +class InputDescriptor(BaseModel): + class Config: + extra = Extra.forbid + + id: str + name: Optional[str] = None + purpose: Optional[str] = None + format: Optional[PresentationDefinitionClaimFormatDesignations] = None + group: Optional[List[str]] = None + constraints: Constraints + +# Model for PresentationDefinition with required id field and input_descriptors field +# Optional submission_requirements field +class PresentationDefinition(BaseModel): + class Config: + extra = Extra.forbid + + id: str + input_descriptors: List[InputDescriptor] + submission_requirements: Optional[List[SubmissionRequirement]] = None + +# Main model for a high assurance profile including an optional presentation_definition field +class PresentationDefinitionForAHighAssuranceProfile(BaseModel): + presentation_definition: Optional[PresentationDefinition] = None diff --git a/script/JSON_validator/test_validation.py b/script/JSON_validator/test_validation.py new file mode 100644 index 000000000..54ea5ac21 --- /dev/null +++ b/script/JSON_validator/test_validation.py @@ -0,0 +1,22 @@ +import json +from pydantic import ValidationError +from model import PresentationDefinitionForAHighAssuranceProfile + +# Function to load JSON data from a file +def load_json(file_path: str) -> dict: + with open(file_path, 'r') as file: + return json.load(file) + +# Load valid data from JSON file and create an instance of PresentationDefinitionForAHighAssuranceProfile +try: + valid_data = load_json('example_data.json') + presentation_definition_instance = PresentationDefinitionForAHighAssuranceProfile(**valid_data) + + # Print the ID of the presentation definition + print(f"Presentation ID: {presentation_definition_instance.presentation_definition.id}") + + # Print the name of the first input descriptor + print(f"Input Descriptor Name: {presentation_definition_instance.presentation_definition.input_descriptors[0].name}") +except ValidationError as e: + # Handle and print validation errors + print(f"Validation error: {e}")