Beispiel #1
0
def check_schema_base_path():
    if not _SCHEMA_BASE_PATH:
        raise SchemaError(
            "Make sure to first set _SCHEMA_BASE_PATH (base_path) to the location of the json/yaml "
            "file to process.")

    if not _SCHEMA_BASE_URI:
        raise SchemaError(
            "Make sure to first set _SCHEMA_BASE_URI (base_uri) to the location of the json/yaml "
            "file to process, and _SCHEMA_BASE_URI to the corresponding URI.")
Beispiel #2
0
def load_schema(schema, schemas_store=None):
    _("""
    Load a schema to the schema store.

    if no schema store is provided, only the internal schema store is filled.

    :param schema: schema as dictionary
    :type schema: dict
    :param schemas_store: optional schemas_store to fill
    :type schemas_store: dict
    """)
    from ngoschema.resolvers.uri_resolver import UriResolver
    uri = _id_of(schema).rstrip('#')
    if not uri and "title" in schema:
        uri = inflection.parameterize(six.text_type(schema["title"]), "_")
    if not uri:
        raise SchemaError(
            "Impossible to load schema because `id (or `$id) and `title fields"
            "are missing.\n%s" % schema)
    if schemas_store is not None:
        if schema != schemas_store.get(uri, schema):
            logger.info(
                "Overwriting a different schema '%s' is already registered in schema store."
                % uri)
        schemas_store[uri] = schema
    # add to main registry
    UriResolver.register_doc(schema, uri)
    return uri, schema
Beispiel #3
0
        def wrapper(self, *method_args, **method_kwargs):
            logging.debug("JSON Schema for %s -> %s", self.request.method,
                          self.__class__)
            try:
                json_req = json.loads(self.request.body)
                if schema is not None:
                    logging.debug("Validating json schema")
                    validate(json_req, schema)
                elif self.request.method not in ["GET", "HEAD", "DELETE"]:
                    raise SchemaError("Request method %s must have a schema" %
                                      self.request.method)
                else:
                    logging.debug("No json schema for request, skipping")

                return method(self, json_req, *method_args, **method_kwargs)
            except (ValidationError, ValidationError) as error:
                self.set_status(BAD_REQUEST)
                self.write({"error": str(error)})
                self.finish()
            except SchemaError as error:
                self.set_status(BAD_REQUEST)
                if options.debug:
                    logging.exception("Request triggered exception")
                    self.write({"error": str(error)})
                else:
                    self.write(
                        {"error": "JSON request not formatted properly"})
                self.finish()
def discriminator_validator(validator, oneOf, instance, schema):
    discriminator = schema.get('discriminator')
    propertyName = discriminator['propertyName']
    mapping = discriminator['mapping']
    errs = list(
        validator.descend(
            instance,
            {
                'type': 'object',
                'properties': {
                    propertyName: {
                        'type': 'string',
                        'enum': list(mapping),
                    },
                },
                'required': [propertyName],
            },
        ))
    if errs:
        yield errs[0]
        return

    descr_value = instance[propertyName]
    descr_schema = mapping[descr_value]

    for index, subschema in enumerate(oneOf):
        if subschema == descr_schema:
            break
    else:
        yield SchemaError('descriminator error')
        return

    yield from validator.descend(instance, subschema, schema_path=index)
Beispiel #5
0
def check_json_matches_schema(jsondata,
                              schema_filename: str,
                              base_path: str = "",
                              base_uri: str = ""):
    """
    Check the given json data against the jsonschema in the given schema file,
    raising an exception on error.  The exception text includes one or more
    validation error messages.

    schema_filename is relative to the schema root directory.

    may raise SchemaError or ValidationError
    """
    set_schema_base_path(base_path=base_path, base_uri=base_uri)

    try:
        validator = Validator(_load_json_schema(schema_filename))
    except SchemaError as e:
        raise SchemaError('{} is invalid: {}'.format(schema_filename, e))

    err_msg_l = []
    for error in validator.iter_errors(jsondata):
        err_msg_l.append('{}: {}'.format(
            ' '.join([str(word) for word in error.path]), error.message))
    if err_msg_l:
        raise ValidationError(' + '.join(err_msg_l))
    else:
        return True
