diff --git a/analysis.py b/analysis.py index eaa932f1a33954fd7121a20cbc7858781f9ac045..0289f0e7f872b48945690ccdbdaa8832486521d3 100644 --- a/analysis.py +++ b/analysis.py @@ -21,6 +21,7 @@ from lxml import etree import ecs_logging +import json import logging import os import requests as requests @@ -34,6 +35,10 @@ handler.setFormatter(ecs_logging.StdlibFormatter()) logger.addHandler(handler) +with open("./xml_namespaces.json") as f: + NS = json.load(f) + + def get_metadata(): url = os.getenv('SAML2_METADATA_URL') if not url: @@ -46,7 +51,7 @@ def get_metadata(): def get_entity_descriptors(): root = get_metadata() - entity_descriptors = root.xpath("//md:EntityDescriptor", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata"}) + entity_descriptors = root.xpath("//md:EntityDescriptor", namespaces=NS) return entity_descriptors @@ -56,7 +61,7 @@ descriptors = get_entity_descriptors() idps = list() for descriptor in descriptors: - idp_search = descriptor.xpath(".//md:IDPSSODescriptor", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata"}) + idp_search = descriptor.xpath(".//md:IDPSSODescriptor", namespaces=NS) idp = dict() @@ -64,15 +69,13 @@ for descriptor in descriptors: if len(idp_search): - names = idp_search[0].xpath("./md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en']", - namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", - "mdui": "urn:oasis:names:tc:SAML:metadata:ui"}) + names = idp_search[0].xpath("./md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en']", namespaces=NS) idp["institution"] = "" if len(names): idp["institution"] = names[0].text - disco_hints = idp_search[0].xpath("./md:Extensions/mdui:DiscoHints/mdui:DomainHint", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui"}) + disco_hints = idp_search[0].xpath("./md:Extensions/mdui:DiscoHints/mdui:DomainHint", namespaces=NS) domains = [] @@ -81,7 +84,7 @@ for descriptor in descriptors: idp["disco_hints"] = domains - shib_scope = idp_search[0].xpath("./md:Extensions/shibmd:Scope", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui", "shibmd": "urn:mace:shibboleth:metadata:1.0"}) + shib_scope = idp_search[0].xpath("./md:Extensions/shibmd:Scope", namespaces=NS) idp["shib_scope"] = "" if len(shib_scope): diff --git a/attribute_mapping.json b/attribute_mapping.json index 01eda11ca3a4e03fb3b7075baca3c78538893988..437264ef90dd640e69b3e3f07d8f6ddad11eb6d2 100644 --- a/attribute_mapping.json +++ b/attribute_mapping.json @@ -1,6 +1,10 @@ { - "urn:oid:1.3.6.1.4.1.5923.1.1.1.6": "eduPersonPrincipalName", + "urn:oasis:names:tc:SAML:attribute:pairwise-id": "pairwise-id", + "urn:oasis:names:tc:SAML:attribute:subject-id": "subject-id", "urn:oid:0.9.2342.19200300.100.1.3": "mail", "urn:oid:2.16.840.1.113730.3.1.241": "displayName", + "urn:oid:2.5.4.4": "sn", + "urn:oid:2.5.4.42": "givenName", + "urn:oid:1.3.6.1.4.1.5923.1.1.1.6": "eduPersonPrincipalName", "urn:oid:1.3.6.1.4.1.5923.1.1.1.9": "eduPersonScopedAffiliation" -} \ No newline at end of file +} diff --git a/main.py b/main.py index 4f59e00f6454d3c580c26ef9d43895952fd1cf52..c0e7e5806e3f3d171f4747b3d1ffa13e9fff42c8 100644 --- a/main.py +++ b/main.py @@ -50,6 +50,7 @@ class Metadata_importer(): self.__db = self.__get_sync_db() self.__init_db() self.__get_mappings() + self.__get_xmlns() self.__get_excluded() def __get_settings(self): @@ -74,6 +75,10 @@ class Metadata_importer(): with open("./attribute_mapping.json") as f: self.mappings = json.load(f) + def __get_xmlns(self): + with open("./xml_namespaces.json") as f: + self.NS = json.load(f) + def __get_excluded(self): with open("./exclude.json") as f: self.excluded = json.load(f) @@ -192,7 +197,7 @@ class Metadata_importer(): def get_entity_descriptors(self): root = self.get_metadata() - entity_descriptors = root.xpath("//md:EntityDescriptor", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata"}) + entity_descriptors = root.xpath("//md:EntityDescriptor", namespaces=self.NS) return entity_descriptors @@ -203,8 +208,8 @@ class Metadata_importer(): idps = list() for entity_descriptor in entity_descriptors: - idp_search = entity_descriptor.xpath(".//md:IDPSSODescriptor", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata"}) - sp_search = entity_descriptor.xpath(".//md:SPSSODescriptor", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata"}) + idp_search = entity_descriptor.xpath(".//md:IDPSSODescriptor", namespaces=self.NS) + sp_search = entity_descriptor.xpath(".//md:SPSSODescriptor", namespaces=self.NS) if len(idp_search): idps.append(entity_descriptor) elif len(sp_search): @@ -254,10 +259,10 @@ class Metadata_importer(): logger.warning("failed", extra={"error": obj["error"]}) continue obj = self.postprocess_client_obj(sp, obj) - displayName_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en']", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui"}) - description_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:Description[@xml:lang='en']", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui"}) - # privacynote_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:PrivacyStatementURL[@xml:lang='en']", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui"}) - logo_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:Logo", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui"}) + displayName_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en']", namespaces=self.NS) + description_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:Description[@xml:lang='en']", namespaces=self.NS) + # privacynote_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:PrivacyStatementURL[@xml:lang='en']", namespaces=self.NS) + logo_nodes = sp.xpath(".//md:Extensions/mdui:UIInfo/mdui:Logo", namespaces=self.NS) if len(description_nodes): obj["description"] = description_nodes[0].text[:255] @@ -311,10 +316,10 @@ class Metadata_importer(): for idp in idps: hints = set() - discoHints = idp.xpath(".//mdui:DomainHint", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui"}) - scope = idp.xpath(".//shibmd:Scope", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui", "shibmd": "urn:mace:shibboleth:metadata:1.0"})[0].text + discoHints = idp.xpath(".//mdui:DomainHint", namespaces=self.NS) + scope = idp.xpath(".//shibmd:Scope", namespaces=self.NS)[0].text - displayName = idp.xpath(".//md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en']", namespaces={"md": "urn:oasis:names:tc:SAML:2.0:metadata", "mdui": "urn:oasis:names:tc:SAML:metadata:ui"})[0].text + displayName = idp.xpath(".//md:Extensions/mdui:UIInfo/mdui:DisplayName[@xml:lang='en']", namespaces=self.NS)[0].text hints.add(scope) diff --git a/xml_namespaces.json b/xml_namespaces.json new file mode 100644 index 0000000000000000000000000000000000000000..a35945e4d10d5a9fd60fc636b240adb45ff1a827 --- /dev/null +++ b/xml_namespaces.json @@ -0,0 +1,5 @@ +{ + "md" : "urn:oasis:names:tc:SAML:2.0:metadata", + "mdui" : "urn:oasis:names:tc:SAML:metadata:ui", + "shibmd" : "urn:mace:shibboleth:metadata:1.0" +}