149 lines
4.2 KiB
Python
Executable File
149 lines
4.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
from saml2 import metadata, element_to_extension_element
|
|
from saml2 import SamlBase
|
|
from saml2 import extension_elements_as_dict
|
|
from saml2 import saml
|
|
from saml2 import md
|
|
from saml2.attribute_converter import ac_factory
|
|
|
|
from saml2.extension import mdui
|
|
from saml2.extension import idpdisc
|
|
from saml2.extension import dri
|
|
from saml2.extension import mdattr
|
|
from saml2.extension import ui
|
|
import xmldsig
|
|
import xmlenc
|
|
|
|
__author__ = 'rolandh'
|
|
|
|
"""
|
|
A script that imports and verifies metadata and stores it in a pysaml2 format
|
|
"""
|
|
|
|
MDIMPORT = {
|
|
"swamid": {
|
|
"url": "https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2",
|
|
"cert":"kalmar2.pem"
|
|
},
|
|
# "incommon": {
|
|
# "url": "file://InCommon-metadata.xml"
|
|
# }
|
|
}
|
|
|
|
ATTRCONV = ac_factory("attributemaps")
|
|
|
|
def _eval(val):
|
|
if isinstance(val, basestring):
|
|
val = val.strip()
|
|
if not val:
|
|
return None
|
|
else:
|
|
return val
|
|
elif isinstance(val, dict) or isinstance(val, SamlBase):
|
|
return to_dict(val)
|
|
elif isinstance(val, list):
|
|
lv = []
|
|
for v in val:
|
|
if isinstance(v, dict) or isinstance(v, SamlBase):
|
|
lv.append(to_dict(v))
|
|
else:
|
|
lv.append(v)
|
|
return lv
|
|
return val
|
|
|
|
def to_dict(_dict):
|
|
res = {}
|
|
if isinstance(_dict, SamlBase):
|
|
res["__type__"] = "%s&%s" % (_dict.c_namespace,_dict.c_tag)
|
|
for key in _dict.keyswv():
|
|
val = getattr(_dict, key)
|
|
if key == "extension_elements":
|
|
_eed = extension_elements_as_dict(val, [idpdisc, mdui,
|
|
ui, dri, mdattr,
|
|
saml])
|
|
_val = {}
|
|
for key, _v in _eed.items():
|
|
_val[key] = _eval(_v)
|
|
else:
|
|
_val = _eval(val)
|
|
if _val:
|
|
res[key] = _val
|
|
else:
|
|
for key, val in _dict.items():
|
|
_val = _eval(val)
|
|
if _val:
|
|
res[key] = _val
|
|
return res
|
|
|
|
metad = metadata.MetaData(xmlsec_binary="/opt/local/bin/xmlsec1",
|
|
attrconv=ATTRCONV)
|
|
|
|
for key, spec in MDIMPORT.items():
|
|
url = spec["url"]
|
|
if url.startswith("file://"):
|
|
metad.import_metadata(open(url[7:]).read(),key)
|
|
else:
|
|
metad.import_external_metadata(url, spec["cert"])
|
|
|
|
_dict = to_dict(metad.entity)
|
|
|
|
#print _dict
|
|
SKIP = ["__type__", "_certs"]
|
|
|
|
def _kwa(val, onts):
|
|
return dict([(k,_x(v, onts)) for k,v in val.items() if k not in SKIP])
|
|
|
|
def _x(val, onts):
|
|
if isinstance(val, dict):
|
|
if "__type__" in val:
|
|
ns, typ = val["__type__"].split("&")
|
|
cls = getattr(onts[ns], typ)
|
|
if cls is md.Extensions:
|
|
lv = []
|
|
for key, ditems in val.items():
|
|
if key in SKIP:
|
|
continue
|
|
for _k, items in ditems.items():
|
|
for item in items:
|
|
ns, typ = item["__type__"].split("&")
|
|
cls = getattr(onts[ns], typ)
|
|
kwargs = _kwa(item, onts)
|
|
inst = cls(**kwargs)
|
|
lv.append(element_to_extension_element(inst))
|
|
return lv
|
|
else:
|
|
kwargs = _kwa(val, onts)
|
|
inst = cls(**kwargs)
|
|
return inst
|
|
else:
|
|
res = {}
|
|
for key, v in val.items():
|
|
res[key] = _x(v, onts)
|
|
return res
|
|
elif isinstance(val, basestring):
|
|
return val
|
|
elif isinstance(val, list):
|
|
return [_x(v, onts) for v in val]
|
|
else:
|
|
return val
|
|
|
|
def from_dict(_dict, onts):
|
|
res = {}
|
|
for key, val in _dict.items():
|
|
res[key] = _x(val, onts)
|
|
|
|
ONTS = {
|
|
saml.NAMESPACE: saml,
|
|
mdui.NAMESPACE: mdui,
|
|
mdattr.NAMESPACE: mdattr,
|
|
dri.NAMESPACE: dri,
|
|
ui.NAMESPACE: ui,
|
|
idpdisc.NAMESPACE: idpdisc,
|
|
md.NAMESPACE: md,
|
|
xmldsig.NAMESPACE: xmldsig,
|
|
xmlenc.NAMESPACE: xmlenc
|
|
}
|
|
|
|
res = from_dict(_dict, ONTS)
|
|
|
|
print res[res.keys()[0]] |