Beispiel #6
0
 def wrapper(self, *method_args, **method_kwargs):
     try:
         if schema is not None:
             schema["additionalProperties"] = False
             validate(self.api_request, schema)
         elif self.request.method not in ["GET", "HEAD", "DELETE"]:
             raise SchemaError("Request method %s must have a schema" %
                               self.request.method)
         return method(self, *method_args, **method_kwargs)
     except (JsonValidationError, ValidationError) as error:
         self.set_status(BAD_REQUEST)
         self.write({"error": str(error)})
         self.finish()
     except SchemaError as error:
         self.set_status(BAD_REQUEST)
         if options.debug:
             logging.exception('Request triggered exception')
             self.write({"error": "JSON schema: " + str(error)})
         else:
             self.write(
                 {"error": "JSON request not formatted properly"})
         self.finish()
     except StatementError:
         self.set_status(BAD_REQUEST)
         logging.exception('Request triggered exception')
         self.write({"error": "JSON request not formatted properly"})
         self.finish()
Beispiel #7
0
    def check_schema(schema: dict) -> None:
        """
        Throws an exception if the schema is not a valid instance of the JSON Schema specification.
        The schema can (and should) specify which draft of JSON Schema it follows using the
        reserved keyword "$schema" [1]. Supports drafts 4, 6 and 7 of JSON Schema [2].
        If not specified, the check is performed against draft 7, the newest version at the time of
        writing this module.

        Parameters
        ----------
        schema : dict
            The schema to be checked.
        
        References
        ----------
        [1] :
        https://json-schema.org/understanding-json-schema/basics.html#declaring-a-json-schema
        [2] :
        https://json-schema.org/understanding-json-schema/reference/schema.html#schema
        """
        specification = schema.get("$schema", None)
        if specification == "http://json-schema.org/draft-07/schema#":
            jsonschema.Draft7Validator.check_schema(schema=schema)
        elif specification == "http://json-schema.org/draft-06/schema#":
            jsonschema.Draft6Validator.check_schema(schema=schema)
        elif specification == "http://json-schema.org/draft-04/schema#":
            jsonschema.Draft4Validator.check_schema(schema=schema)
        elif specification is None:
            # Default to draft 7 if unspecified
            jsonschema.Draft7Validator.check_schema(schema=schema)
        else:
            # Throw exception if specified but not supported
            raise SchemaError(
                f"JSON Schema specification ({specification}) is not supported."
            )
Beispiel #8
0
    def validate_against(self, instance, schemauris=[], strict=False):
        """
        validate the instance against each of the schemas identified by the 
        list of schemauris.  For the instance to be considered valid, it 
        must validate against each of the named schemas.  $extensionSchema
        properties within the instance are ignored.  

        :argument instance:  a parsed JSON document to be validated.
        :argument list schemauris:  a list of URIs of the schemas to validate
                                    against.  
        :argument bool strict:  if True, validation will fail if any of the 
                                schema URIs cannot be resolved to a schema.
                                if False, unresolvable schemas URIs will be 
                                ignored and validation against that schema will
                                be skipped.  
        """
        if isinstance(schemauris, str) or isinstance(schemauris, unicode):
            schemauris = [ schemauris ]
        schema = None
        out = True
        for uri in schemauris:
            val = self._validators.get(uri)
            if not val:
                (urib,frag) = self._spliturifrag(uri)
                schema = self._schemaStore.get(urib)
                if not schema:
                    try:
                        schema = self._loader(urib)
                    except KeyError, e:
                        if strict:
                            raise SchemaError("Unable to resolve schema for " + 
                                              urib)
                        continue
                resolver = jsch.RefResolver(uri, schema, self._schemaStore,
                                            handlers=self._handler)

                if frag:
                    try:
                        schema = resolver.resolve_fragment(schema, frag)
                    except RefResolutionError, ex:
                        raise SchemaError("Unable to resolve fragment, "+frag+
                                          "from schema, "+ urib)

                cls = jsch.validator_for(schema)
                cls.check_schema(schema)
                val = cls(schema, resolver=resolver)
