-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Created a presentation_definition JSON validator python script #315
Draft
cmarco0
wants to merge
16
commits into
italia:versione-corrente
Choose a base branch
from
cmarco0:cmarco0-scriptPY4JSONSchemaPresentationDefinition
base: versione-corrente
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 7 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
43d0e22
Created a presentation_definition JSON validator
cmarco0 e254bec
added schema.json
cmarco0 308abe8
Create readme.md
cmarco0 2462bb3
Possible error in presentation_definition validation
cmarco0 68bf8b5
Update the readme.md for presentation_definition script
cmarco0 74e286a
editorial update
cmarco0 84c4331
editorial update
cmarco0 9255c35
update python script
cmarco0 ad9a7e8
Delete script/JSON_validator/end.png
cmarco0 533f86b
Delete script/JSON_validator/err1.png
cmarco0 9b99e80
Delete script/JSON_validator/err2.png
cmarco0 8fa4707
Delete script/JSON_validator/err3.png
cmarco0 04f1596
Delete script/JSON_validator/err4.png
cmarco0 a43da54
Delete script/JSON_validator/err5.png
cmarco0 137e85f
Delete script/JSON_validator/readme.md
cmarco0 90bf7bb
Update test_validation.py to validate a JSON file
cmarco0 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions
94
script/JSON_validator/presentation_definition_validator.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import json | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is not what I have explicitly asked we need a loader of the json schema validator using pydantic, as the provided example. We don't need static code doing static validation since the json validation schema may change |
||
import jsonschema | ||
import argparse | ||
from jsonschema import validate, ValidationError | ||
|
||
# Function to read a JSON file | ||
def load_json(file_path): | ||
with open(file_path, 'r', encoding='utf-8') as file: | ||
return json.load(file) | ||
|
||
# Function to validate additional rules | ||
def validate_additional_rules(data): | ||
presentation_definition = data.get('presentation_definition', {}) | ||
|
||
# Rule 1: Required properties in presentation_definition | ||
required_pd_properties = ['id', 'input_descriptors', 'submission_requirements'] | ||
for prop in required_pd_properties: | ||
if prop not in presentation_definition: | ||
raise ValidationError(f"Missing required property '{prop}' in presentation_definition") | ||
|
||
# Rule 2: Required properties in input_descriptors | ||
for descriptor in presentation_definition.get('input_descriptors', []): | ||
required_id_properties = ['id', 'name', 'purpose', 'group', 'format', 'constraints'] | ||
for prop in required_id_properties: | ||
if prop not in descriptor: | ||
raise ValidationError(f"Missing required property '{prop}' in input_descriptors") | ||
|
||
# Rule 3: Required properties in constraints | ||
constraints = descriptor.get('constraints', {}) | ||
required_constraints_properties = ['limit_disclosure', 'fields'] | ||
for prop in required_constraints_properties: | ||
if prop not in constraints: | ||
raise ValidationError(f"Missing required property '{prop}' in constraints") | ||
|
||
# Rule 4: Required properties in fields | ||
for field in constraints.get('fields', []): | ||
required_fields_properties = ['path', 'filter'] | ||
for prop in required_fields_properties: | ||
if prop not in field: | ||
raise ValidationError(f"Missing required property '{prop}' in fields") | ||
|
||
# Rule 5: Only one path with a static path | ||
if len(field['path']) != 1: | ||
raise ValidationError("Field 'path' must contain exactly one entry") | ||
|
||
# Rule 6: Filter must only contain string and const elements | ||
filter_keys = field['filter'].keys() | ||
if any(key not in ['type', 'const'] for key in filter_keys): | ||
raise ValidationError("Filter must only contain 'type' and 'const' elements") | ||
if field['filter'].get('type') != 'string': | ||
raise ValidationError("Filter 'type' must be 'string'") | ||
|
||
# Rule 7: Required properties in submission_requirements | ||
for submission in presentation_definition.get('submission_requirements', []): | ||
required_sr_properties = ['name', 'rule', 'count', 'from'] | ||
for prop in required_sr_properties: | ||
if prop not in submission: | ||
raise ValidationError(f"Missing required property '{prop}' in submission_requirements") | ||
if submission['rule'] != 'pick': | ||
raise ValidationError("Submission rule must be 'pick'") | ||
|
||
# Function to validate data | ||
def validate_json(data, schema): | ||
try: | ||
validate(instance=data, schema=schema) | ||
print("JSON schema validation passed.") | ||
|
||
# Validate additional rules | ||
validate_additional_rules(data) | ||
print("Additional rules validation passed.") | ||
|
||
return True | ||
except ValidationError as err: | ||
print("JSON data is invalid.") | ||
print(err) | ||
return False | ||
|
||
# Main function | ||
def main(schema_file, data_file): | ||
# Load schema and data from files | ||
schema = load_json(schema_file) | ||
data = load_json(data_file) | ||
|
||
# Validate data | ||
validate_json(data, schema) | ||
|
||
# Command-line argument configuration | ||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser(description="Validate JSON data against a schema") | ||
parser.add_argument("schema", help="Path to the JSON schema file") | ||
parser.add_argument("data", help="Path to the JSON data file") | ||
|
||
args = parser.parse_args() | ||
main(args.schema, args.data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
# Presentation Definition JSON Validator | ||
|
||
## Table of Contents | ||
|
||
1. [Introduction](#introduction) | ||
2. [Installation](#installation) | ||
3. [Usage](#usage) | ||
|
||
## Introduction | ||
|
||
|
||
This script is designed to validate JSON data against a specified JSON schema and additional custom rules. It reads the JSON schema and data from files, checks if the data conforms to the schema, and ensures that certain additional requirements are met. | ||
This validation process helps in ensuring that the JSON data structure adheres to expected standards and rules, making it reliable and consistent for further processing or usage in applications. | ||
|
||
## Installation | ||
|
||
To get started with this project, follow these steps: | ||
|
||
1. **Download the files:** | ||
|
||
```bash | ||
presentation_definition_validation.py | ||
schema.json | ||
|
||
2. **Create a presentation_definition JSON file:** | ||
|
||
This is just an example: | ||
|
||
```bash | ||
{ | ||
"presentation_definition": { | ||
"id": "presentation definitions", | ||
"input_descriptors": [ | ||
{ | ||
"id": "eu.europa.ec.eudiw.pid.it.1", | ||
"name": "Person Identification Data", | ||
"purpose": "User authentication", | ||
"format": "vc+sd-jwt", | ||
"constraints": { | ||
"fields": [ | ||
{ | ||
"path": [ | ||
"$.credentialSubject.unique_id", | ||
"$.credentialSubject.given_name", | ||
"$.credentialSubject.family_name" | ||
] | ||
} | ||
], | ||
"limit_disclosure": "preferred" | ||
} | ||
}, | ||
{ | ||
"id": "WalletAttestation", | ||
"name": "Wallet Attestation", | ||
"purpose": "Wallet Authentication", | ||
"format": "jwt", | ||
"constraints": { | ||
"fields": [ | ||
{ | ||
"path": [ | ||
"$.iss", | ||
"$.exp", | ||
"$.iat", | ||
"$.cnf.jwk", | ||
"$.aal" | ||
] | ||
} | ||
] | ||
} | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
## Usage | ||
|
||
1. **Execute the script:** | ||
|
||
```bash | ||
python3 presentation_definition_validator.py schema.json example_to_test.json | ||
|
||
2. **Check the output:** | ||
|
||
You can get different kind of errors, these are just some of them: | ||
|
||
![Error 1](script/JSON_validator/err1.png) | ||
|
||
![Error 2](script/JSON_validator/err2.png) | ||
|
||
![Error 3](script/JSON_validator/err3.png) | ||
|
||
![Error 4](script/JSON_validator/err4.png) | ||
|
||
![Error 5](script/JSON_validator/err5.png) | ||
|
||
|
||
3. **Final result:** | ||
|
||
After some modification i got a JSON like this: | ||
|
||
```json | ||
{ | ||
"presentation_definition": { | ||
"id": "presentation definitions", | ||
"input_descriptors": [ | ||
{ | ||
"id": "eu.europa.ec.eudiw.pid.it.1", | ||
"name": "Person Identification Data", | ||
"purpose": "User authentication", | ||
"group": ["group1"], | ||
"format": { | ||
"vc+sd-jwt": { | ||
"alg": ["RS256", "ES256"] | ||
} | ||
}, | ||
"constraints": { | ||
"limit_disclosure": "preferred", | ||
"fields": [ | ||
{ | ||
"path": ["$.credentialSubject.unique_id"], | ||
"filter": { | ||
"type": "string", | ||
"const": "unique_id" | ||
} | ||
}, | ||
{ | ||
"path": ["$.credentialSubject.given_name"], | ||
"filter": { | ||
"type": "string", | ||
"const": "given_name" | ||
} | ||
}, | ||
{ | ||
"path": ["$.credentialSubject.family_name"], | ||
"filter": { | ||
"type": "string", | ||
"const": "family_name" | ||
} | ||
} | ||
] | ||
} | ||
}, | ||
{ | ||
"id": "WalletAttestation", | ||
"name": "Wallet Attestation", | ||
"purpose": "Wallet Authentication", | ||
"group": ["group1"], | ||
"format": { | ||
"jwt": { | ||
"alg": ["RS256", "ES256"] | ||
} | ||
}, | ||
"constraints": { | ||
"limit_disclosure": "preferred", | ||
"fields": [ | ||
{ | ||
"path": ["$.iss"], | ||
"filter": { | ||
"type": "string", | ||
"const":"https://issuer.example.org" | ||
} | ||
}, | ||
{ | ||
"path": ["$.exp"], | ||
"filter": { | ||
"type": "string", | ||
"const": 1504700136 | ||
} | ||
}, | ||
{ | ||
"path": ["$.iat"], | ||
"filter": { | ||
"type": "string", | ||
"const": 1504700136 | ||
} | ||
}, | ||
{ | ||
"path": ["$.cnf.jwk"], | ||
"filter": { | ||
"type": "string" | ||
} | ||
}, | ||
{ | ||
"path": ["$.aal"], | ||
"filter": { | ||
"type": "string", | ||
"const": "aal" | ||
} | ||
} | ||
] | ||
} | ||
} | ||
], | ||
"submission_requirements": [ | ||
{ | ||
"name": "Sample requirement", | ||
"rule": "pick", | ||
"count": 1, | ||
"from": "group1" | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
![Final](script/JSON_validator/end.png) | ||
|
||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need images