1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
import sys
# importlib.resources was introduced in python 3.7
# files API from importlib.resources introduced in python 3.9
if sys.version_info[:2] >= (3, 9):
from importlib.resources import files as _resource_files
else:
from importlib_resources import files as _resource_files
from xmlschema import XMLSchema as _XMLSchema
from xmlschema.exceptions import XMLSchemaException as _XMLSchemaException
import saml2.data.schemas as _data_schemas
class XMLSchemaError(Exception):
"""Generic error raised when the schema does not validate with a document"""
def _create_xml_schema_validator(source=None, **kwargs):
schema_resources = _resource_files(_data_schemas)
path_schema_xml = str(schema_resources.joinpath("xml.xsd"))
path_schema_envelope = str(schema_resources.joinpath("envelope.xsd"))
path_schema_xenc = str(schema_resources.joinpath("xenc-schema.xsd"))
path_schema_xmldsig_core = str(schema_resources.joinpath("xmldsig-core-schema.xsd"))
path_schema_saml_assertion = str(
schema_resources.joinpath("saml-schema-assertion-2.0.xsd")
)
path_schema_saml_metadata = str(
schema_resources.joinpath("saml-schema-metadata-2.0.xsd")
)
path_schema_saml_protocol = str(
schema_resources.joinpath("saml-schema-protocol-2.0.xsd")
)
path_schema_eidas_metadata_servicelist= str(
schema_resources.joinpath("eidas-schema-metadata-servicelist.xsd")
)
path_schema_eidas_saml_extensions = str(
schema_resources.joinpath("eidas-schema-saml-extensions.xsd")
)
path_schema_eidas_attribute_naturalperson = str(
schema_resources.joinpath("eidas-schema-attribute-naturalperson.xsd")
)
path_schema_eidas_attribute_legalperson = str(
schema_resources.joinpath("eidas-schema-attribute-legalperson.xsd")
)
source = source if source else path_schema_saml_protocol
locations = {
"http://www.w3.org/XML/1998/namespace": path_schema_xml,
"http://schemas.xmlsoap.org/soap/envelope/": path_schema_envelope,
"http://www.w3.org/2001/04/xmlenc#": path_schema_xenc,
"http://www.w3.org/2000/09/xmldsig#": path_schema_xmldsig_core,
"urn:oasis:names:tc:SAML:2.0:assertion": path_schema_saml_assertion,
"urn:oasis:names:tc:SAML:2.0:metadata": path_schema_saml_metadata,
"urn:oasis:names:tc:SAML:2.0:protocol": path_schema_saml_protocol,
"http://eidas.europa.eu/metadata/servicelist": path_schema_eidas_metadata_servicelist,
"http://eidas.europa.eu/saml-extensions": path_schema_eidas_saml_extensions,
"http://eidas.europa.eu/attributes/naturalperson": path_schema_eidas_attribute_naturalperson,
"http://eidas.europa.eu/attributes/legalperson": path_schema_eidas_attribute_legalperson,
}
kwargs = {
**kwargs,
"validation": "strict",
"locations": locations,
"base_url": source,
"allow": "sandbox",
"use_fallback": False,
}
return _XMLSchema(source, **kwargs)
_schema_validator_default = _create_xml_schema_validator()
def validate(doc, validator=None):
validator = _schema_validator_default if validator is None else validator
try:
validator.validate(doc)
except _XMLSchemaException as e:
error_context = {
"doc": doc,
"error": str(e),
}
raise XMLSchemaError(error_context) from e
except Exception as e:
error_context = {
"doc": doc,
"error": str(e),
}
raise XMLSchemaError(error_context) from e
|