Esempio n. 1
0
    def test_it_delegates_to_a_ref_resolver(self):
        ref, schema = "someCoolRef", {"type": "integer"}
        resolver = validators.RefResolver("", {}, store={ref: schema})
        validator = self.Validator({"$ref": ref}, resolver=resolver)

        with self.assertRaises(ValidationError):
            validator.validate(None)
Esempio n. 2
0
def _make_resolver(url_mapping):
    handlers = {}
    schema_loader = _make_schema_loader(url_mapping)

    def get_schema(url):
        return schema_loader(url)[0]

    for x in ['http', 'https', 'file', 'tag', 'asdf']:
        handlers[x] = get_schema

    # Supplying our own implementation of urljoin_cache
    # allows asdf:// URIs to be resolved correctly.
    urljoin_cache = lru_cache(1024)(patched_urllib_parse.urljoin)

    # We set cache_remote=False here because we do the caching of
    # remote schemas here in `load_schema`, so we don't need
    # jsonschema to do it on our behalf.  Setting it to `True`
    # counterintuitively makes things slower.
    return mvalidators.RefResolver(
        '',
        {},
        cache_remote=False,
        handlers=handlers,
        urljoin_cache=urljoin_cache,
    )
Esempio n. 3
0
def create_spec(spec_dict: dict) -> models.Spec:
    """Create and return the OpenAPI v3 Spec Model"""
    spec_resolver = jsonschema_validators.RefResolver(
        '', spec_dict, handlers=openapi_spec_validator.default_handlers)
    spec_factory = factories.SpecFactory(
        spec_resolver, config={'validate_spec': False})
    return spec_factory.create(spec_dict, spec_url='')
Esempio n. 4
0
 def setUp(self):
     self.referrer = {}
     self.store = {self.stored_uri: self.stored_schema}
     self.resolver = validators.RefResolver(
         self.base_uri,
         self.referrer,
         self.store,
     )
Esempio n. 5
0
def scrub_index_data(index_data: dict, bundle_id: str) -> list:
    cache = S3UrlCache()

    def request_json(url):
        return json.loads(cache.resolve(url).decode("utf-8"))

    resolver = validators.RefResolver(referrer='',
                                      base_uri='',
                                      handlers={
                                          'http': request_json,
                                          'https': request_json
                                      })
    extra_fields = []
    extra_documents = []
    for document in index_data.keys():
        for doc_list_ind, document_content in enumerate(index_data[document]):
            schema_info = SchemaInfo.from_json(document_content)
            if schema_info is not None:
                try:
                    schema = request_json(schema_info.url)
                except Exception as ex:
                    extra_documents.append(document)
                    logger.warning(
                        f"Unable to retrieve JSON schema information from {document} in bundle {bundle_id} "
                        f"because retrieving {schema_info.url} caused exception: {ex}."
                    )
                else:
                    for error in DSS_Draft4Validator(
                            schema,
                            resolver=resolver).iter_errors(document_content):
                        if error.validator == 'additionalProperties':
                            path = [document, doc_list_ind, *error.path]
                            #  Example error message: "Additional properties are not allowed ('extra_lst', 'extra_top'
                            #  were unexpected)" or "'extra', does not match any of the regexes: '^characteristics_.*$'"
                            fields_to_remove = (path, [
                                field
                                for field in _utils.find_additional_properties(
                                    error.instance, error.schema)
                            ])
                            extra_fields.append(fields_to_remove)
            else:
                logger.warning(
                    f"Unable to retrieve JSON schema information from {document} in bundle {bundle_id}."
                )
                extra_documents.append(document)

    if extra_documents:
        extra_fields.append(([], extra_documents))
    removed_fields = []
    for path, fields in extra_fields:
        remove_json_fields(index_data, path, fields)
        removed_fields.extend(
            ['.'.join((*[str(p) for p in path], field)) for field in fields])
    if removed_fields:
        logger.info(
            f"In {bundle_id}, unexpected additional fields have been removed from the data"
            f" to be indexed. Removed {removed_fields}.")
    return removed_fields
 def test_cache_remote_off(self):
     ref = "foo://bar"
     foo_handler = mock.Mock()
     resolver = validators.RefResolver(
         "", {}, cache_remote=False, handlers={"foo": foo_handler},
     )
     with resolver.resolving(ref):
         pass
     self.assertEqual(foo_handler.call_count, 1)
 def test_if_you_give_it_junk_you_get_a_resolution_error(self):
     ref = "foo://bar"
     foo_handler = mock.Mock(side_effect=ValueError("Oh no! What's this?"))
     resolver = validators.RefResolver(
         "", {}, handlers={"foo": foo_handler},
     )
     with self.assertRaises(validators.RefResolutionError) as err:
         with resolver.resolving(ref):
             pass
     self.assertEqual(str(err.exception), "Oh no! What's this?")
