Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -844,6 +844,14 @@ def extension_elements_to_elements(extension_elements, schemas):
|
|||||||
according to the schemas.
|
according to the schemas.
|
||||||
"""
|
"""
|
||||||
res = []
|
res = []
|
||||||
|
|
||||||
|
if isinstance(schemas, list):
|
||||||
|
pass
|
||||||
|
elif isinstance(schemas, dict):
|
||||||
|
schemas = schemas.values()
|
||||||
|
else:
|
||||||
|
return res
|
||||||
|
|
||||||
for extension_element in extension_elements:
|
for extension_element in extension_elements:
|
||||||
for schema in schemas:
|
for schema in schemas:
|
||||||
inst = extension_element_to_element(extension_element,
|
inst = extension_element_to_element(extension_element,
|
||||||
|
@@ -117,7 +117,8 @@ class Saml2Client(Base):
|
|||||||
entity_ids = self.users.issuers_of_info(name_id)
|
entity_ids = self.users.issuers_of_info(name_id)
|
||||||
return self.do_logout(name_id, entity_ids, reason, expire, sign)
|
return self.do_logout(name_id, entity_ids, reason, expire, sign)
|
||||||
|
|
||||||
def do_logout(self, name_id, entity_ids, reason, expire, sign=None):
|
def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
|
||||||
|
expected_binding=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param name_id: Identifier of the Subject (a NameID instance)
|
:param name_id: Identifier of the Subject (a NameID instance)
|
||||||
@@ -126,6 +127,8 @@ class Saml2Client(Base):
|
|||||||
:param reason: The reason for doing the logout
|
:param reason: The reason for doing the logout
|
||||||
:param expire: Try to logout before this time.
|
:param expire: Try to logout before this time.
|
||||||
:param sign: Whether to sign the request or not
|
:param sign: Whether to sign the request or not
|
||||||
|
:param expected_binding: Specify the expected binding then not try it
|
||||||
|
all
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
# check time
|
# check time
|
||||||
@@ -142,6 +145,8 @@ class Saml2Client(Base):
|
|||||||
# for all where I can use the SOAP binding, do those first
|
# for all where I can use the SOAP binding, do those first
|
||||||
for binding in [BINDING_SOAP, BINDING_HTTP_POST,
|
for binding in [BINDING_SOAP, BINDING_HTTP_POST,
|
||||||
BINDING_HTTP_REDIRECT]:
|
BINDING_HTTP_REDIRECT]:
|
||||||
|
if expected_binding and binding != expected_binding:
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
srvs = self.metadata.single_logout_service(entity_id,
|
srvs = self.metadata.single_logout_service(entity_id,
|
||||||
binding,
|
binding,
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
__author__ = 'rolandh'
|
__author__ = 'rolandh'
|
||||||
|
|
||||||
|
import copy
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -48,7 +49,7 @@ ONTS = {
|
|||||||
|
|
||||||
COMMON_ARGS = [
|
COMMON_ARGS = [
|
||||||
"entityid", "xmlsec_binary", "debug", "key_file", "cert_file",
|
"entityid", "xmlsec_binary", "debug", "key_file", "cert_file",
|
||||||
"secret", "accepted_time_diff", "name", "ca_certs",
|
"encryption_type", "secret", "accepted_time_diff", "name", "ca_certs",
|
||||||
"description", "valid_for", "verify_ssl_cert",
|
"description", "valid_for", "verify_ssl_cert",
|
||||||
"organization",
|
"organization",
|
||||||
"contact_person",
|
"contact_person",
|
||||||
@@ -175,6 +176,7 @@ class Config(object):
|
|||||||
self.debug = False
|
self.debug = False
|
||||||
self.key_file = None
|
self.key_file = None
|
||||||
self.cert_file = None
|
self.cert_file = None
|
||||||
|
self.encryption_type = 'both'
|
||||||
self.secret = None
|
self.secret = None
|
||||||
self.accepted_time_diff = None
|
self.accepted_time_diff = None
|
||||||
self.name = None
|
self.name = None
|
||||||
@@ -349,7 +351,7 @@ class Config(object):
|
|||||||
|
|
||||||
mod = self._load(config_file)
|
mod = self._load(config_file)
|
||||||
#return self.load(eval(open(config_file).read()))
|
#return self.load(eval(open(config_file).read()))
|
||||||
return self.load(mod.CONFIG, metadata_construction)
|
return self.load(copy.deepcopy(mod.CONFIG), metadata_construction)
|
||||||
|
|
||||||
def load_metadata(self, metadata_conf):
|
def load_metadata(self, metadata_conf):
|
||||||
""" Loads metadata into an internal structure """
|
""" Loads metadata into an internal structure """
|
||||||
|
@@ -291,7 +291,8 @@ class Entity(HTTPBase):
|
|||||||
def unravel(self, txt, binding, msgtype="response"):
|
def unravel(self, txt, binding, msgtype="response"):
|
||||||
#logger.debug("unravel '%s'" % txt)
|
#logger.debug("unravel '%s'" % txt)
|
||||||
if binding not in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST,
|
if binding not in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST,
|
||||||
BINDING_SOAP, BINDING_URI, None]:
|
BINDING_SOAP, BINDING_URI, BINDING_HTTP_ARTIFACT,
|
||||||
|
None]:
|
||||||
raise ValueError("Don't know how to handle '%s'" % binding)
|
raise ValueError("Don't know how to handle '%s'" % binding)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -302,6 +303,8 @@ class Entity(HTTPBase):
|
|||||||
elif binding == BINDING_SOAP:
|
elif binding == BINDING_SOAP:
|
||||||
func = getattr(soap, "parse_soap_enveloped_saml_%s" % msgtype)
|
func = getattr(soap, "parse_soap_enveloped_saml_%s" % msgtype)
|
||||||
xmlstr = func(txt)
|
xmlstr = func(txt)
|
||||||
|
elif binding == BINDING_HTTP_ARTIFACT:
|
||||||
|
xmlstr = base64.b64decode(txt)
|
||||||
else:
|
else:
|
||||||
xmlstr = txt
|
xmlstr = txt
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@@ -120,6 +120,9 @@ class IdentDB(object):
|
|||||||
|
|
||||||
_id = "%s@%s" % (_id, self.domain)
|
_id = "%s@%s" % (_id, self.domain)
|
||||||
|
|
||||||
|
if nformat == NAMEID_FORMAT_PERSISTENT:
|
||||||
|
_id = userid
|
||||||
|
|
||||||
nameid = NameID(format=nformat, sp_name_qualifier=sp_name_qualifier,
|
nameid = NameID(format=nformat, sp_name_qualifier=sp_name_qualifier,
|
||||||
name_qualifier=name_qualifier, text=_id)
|
name_qualifier=name_qualifier, text=_id)
|
||||||
|
|
||||||
@@ -281,7 +284,7 @@ class IdentDB(object):
|
|||||||
# else create and return a new one
|
# else create and return a new one
|
||||||
return self.construct_nameid(_id, name_id_policy=name_id_policy)
|
return self.construct_nameid(_id, name_id_policy=name_id_policy)
|
||||||
|
|
||||||
def handle_manage_name_id_request(self, name_id, new_id="",
|
def handle_manage_name_id_request(self, name_id, new_id=None,
|
||||||
new_encrypted_id="", terminate=""):
|
new_encrypted_id="", terminate=""):
|
||||||
"""
|
"""
|
||||||
Requests from the SP is about the SPProvidedID attribute.
|
Requests from the SP is about the SPProvidedID attribute.
|
||||||
|
@@ -103,12 +103,13 @@ def repack_cert(cert):
|
|||||||
|
|
||||||
|
|
||||||
class MetaData(object):
|
class MetaData(object):
|
||||||
def __init__(self, onts, attrc, metadata=""):
|
def __init__(self, onts, attrc, metadata="", node_name=None, **kwargs):
|
||||||
self.onts = onts
|
self.onts = onts
|
||||||
self.attrc = attrc
|
self.attrc = attrc
|
||||||
self.entity = {}
|
self.entity = {}
|
||||||
self.metadata = metadata
|
self.metadata = metadata
|
||||||
self.security = None
|
self.security = None
|
||||||
|
self.node_name = node_name
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
return self.entity.items()
|
return self.entity.items()
|
||||||
@@ -371,8 +372,8 @@ class MetaDataFile(MetaData):
|
|||||||
Handles Metadata file on the same machine. The format of the file is
|
Handles Metadata file on the same machine. The format of the file is
|
||||||
the SAML Metadata format.
|
the SAML Metadata format.
|
||||||
"""
|
"""
|
||||||
def __init__(self, onts, attrc, filename, cert=None):
|
def __init__(self, onts, attrc, filename, cert=None, **kwargs):
|
||||||
MetaData.__init__(self, onts, attrc)
|
MetaData.__init__(self, onts, attrc, **kwargs)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.cert = cert
|
self.cert = cert
|
||||||
|
|
||||||
@@ -382,7 +383,8 @@ class MetaDataFile(MetaData):
|
|||||||
def load(self):
|
def load(self):
|
||||||
_txt = self.get_metadata_content()
|
_txt = self.get_metadata_content()
|
||||||
if self.cert:
|
if self.cert:
|
||||||
node_name = "%s:%s" % (md.EntitiesDescriptor.c_namespace,
|
node_name = self.node_name \
|
||||||
|
or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
|
||||||
md.EntitiesDescriptor.c_tag)
|
md.EntitiesDescriptor.c_tag)
|
||||||
|
|
||||||
if self.security.verify_signature(_txt,
|
if self.security.verify_signature(_txt,
|
||||||
@@ -400,8 +402,8 @@ class MetaDataLoader(MetaDataFile):
|
|||||||
Handles Metadata file loaded by a passed in function.
|
Handles Metadata file loaded by a passed in function.
|
||||||
The format of the file is the SAML Metadata format.
|
The format of the file is the SAML Metadata format.
|
||||||
"""
|
"""
|
||||||
def __init__(self, onts, attrc, loader_callable, cert=None):
|
def __init__(self, onts, attrc, loader_callable, cert=None, **kwargs):
|
||||||
MetaData.__init__(self, onts, attrc)
|
MetaData.__init__(self, onts, attrc, **kwargs)
|
||||||
self.metadata_provider_callable = self.get_metadata_loader(loader_callable)
|
self.metadata_provider_callable = self.get_metadata_loader(loader_callable)
|
||||||
self.cert = cert
|
self.cert = cert
|
||||||
|
|
||||||
@@ -444,7 +446,7 @@ class MetaDataExtern(MetaData):
|
|||||||
Accessible but HTTP GET.
|
Accessible but HTTP GET.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, onts, attrc, url, security, cert, http):
|
def __init__(self, onts, attrc, url, security, cert, http, **kwargs):
|
||||||
"""
|
"""
|
||||||
:params onts:
|
:params onts:
|
||||||
:params attrc:
|
:params attrc:
|
||||||
@@ -453,7 +455,7 @@ class MetaDataExtern(MetaData):
|
|||||||
:params cert:
|
:params cert:
|
||||||
:params http:
|
:params http:
|
||||||
"""
|
"""
|
||||||
MetaData.__init__(self, onts, attrc)
|
MetaData.__init__(self, onts, attrc, **kwargs)
|
||||||
self.url = url
|
self.url = url
|
||||||
self.security = security
|
self.security = security
|
||||||
self.cert = cert
|
self.cert = cert
|
||||||
@@ -466,7 +468,8 @@ class MetaDataExtern(MetaData):
|
|||||||
"""
|
"""
|
||||||
response = self.http.send(self.url)
|
response = self.http.send(self.url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
node_name = "%s:%s" % (md.EntitiesDescriptor.c_namespace,
|
node_name = self.node_name \
|
||||||
|
or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
|
||||||
md.EntitiesDescriptor.c_tag)
|
md.EntitiesDescriptor.c_tag)
|
||||||
|
|
||||||
_txt = response.text.encode("utf-8")
|
_txt = response.text.encode("utf-8")
|
||||||
@@ -480,7 +483,7 @@ class MetaDataExtern(MetaData):
|
|||||||
self.parse(_txt)
|
self.parse(_txt)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logger.info("Response status: %s" % response.status)
|
logger.info("Response status: %s" % response.status_code)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -489,8 +492,8 @@ class MetaDataMD(MetaData):
|
|||||||
Handles locally stored metadata, the file format is the text representation
|
Handles locally stored metadata, the file format is the text representation
|
||||||
of the Python representation of the metadata.
|
of the Python representation of the metadata.
|
||||||
"""
|
"""
|
||||||
def __init__(self, onts, attrc, filename):
|
def __init__(self, onts, attrc, filename, **kwargs):
|
||||||
MetaData.__init__(self, onts, attrc)
|
MetaData.__init__(self, onts, attrc, **kwargs)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
@@ -523,12 +526,13 @@ class MetadataStore(object):
|
|||||||
elif typ == "inline":
|
elif typ == "inline":
|
||||||
self.ii += 1
|
self.ii += 1
|
||||||
key = self.ii
|
key = self.ii
|
||||||
md = MetaData(self.onts, self.attrc, args[0])
|
md = MetaData(self.onts, self.attrc, args[0], **kwargs)
|
||||||
elif typ == "remote":
|
elif typ == "remote":
|
||||||
key = kwargs["url"]
|
key = kwargs["url"]
|
||||||
md = MetaDataExtern(self.onts, self.attrc,
|
md = MetaDataExtern(self.onts, self.attrc,
|
||||||
kwargs["url"], self.security,
|
kwargs["url"], self.security,
|
||||||
kwargs["cert"], self.http)
|
kwargs["cert"], self.http,
|
||||||
|
node_name=kwargs.get('node_name'))
|
||||||
elif typ == "mdfile":
|
elif typ == "mdfile":
|
||||||
key = args[0]
|
key = args[0]
|
||||||
md = MetaDataMD(self.onts, self.attrc, args[0])
|
md = MetaDataMD(self.onts, self.attrc, args[0])
|
||||||
@@ -804,7 +808,7 @@ class MetadataStore(object):
|
|||||||
res = []
|
res = []
|
||||||
for md in self.metadata.values():
|
for md in self.metadata.values():
|
||||||
for ent_id, ent_desc in md.items():
|
for ent_id, ent_desc in md.items():
|
||||||
if "spsso_descriptor" in ent_desc:
|
if descriptor in ent_desc:
|
||||||
res.append(ent_id)
|
res.append(ent_id)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
@@ -197,7 +197,7 @@ def do_key_descriptor(cert, use="both"):
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
elif use in ["signing", "encryption"]:
|
elif use in ["signing", "encryption"]:
|
||||||
md.KeyDescriptor(
|
return md.KeyDescriptor(
|
||||||
key_info=ds.KeyInfo(
|
key_info=ds.KeyInfo(
|
||||||
x509_data=ds.X509Data(
|
x509_data=ds.X509Data(
|
||||||
x509_certificate=ds.X509Certificate(text=cert)
|
x509_certificate=ds.X509Certificate(text=cert)
|
||||||
@@ -429,7 +429,8 @@ def do_spsso_descriptor(conf, cert=None):
|
|||||||
spsso.extensions.add_extension_element(val)
|
spsso.extensions.add_extension_element(val)
|
||||||
|
|
||||||
if cert:
|
if cert:
|
||||||
spsso.key_descriptor = do_key_descriptor(cert, "both")
|
encryption_type = conf.encryption_type
|
||||||
|
spsso.key_descriptor = do_key_descriptor(cert, encryption_type)
|
||||||
|
|
||||||
for key in ["want_assertions_signed", "authn_requests_signed"]:
|
for key in ["want_assertions_signed", "authn_requests_signed"]:
|
||||||
try:
|
try:
|
||||||
|
@@ -153,7 +153,8 @@ class IdentMDB(IdentDB):
|
|||||||
self.mdb.store(ident, name_id=to_dict(name_id, ONTS.values(), True))
|
self.mdb.store(ident, name_id=to_dict(name_id, ONTS.values(), True))
|
||||||
|
|
||||||
def find_nameid(self, userid, nformat=None, sp_name_qualifier=None,
|
def find_nameid(self, userid, nformat=None, sp_name_qualifier=None,
|
||||||
name_qualifier=None, sp_provided_id=None):
|
name_qualifier=None, sp_provided_id=None, **kwargs):
|
||||||
|
# reset passed for compatibility kwargs for next usage
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if nformat:
|
if nformat:
|
||||||
kwargs["name_format"] = nformat
|
kwargs["name_format"] = nformat
|
||||||
|
@@ -762,6 +762,10 @@ class AuthnResponse(StatusResponse):
|
|||||||
return self._assertion(assertion)
|
return self._assertion(assertion)
|
||||||
|
|
||||||
def parse_assertion(self):
|
def parse_assertion(self):
|
||||||
|
if self.context == "AuthnQuery":
|
||||||
|
# can contain one or more assertions
|
||||||
|
pass
|
||||||
|
else: # This is a saml2int limitation
|
||||||
try:
|
try:
|
||||||
assert len(self.response.assertion) == 1 or \
|
assert len(self.response.assertion) == 1 or \
|
||||||
len(self.response.encrypted_assertion) == 1
|
len(self.response.encrypted_assertion) == 1
|
||||||
@@ -770,11 +774,16 @@ class AuthnResponse(StatusResponse):
|
|||||||
|
|
||||||
if self.response.assertion:
|
if self.response.assertion:
|
||||||
logger.debug("***Unencrypted response***")
|
logger.debug("***Unencrypted response***")
|
||||||
return self._assertion(self.response.assertion[0])
|
for assertion in self.response.assertion:
|
||||||
|
if not self._assertion(assertion):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
logger.debug("***Encrypted response***")
|
logger.debug("***Encrypted response***")
|
||||||
return self._encrypted_assertion(
|
for assertion in self.response.encrypted_assertion:
|
||||||
self.response.encrypted_assertion[0])
|
if not self._encrypted_assertion(assertion):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def verify(self):
|
def verify(self):
|
||||||
""" Verify that the assertion is syntactically correct and
|
""" Verify that the assertion is syntactically correct and
|
||||||
@@ -883,7 +892,7 @@ class AuthnQueryResponse(AuthnResponse):
|
|||||||
self.entity_id = entity_id
|
self.entity_id = entity_id
|
||||||
self.attribute_converters = attribute_converters
|
self.attribute_converters = attribute_converters
|
||||||
self.assertion = None
|
self.assertion = None
|
||||||
self.context = "AuthnQueryResponse"
|
self.context = "AuthnQuery"
|
||||||
|
|
||||||
def condition_ok(self, lax=False): # Should I care about conditions ?
|
def condition_ok(self, lax=False): # Should I care about conditions ?
|
||||||
return True
|
return True
|
||||||
|
@@ -151,6 +151,10 @@ class Server(Entity):
|
|||||||
raise Exception("Couldn't open identity database: %s" %
|
raise Exception("Couldn't open identity database: %s" %
|
||||||
(dbspec,))
|
(dbspec,))
|
||||||
|
|
||||||
|
_domain = self.config.getattr("domain", "idp")
|
||||||
|
if _domain:
|
||||||
|
self.ident.domain = _domain
|
||||||
|
|
||||||
self.ident.name_qualifier = self.config.entityid
|
self.ident.name_qualifier = self.config.entityid
|
||||||
|
|
||||||
dbspec = self.config.getattr("edu_person_targeted_id", "idp")
|
dbspec = self.config.getattr("edu_person_targeted_id", "idp")
|
||||||
@@ -465,7 +469,14 @@ class Server(Entity):
|
|||||||
if not snq:
|
if not snq:
|
||||||
snq = sp_entity_id
|
snq = sp_entity_id
|
||||||
|
|
||||||
_nids = self.ident.find_nameid(userid, sp_name_qualifier=snq)
|
kwa = {"sp_name_qualifier": snq}
|
||||||
|
|
||||||
|
try:
|
||||||
|
kwa["format"] = name_id_policy.format
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
_nids = self.ident.find_nameid(userid, **kwa)
|
||||||
# either none or one
|
# either none or one
|
||||||
if _nids:
|
if _nids:
|
||||||
name_id = _nids[0]
|
name_id = _nids[0]
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?><EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="INC20140204T195141" Name="urn:mace:incommon" validUntil="2014-02-18T10:00:00Z" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata sstc-saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
<?xml version="1.0" encoding="UTF-8"?><EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="INC20140204T195141" Name="urn:mace:incommon" validUntil="2020-02-18T10:00:00Z" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata sstc-saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||||
<ds:SignedInfo>
|
<ds:SignedInfo>
|
||||||
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
||||||
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
|
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?><EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="AAITest-20140205105921" Name="urn:mace:switch.ch:aaitest" validUntil="2014-02-10T09:59:21Z" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
<?xml version="1.0" encoding="UTF-8"?><EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:mdrpi="urn:oasis:names:tc:SAML:metadata:rpi" xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui" xmlns:shibmd="urn:mace:shibboleth:metadata:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="AAITest-20140205105921" Name="urn:mace:switch.ch:aaitest" validUntil="2020-02-10T09:59:21Z" xsi:schemaLocation="urn:oasis:names:tc:SAML:2.0:metadata saml-schema-metadata-2.0.xsd urn:mace:shibboleth:metadata:1.0 shibboleth-metadata-1.0.xsd http://www.w3.org/2000/09/xmldsig# xmldsig-core-schema.xsd"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||||
<ds:SignedInfo>
|
<ds:SignedInfo>
|
||||||
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
||||||
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||||
|
70292
tests/swamid-2.0.xml
Normal file
70292
tests/swamid-2.0.xml
Normal file
File diff suppressed because one or more lines are too long
@@ -39,9 +39,11 @@ class TestAC():
|
|||||||
for ac in self.acs:
|
for ac in self.acs:
|
||||||
try:
|
try:
|
||||||
ava = ac.fro(ats)
|
ava = ac.fro(ats)
|
||||||
break
|
|
||||||
except attribute_converter.UnknownNameFormat:
|
except attribute_converter.UnknownNameFormat:
|
||||||
pass
|
pass
|
||||||
|
# break if we have something
|
||||||
|
if ava:
|
||||||
|
break
|
||||||
print ava.keys()
|
print ava.keys()
|
||||||
assert _eq(ava.keys(), ['givenName', 'displayName', 'uid',
|
assert _eq(ava.keys(), ['givenName', 'displayName', 'uid',
|
||||||
'eduPersonNickname', 'street',
|
'eduPersonNickname', 'street',
|
||||||
|
@@ -96,6 +96,7 @@ class TestIdentifier():
|
|||||||
assert _eq(nameid.keyswv(), ['text', 'format', 'sp_name_qualifier',
|
assert _eq(nameid.keyswv(), ['text', 'format', 'sp_name_qualifier',
|
||||||
'name_qualifier'])
|
'name_qualifier'])
|
||||||
assert nameid.format == NAMEID_FORMAT_TRANSIENT
|
assert nameid.format == NAMEID_FORMAT_TRANSIENT
|
||||||
|
assert nameid.text != "foobar"
|
||||||
|
|
||||||
def test_vo_1(self):
|
def test_vo_1(self):
|
||||||
policy = Policy({
|
policy = Policy({
|
||||||
@@ -119,7 +120,8 @@ class TestIdentifier():
|
|||||||
'name_qualifier'])
|
'name_qualifier'])
|
||||||
assert nameid.sp_name_qualifier == 'http://vo.example.org/biomed'
|
assert nameid.sp_name_qualifier == 'http://vo.example.org/biomed'
|
||||||
assert nameid.format == NAMEID_FORMAT_PERSISTENT
|
assert nameid.format == NAMEID_FORMAT_PERSISTENT
|
||||||
assert nameid.text != "foobar"
|
# we want to keep the user identifier in the nameid node
|
||||||
|
assert nameid.text == "foobar"
|
||||||
|
|
||||||
def test_vo_2(self):
|
def test_vo_2(self):
|
||||||
policy = Policy({
|
policy = Policy({
|
||||||
|
@@ -74,7 +74,7 @@ def test_metadata():
|
|||||||
assert len(certs) == 1
|
assert len(certs) == 1
|
||||||
|
|
||||||
sps = mds.with_descriptor("spsso")
|
sps = mds.with_descriptor("spsso")
|
||||||
assert len(sps) == 418
|
assert len(sps) == 417
|
||||||
|
|
||||||
wants = mds.attribute_requirement('https://connect.sunet.se/shibboleth')
|
wants = mds.attribute_requirement('https://connect.sunet.se/shibboleth')
|
||||||
assert wants["optional"] == []
|
assert wants["optional"] == []
|
||||||
|
@@ -52,6 +52,7 @@ MDIMPORT = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
item = MDIMPORT[sys.argv[1]]
|
item = MDIMPORT[sys.argv[1]]
|
||||||
|
|
||||||
metad = None
|
metad = None
|
||||||
@@ -66,3 +67,6 @@ if metad:
|
|||||||
metad.load()
|
metad.load()
|
||||||
print metad.dumps()
|
print metad.dumps()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
Reference in New Issue
Block a user