From ef43bdfe65ee49cf84d32e8de37468724bd5e936 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 1 Apr 2025 11:13:41 -0400 Subject: [PATCH] Implement sanity checking for JSON schema definitions --- netbox/dcim/models/modules.py | 12 ++++++------ netbox/utilities/jsonschema.py | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/models/modules.py b/netbox/dcim/models/modules.py index 6f64275ce..432b7afd1 100644 --- a/netbox/dcim/models/modules.py +++ b/netbox/dcim/models/modules.py @@ -4,8 +4,7 @@ from django.core.exceptions import ValidationError from django.db import models from django.db.models.signals import post_save from django.utils.translation import gettext_lazy as _ -from jsonschema.exceptions import SchemaError, ValidationError as JSONValidationError -from jsonschema.validators import Draft202012Validator as JSONSchemaValidator +from jsonschema.exceptions import ValidationError as JSONValidationError from dcim.choices import * from dcim.utils import update_interface_bridges @@ -13,6 +12,7 @@ from extras.models import ConfigContextModel, CustomField from netbox.models import PrimaryModel from netbox.models.features import ImageAttachmentsMixin from netbox.models.mixins import WeightMixin +from utilities.jsonschema import validate_schema from utilities.string import title from .device_components import * @@ -52,12 +52,12 @@ class ModuleTypeProfile(PrimaryModel): super().clean() # Validate the schema definition - if self.schema: + if self.schema is not None: try: - JSONSchemaValidator.check_schema(self.schema) - except SchemaError as e: + validate_schema(self.schema) + except ValidationError as e: raise ValidationError({ - 'schema': _("Invalid schema: {error}").format(error=e) + 'schema': e.message, }) diff --git a/netbox/utilities/jsonschema.py b/netbox/utilities/jsonschema.py index 97217286a..724253a50 100644 --- a/netbox/utilities/jsonschema.py +++ b/netbox/utilities/jsonschema.py @@ -4,7 +4,11 @@ from typing import Any from django import forms from django.contrib.postgres.forms import SimpleArrayField +from django.core.exceptions import ValidationError from django.core.validators import RegexValidator +from django.utils.translation import gettext_lazy as _ +from jsonschema.exceptions import SchemaError +from jsonschema.validators import validator_for from utilities.string import title from utilities.validators import MultipleOfValidator @@ -13,6 +17,7 @@ __all__ = ( 'JSONSchemaProperty', 'PropertyTypeEnum', 'StringFormatEnum', + 'validate_schema', ) @@ -143,3 +148,19 @@ class JSONSchemaProperty: return FORM_FIELDS[self.type] except KeyError: raise ValueError(f"Unknown property type: {self.type}") + + +def validate_schema(schema): + """ + Check that a minimum JSON schema definition is defined. + """ + # Provide some basic sanity checking (not provided by jsonschema) + if not schema or type(schema) is not dict: + raise ValidationError(_("Invalid JSON schema definition")) + if not schema.get('properties'): + raise ValidationError(_("JSON schema must define properties")) + try: + ValidatorClass = validator_for(schema) + ValidatorClass.check_schema(schema) + except SchemaError as e: + raise ValidationError(_("Invalid JSON schema definition: {error}").format(error=e))