66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
import pytest
|
|
|
|
from app.schema_security import (
|
|
ExternalSchemaReferenceError,
|
|
UnresolvableLocalSchemaReferenceError,
|
|
reject_external_schema_references,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"schema",
|
|
[
|
|
{"$ref": "file:///host/private-schema.json"},
|
|
{"properties": {"value": {"$ref": "https://schema.invalid/value.json"}}},
|
|
{"allOf": [{"$dynamicRef": "https://schema.invalid/dynamic"}]},
|
|
],
|
|
)
|
|
def test_external_json_schema_references_are_rejected(schema) -> None:
|
|
with pytest.raises(ExternalSchemaReferenceError):
|
|
reject_external_schema_references(schema)
|
|
|
|
|
|
def test_local_json_schema_fragment_reference_is_allowed() -> None:
|
|
reject_external_schema_references(
|
|
{
|
|
"$defs": {"value": {"type": "string"}},
|
|
"properties": {"value": {"$ref": "#/$defs/value"}},
|
|
}
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("reference", ["#/$defs/missing", "#missing-anchor"])
|
|
def test_unresolvable_local_schema_reference_is_rejected(reference: str) -> None:
|
|
with pytest.raises(UnresolvableLocalSchemaReferenceError):
|
|
reject_external_schema_references({"type": "object", "$ref": reference})
|
|
|
|
|
|
def test_root_reference_cannot_use_anchor_from_nested_schema_resource() -> None:
|
|
schema = {
|
|
"$defs": {
|
|
"nested": {
|
|
"$id": "nested",
|
|
"$anchor": "inside",
|
|
"type": "string",
|
|
}
|
|
},
|
|
"properties": {"value": {"$ref": "#inside"}},
|
|
}
|
|
|
|
with pytest.raises(UnresolvableLocalSchemaReferenceError):
|
|
reject_external_schema_references(schema)
|
|
|
|
|
|
def test_nested_schema_resource_can_resolve_its_own_anchor() -> None:
|
|
schema = {
|
|
"$defs": {
|
|
"nested": {
|
|
"$id": "nested",
|
|
"$anchor": "inside",
|
|
"allOf": [{"$ref": "#inside"}],
|
|
}
|
|
}
|
|
}
|
|
|
|
reject_external_schema_references(schema)
|