Skip to content
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
wants to merge 16 commits into
base: versione-corrente
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added script/JSON_validator/end.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/JSON_validator/err1.png
Copy link
Member

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

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/JSON_validator/err2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/JSON_validator/err3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/JSON_validator/err4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added script/JSON_validator/err5.png
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 script/JSON_validator/presentation_definition_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import json
Copy link
Member

Choose a reason for hiding this comment

The 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)
209 changes: 209 additions & 0 deletions script/JSON_validator/readme.md
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)


Loading
Loading