Esempio n. 8
0
    def test_it_delegates_to_a_ref_resolver(self):
        resolver = validators.RefResolver("", {})
        schema = {"$ref": mock.Mock()}

        with mock.patch.object(resolver, "resolve") as resolve:
            resolve.return_value = "url", {"type": "integer"}
            with self.assertRaises(ValidationError):
                self.validator_class(schema, resolver=resolver).validate(None)

        resolve.assert_called_once_with(schema["$ref"])
Esempio n. 9
0
    def test_custom_uri_scheme_handlers(self):
        def handler(url):
            self.assertEqual(url, ref)
            return schema

        schema = {"foo": "bar"}
        ref = "foo://bar"
        resolver = validators.RefResolver("", {}, handlers={"foo": handler})
        with resolver.resolving(ref) as resolved:
            self.assertEqual(resolved, schema)
Esempio n. 10
0
 def test_custom_uri_scheme_handlers(self):
     schema = {"foo": "bar"}
     ref = "foo://bar"
     foo_handler = mock.Mock(return_value=schema)
     resolver = validators.RefResolver(
         "", {}, handlers={"foo": foo_handler},
     )
     with resolver.resolving(ref) as resolved:
         self.assertEqual(resolved, schema)
     foo_handler.assert_called_once_with(ref)
Esempio n. 11
0
 def test_cache_remote_on(self):
     ref = "foo://bar"
     foo_handler = mock.Mock()
     resolver = validators.RefResolver(
         "", {}, cache_remote=True, handlers={"foo": foo_handler},
     )
     with resolver.resolving(ref):
         pass
     with resolver.resolving(ref):
         pass
     foo_handler.assert_called_once_with(ref)
Esempio n. 12
0
    def test_if_you_give_it_junk_you_get_a_resolution_error(self):
        error = ValueError("Oh no! What's this?")

        def handler(url):
            raise error

        ref = "foo://bar"
        resolver = validators.RefResolver("", {}, handlers={"foo": handler})
        with self.assertRaises(validators.RefResolutionError) as err:
            with resolver.resolving(ref):
                self.fail("Shouldn't get this far!")  # pragma: no cover
        self.assertEqual(err.exception, validators.RefResolutionError(error))
Esempio n. 13
0
def _make_resolver(url_mapping):
    handlers = {}
    schema_loader = _make_schema_loader(url_mapping)
    for x in ['http', 'https', 'file']:
        handlers[x] = schema_loader

    # We set cache_remote=False here because we do the caching of
    # remote schemas here in `load_schema`, so we don't need
    # jsonschema to do it on our behalf.  Setting it to `True`
    # counterintuitively makes things slower.
    return validators.RefResolver('', {},
                                  cache_remote=False,
                                  handlers=handlers)
Esempio n. 14
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)
Esempio n. 15
0
    def test_cache_remote_off(self):
        response = [object()]

        def handler(url):
            try:
                return response.pop()
            except IndexError:  # pragma: no cover
                self.fail("Handler called twice!")

        ref = "foo://bar"
        resolver = validators.RefResolver(
            "",
            {},
            cache_remote=False,
            handlers={"foo": handler},
        )
        with resolver.resolving(ref):
            pass
Esempio n. 16
0
    def test_cache_remote_on(self):
        response = [object()]

        def handler(url):
            try:
                return response.pop()
            except IndexError:  # pragma: no cover
                self.fail("Response must not have been cached!")

        ref = "foo://bar"
        resolver = validators.RefResolver(
            "",
            {},
            cache_remote=True,
            handlers={"foo": handler},
        )
        with resolver.resolving(ref):
            pass
        with resolver.resolving(ref):
            pass
Esempio n. 17
0
def validate(instance, schema, resolver=None, *args, **kwargs):
    """
    Validate the given instance against the given schema using the
    YAML schema extensions to JSON schema.

    The arguments are the same as to `jsonschema.validate`.
    """
    create_validator()

    handlers = {}
    for x in ['http', 'https', 'file']:
        handlers[x] = _make_schema_loader(resolver)
    kwargs['resolver'] = validators.RefResolver(schema.get('id', ''),
                                                schema,
                                                cache_remote=False,
                                                handlers=handlers)

    # We don't just call validators.validate() directly here, because
    # that validates the schema itself, wasting a lot of time (at the
    # time of this writing, it was half of the runtime of the unit
    # test suite!!!).  Instead, we assume that the schemas are valid
    # through the running of the unit tests, not at run time.
    cls = validators.validator_for(schema)
    cls(schema, *args, **kwargs).validate(instance)
Esempio n. 18
0
 def test_helpful_error_message_on_failed_pop_scope(self):
     resolver = validators.RefResolver("", {})
     resolver.pop_scope()
     with self.assertRaises(validators.RefResolutionError) as exc:
         resolver.pop_scope()
     self.assertIn("Failed to pop the scope", str(exc.exception))
Esempio n. 19
0
 def test_False_is_not_a_schema_even_if_you_forget_to_check(self):
     resolver = validators.RefResolver("", {})
     with self.assertRaises(TypeError):
         self.Validator(False, resolver=resolver).validate(12)
Esempio n. 20
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