Beispiel #9
0
    def __init__(self,
                 schema,
                 types=(),
                 resolver=None,
                 format_checker=None,
                 skip_meta_validation=False):
        super(PandelVisitor, self).__init__(schema, types, resolver,
                                            format_checker)

        self._types.update({
            "number": (
                numbers.Number, np.number
            ),  ## type(np.nan) == builtins.float! FIXME, are numpy-numbers --> json-types OK??
            "integer": (int, np.integer),
            "boolean": (bool, np.bool_),  #, np.bool8),
            "array": (list, tuple, np.ndarray),
            "object": (dict, pd.DataFrame, pd.Series)
        })

        ## Setup Draft4/3 validation
        #
        # Meta-validate schema
        #    with original validators (and not self)
        #    because this class inherits an empty (schema/rules) validator.
        validator_class = jsonschema.validators.validator_for(
            schema)  ## Falls back to 'Draft4' if no `$schema` exists.
        self.VALIDATORS = validator_class.VALIDATORS.copy()
        self.META_SCHEMA = validator_class.META_SCHEMA
        self.VALIDATORS.update({
            'items':
            PandelVisitor._rule_items,
            'additionalProperties':
            PandelVisitor._rule_additionalProperties,
            'additionalItems':
            PandelVisitor._rule_additionalItems,
        })
        if validator_class == Draft3Validator:
            self.VALIDATORS.update({
                'properties':
                PandelVisitor._rule_properties_draft3,
            })
        else:
            self.VALIDATORS.update({
                'properties':
                PandelVisitor._rule_properties_draft4,
                'required':
                PandelVisitor._rule_required_draft4,
            })

        self.old_scopes = []

        ## Cannot use ``validator_class.check_schema()`` because
        #    need to relay my args to ``validator_class.__init__()``.
        # Even better use myself, that i'm fatser (kind of...).
        if not skip_meta_validation:
            for error in self.iter_errors(schema, validator_class.META_SCHEMA):
                raise SchemaError.create_from(error)
Beispiel #10
0
def load_schema(filename: Path) -> Dict:
    with open(filename, 'r') as f:
        try:
            if filename.suffix == '.json':
                data = json.load(f)
                return data
            elif filename.suffix == '.yaml':
                data = yaml.safe_load(f)
                return data
        except Exception as e:
            logger.debug(e)
            raise SchemaError("Schema not saved in a known format")
    return {}
Beispiel #11
0
 def _get_ssh_key(self, key):
     key_fileobj = StringIO(key)
     key_algorithms = [
         paramiko.RSAKey,
         paramiko.Ed25519Key,
     ]
     for key_algo in key_algorithms:
         try:
             return getattr(key_algo, 'from_private_key')(key_fileobj)
         except (paramiko.ssh_exception.SSHException, ValueError):
             key_fileobj.seek(0)
             continue
     else:
         raise SchemaError(
             _('Unrecognized or unsupported SSH key algorithm, '
               'only RSA and ED25519 are currently supported.'))
Beispiel #12
0
    def __init__(self, schema, types=(), resolver=None, format_checker=None, skip_meta_validation=False):
        super(PandelVisitor, self).__init__(
            schema, types, resolver, format_checker)

        self._types.update({
            # type(np.nan) == builtins.float! FIXME, are numpy-numbers -->
            # json-types OK??
            "number":   (numbers.Number, np.number),
            "integer":  (int, np.integer),
            "boolean":  (bool, np.bool_),  # , np.bool8),
            "array":    (list, tuple, np.ndarray),
            "object":  (dict, pd.DataFrame, pd.Series)
        })

        # Setup Draft4/3 validation
        #
        # Meta-validate schema
        #    with original validators (and not self)
        #    because this class inherits an empty (schema/rules) validator.
        # Falls back to 'Draft4' if no `$schema` exists.
        validator_class = jsonschema.validators.validator_for(schema)
        self.VALIDATORS = validator_class.VALIDATORS.copy()
        self.META_SCHEMA = validator_class.META_SCHEMA
        self.VALIDATORS.update({
            'items':                PandelVisitor._rule_items,
            'additionalProperties': PandelVisitor._rule_additionalProperties,
            'additionalItems':      PandelVisitor._rule_additionalItems,
        })
        if validator_class == Draft3Validator:
            self.VALIDATORS.update({
                'properties':           PandelVisitor._rule_properties_draft3,
            })
        else:
            self.VALIDATORS.update({
                'properties':           PandelVisitor._rule_properties_draft4,
                'required':             PandelVisitor._rule_required_draft4,
            })

        self.old_scopes = []

        # Cannot use ``validator_class.check_schema()`` because
        #    need to relay my args to ``validator_class.__init__()``.
        # Even better use myself, that i'm fatser (kind of...).
        if not skip_meta_validation:
            for error in self.iter_errors(schema, validator_class.META_SCHEMA):
                raise SchemaError.create_from(error)
Beispiel #13
0
def is_controlled_vocabulary(validator, value, instance, schema):
    if not isinstance(instance, str):
        yield ValidationError("%r is not a string" % instance)

    ontology = value.get('ontology', None)
    if not ontology:
        yield SchemaError('must provide "ontology" for "vocabulary" in schema')
    children_of = value.get('children_of', None)
    is_strict = value.get('strict', True)
    if not term_found_in_ontology(instance, ontology, children_of):
        err_msg = f'value "{instance}" not found in "{ontology}" ontology'
        if children_of:
            err_msg += f' (children nodes of "{children_of}")'
        if is_strict:
            # raise a valiation error, this is the default
            yield ValidationError(err_msg)
        else:
            # just print out a warning msg
            print("Warning:", err_msg)
Beispiel #14
0
 def check_schema(cls, schema):
     for error in cls(cls.META_SCHEMA).iter_errors(schema):
         raise SchemaError.create_from(error)
Beispiel #15
0
 def check_schema(cls, schema):
     for error in cls(cls.META_SCHEMA).iter_errors(schema):
         raise SchemaError.create_from(error)
Beispiel #16
0
 def check_schema(self, schema):
     from jsonschema.exceptions import SchemaError
     for error in default_meta_validator.iter_errors(schema):
         raise SchemaError.create_from(error)
Beispiel #17
0
 def custom_validation(cls, params):
     if 'password' not in params and 'key' not in params:
         raise SchemaError('Missing password or key')
Beispiel #18
0
    def validate_against(self, instance, schemauris=[], strict=False):
        """
        validate the instance against each of the schemas identified by the 
        list of schemauris.  For the instance to be considered valid, it 
        must validate against each of the named schemas.  $extensionSchema
        properties within the instance are ignored.  

        :argument instance:  a parsed JSON document to be validated.
        :argument list schemauris:  a list of URIs of the schemas to validate
                                    against.  

        :return list: a list of encountered errors in the form of exceptions; 
                      otherwise, an empty list if the instance is valid against
                      all schemas.
        """
        if isinstance(schemauris, (str, unicode)):
            schemauris = [schemauris]
        schema = None
        out = []
        for uri in schemauris:
            val = self._validators.get(uri)
            if not val:
                (urib, frag) = self._spliturifrag(uri)
                schema = self._schemaStore.get(urib)
                if not schema:
                    try:
                        schema = self._loader(urib)
                    except KeyError as e:
                        ex = MissingSchemaDocument(
                            "Unable to find schema document for " + urib)
                        if strict:
                            out.append(ex)
                        continue

                resolver = jsch.RefResolver(uri,
                                            schema,
                                            self._schemaStore,
                                            handlers=self._handler)

                if frag:
                    try:
                        schema = resolver.resolve_fragment(schema, frag)
                    except RefResolutionError as ex:
                        exc = RefResolutionError(
                            "Unable to resolve fragment, {0} from schema, {1} ({2})"
                            .format(frag, urib, str(ex)))
                        out.append(exc)
                        continue

                cls = jsch.validator_for(schema)

                # check the schema for errors
                scherrs = [ SchemaError.create_from(err) \
                            for err in cls(cls.META_SCHEMA).iter_errors(schema) ]
                if len(scherrs) > 0:
                    out.extend(scherrs)
                    continue

                val = cls(schema, resolver=resolver)

            out.extend([err for err in val.iter_errors(instance)])

            self._validators[uri] = val
            self._schemaStore.update(val.resolver.store)

        return out