diff options
author | Fredrik Thulin <fredrik@thulin.net> | 2013-11-29 12:42:16 +0100 |
---|---|---|
committer | Fredrik Thulin <fredrik@thulin.net> | 2013-11-29 12:42:16 +0100 |
commit | e8ebab62c8520492019f713e66852b310b90164a (patch) | |
tree | 9153acf208d86dbb38e4d5374e8bc2addd0b0d80 | |
parent | 89ed3e3ab849b43ce76ad06a15e38ba9f16b7609 (diff) | |
parent | 94b574c56a7c2fe5b03d7ca948823c4b8af9fb39 (diff) | |
download | pysaml2-e8ebab62c8520492019f713e66852b310b90164a.tar.gz |
Merge branch 'master' of https://github.com/rohe/pysaml2
30 files changed, 1299 insertions, 738 deletions
@@ -83,3 +83,27 @@ example/idp2/modules/root.mako.py example/idp3/idp_conf_test.py update + +src/saml2/entity_category/swamid2.py + +example/idp2/IdpTestConf.py + +example/idp2/create_idp_conf.json + +example/idp2/create_idp_conf.py + +example/idp2/idpSaml2test.xml + +example/idp2/idp_conf.template + +example/idp2/idp_conf_saml2test.py + +example/sp/sp.xml + +example/idp2/idp_conf_local.py + +example/sp/sp_conf_local.py + +example/sp/my_backup_sp_conf_local.py + +example/sp/backup_sp_conf_local.py diff --git a/example/idp2/idp.py b/example/idp2/idp.py index 028d6ef0..0d6ecbe7 100755 --- a/example/idp2/idp.py +++ b/example/idp2/idp.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import argparse import base64 import re @@ -8,6 +9,8 @@ from hashlib import sha1 from urlparse import parse_qs from Cookie import SimpleCookie +import subprocess +import os from saml2 import server from saml2 import BINDING_HTTP_ARTIFACT @@ -31,6 +34,7 @@ from saml2.httputil import Unauthorized from saml2.httputil import BadRequest from saml2.httputil import ServiceError from saml2.ident import Unknown +from saml2.metadata import create_metadata_string from saml2.s_utils import rndstr, exception_trace from saml2.s_utils import UnknownPrincipal from saml2.s_utils import UnsupportedBinding @@ -431,7 +435,8 @@ def do_authentication(environ, start_response, authn_context, key, # ----------------------------------------------------------------------------- -PASSWD = {"roland": "dianakra", +PASSWD = {"haho0032": "qwerty", + "roland": "dianakra", "babs": "howes", "upper": "crust"} @@ -809,6 +814,21 @@ NON_AUTHN_URLS = [ # ---------------------------------------------------------------------------- +def metadata(environ, start_response): + try: + path = args.path + if path is None or len(path) == 0: + path = os.path.dirname(os.path.abspath( __file__ )) + if path[-1] != "/": + path += "/" + metadata = create_metadata_string(path+args.config, IDP.config, + args.valid, args.cert, args.keyfile, + args.id, args.name, args.sign) + start_response('200 OK', [('Content-Type', "text/xml")]) + return metadata + except Exception as ex: + logger.error("An error occured while creating metadata:" + ex.message) + return not_found(environ, start_response) def application(environ, start_response): """ @@ -826,6 +846,10 @@ def application(environ, start_response): """ path = environ.get('PATH_INFO', '').lstrip('/') + + if path == "metadata": + return metadata(environ, start_response) + kaka = environ.get("HTTP_COOKIE", None) logger.info("<application> PATH: %s" % path) @@ -882,6 +906,21 @@ if __name__ == '__main__': from idp_user import EXTRA from wsgiref.simple_server import make_server + parser = argparse.ArgumentParser() + parser.add_argument('-p', dest='path', help='Path to configuration file.') + parser.add_argument('-v', dest='valid', + help="How long, in days, the metadata is valid from the time of creation") + parser.add_argument('-c', dest='cert', help='certificate') + parser.add_argument('-i', dest='id', + help="The ID of the entities descriptor") + parser.add_argument('-k', dest='keyfile', + help="A file with a key to sign the metadata with") + parser.add_argument('-n', dest='name') + parser.add_argument('-s', dest='sign', action='store_true', + help="sign the metadata") + parser.add_argument(dest="config") + args = parser.parse_args() + PORT = 8088 AUTHN_BROKER = AuthnBroker() @@ -891,7 +930,7 @@ if __name__ == '__main__': AUTHN_BROKER.add(authn_context_class_ref(UNSPECIFIED), "", 0, "http://%s" % socket.gethostname()) - IDP = server.Server(sys.argv[1], cache=Cache()) + IDP = server.Server(args.config, cache=Cache()) IDP.ticket = {} SRV = make_server('', PORT, application) diff --git a/example/idp2/idp_user.py b/example/idp2/idp_user.py index ee2f68bd..aa60c7da 100644 --- a/example/idp2/idp_user.py +++ b/example/idp2/idp_user.py @@ -1,4 +1,21 @@ USERS = { + "haho0032": { + "sn": "Hoerberg", + "givenName": "Hans", + "eduPersonScopedAffiliation": "staff@example.com", + "eduPersonPrincipalName": "haho@example.com", + "uid": "haho", + "eduPersonTargetedID": "one!for!all", + "c": "SE", + "o": "Example Co.", + "ou": "IT", + "initials": "P", + "schacHomeOrganization": "example.com", + "email": "hans@example.com", + "displayName": "Hans Hoerberg", + "labeledURL": "http://www.example.com/haho My homepage", + "norEduPersonNIN": "SE199012315555" + }, "roland": { "sn": "Hedberg", "givenName": "Roland", @@ -10,7 +27,7 @@ USERS = { "o": "Example Co.", "ou": "IT", "initials": "P", - "schacHomeOrganization": "example.com", + #"schacHomeOrganization": "example.com", "email": "roland@example.com", "displayName": "P. Roland Hedberg", "labeledURL": "http://www.example.com/rohe My homepage", diff --git a/example/sp/sp.py b/example/sp/sp.py index a00d6267..b0a3c61d 100755 --- a/example/sp/sp.py +++ b/example/sp/sp.py @@ -1,18 +1,27 @@ #!/usr/bin/env python from Cookie import SimpleCookie import logging +import os +from sp_conf import CONFIG import re +import subprocess from urlparse import parse_qs +import argparse from saml2 import BINDING_HTTP_REDIRECT, time_util from saml2.httputil import Response from saml2.httputil import Unauthorized from saml2.httputil import NotFound from saml2.httputil import Redirect #from saml2.httputil import ServiceError +from saml2.metadata import create_metadata_string +from saml2.metadata import entities_descriptor +from saml2.config import Config +from saml2.sigver import security_context logger = logging.getLogger("saml2.SP") +args = None # ----------------------------------------------------------------------------- @@ -193,6 +202,21 @@ urls = [ # ---------------------------------------------------------------------------- +def metadata(environ, start_response): + try: + path = args.path + if path is None or len(path) == 0: + path = os.path.dirname(os.path.abspath( __file__ )) + if path[-1] != "/": + path += "/" + metadata = create_metadata_string(path+"sp_conf.py", None, + args.valid, args.cert, args.keyfile, + args.id, args.name, args.sign) + start_response('200 OK', [('Content-Type', "text/xml")]) + return metadata + except Exception as ex: + logger.error("An error occured while creating metadata:" + ex.message) + return not_found(environ, start_response) def application(environ, start_response): """ @@ -211,6 +235,9 @@ def application(environ, start_response): path = environ.get('PATH_INFO', '').lstrip('/') logger.info("<application> PATH: %s" % path) + if path == "metadata": + return metadata(environ, start_response) + user = environ.get("REMOTE_USER", "") if not user: user = environ.get("repoze.who.identity", "") @@ -243,7 +270,23 @@ app_with_auth = make_middleware_with_config(application, {"here": "."}, # ---------------------------------------------------------------------------- PORT = 8087 + if __name__ == '__main__': + #make_metadata arguments + parser = argparse.ArgumentParser() + parser.add_argument('-p', dest='path', help='Path to configuration file.') + parser.add_argument('-v', dest='valid', default="4", + help="How long, in days, the metadata is valid from the time of creation") + parser.add_argument('-c', dest='cert', help='certificate') + parser.add_argument('-i', dest='id', + help="The ID of the entities descriptor in the metadata") + parser.add_argument('-k', dest='keyfile', + help="A file with a key to sign the metadata with") + parser.add_argument('-n', dest='name') + parser.add_argument('-s', dest='sign', action='store_true', + help="sign the metadata") + args = parser.parse_args() + from wsgiref.simple_server import make_server srv = make_server('', PORT, app_with_auth) print "SP listening on port: %s" % PORT @@ -74,11 +74,10 @@ setup( packages=['saml2', 'xmldsig', 'xmlenc', 's2repoze', 's2repoze.plugins', "saml2/profile", "saml2/schema", "saml2/extension", "saml2/attributemaps", "saml2/authn_context", - "saml2/entity_category"], + "saml2/entity_category", "saml2/userinfo"], package_dir={'': 'src'}, package_data={'': ['xml/*.xml']}, - classifiers=["Development Status :: 4 - Beta", "License :: OSI Approved :: Apache Software License", "Topic :: Software Development :: Libraries :: Python Modules"], diff --git a/src/s2repoze/plugins/sp.py b/src/s2repoze/plugins/sp.py index d5cbe0f1..31526289 100644 --- a/src/s2repoze/plugins/sp.py +++ b/src/s2repoze/plugins/sp.py @@ -33,6 +33,7 @@ from paste.httpexceptions import HTTPNotImplemented from paste.httpexceptions import HTTPInternalServerError from paste.request import parse_dict_querystring from paste.request import construct_url +from saml2.httputil import SeeOther from saml2.client_base import ECP_SERVICE from zope.interface import implements @@ -281,11 +282,15 @@ class SAML2Plugin(object): else: sid_ = sid() self.outstanding_queries[sid_] = came_from - logger.info("Redirect to Discovery Service function") - eid = _cli.config.entity_id + logger.debug("Redirect to Discovery Service function") + eid = _cli.config.entityid + ret = _cli.config.getattr("endpoints", + "sp")["discovery_response"][0][0] + ret += "?sid=%s" % sid_ loc = _cli.create_discovery_service_request( - self.discosrv, eid) - return -1, HTTPSeeOther(headers=[('Location', loc)]) + self.discosrv, eid, **{"return": ret}) + return -1, SeeOther(loc) + else: return -1, HTTPNotImplemented( detail='No WAYF or DJ present!') @@ -366,6 +371,15 @@ class SAML2Plugin(object): raise Exception( "Failed to construct the AuthnRequest: %s" % exc) + + try: + ret = _cli.config.getattr("endpoints","sp")["discovery_response"][0][0] + if (environ["PATH_INFO"]) in ret and ret.split(environ["PATH_INFO"])[1] == "": + query = parse_qs(environ["QUERY_STRING"]) + sid = query["sid"][0] + came_from = self.outstanding_queries[sid] + except: + pass # remember the request self.outstanding_queries[_sid] = came_from diff --git a/src/saml2/assertion.py b/src/saml2/assertion.py index a08dad22..60535c55 100644 --- a/src/saml2/assertion.py +++ b/src/saml2/assertion.py @@ -439,31 +439,33 @@ class Policy(object): pass if ec_maps: - # always released - for ec_map in ec_maps: - try: - attrs = ec_map[""] - except KeyError: - pass - else: - for attr in attrs: - restrictions[attr] = None - if mds: try: ecs = mds.entity_categories(sp_entity_id) except KeyError: - pass + for ec_map in ec_maps: + for attr in ec_map[""]: + restrictions[attr] = None else: - for ec in ecs: - for ec_map in ec_maps: - try: - attrs = ec_map[ec] - except KeyError: - pass + for ec_map in ec_maps: + for key, val in ec_map.items(): + if key == "": # always released + attrs = val + elif isinstance(key, tuple): + attrs = val + for _key in key: + try: + assert _key in ecs + except AssertionError: + attrs = [] + break + elif key in ecs: + attrs = val else: - for attr in attrs: - restrictions[attr] = None + attrs = [] + + for attr in attrs: + restrictions[attr] = None return restrictions @@ -673,10 +675,9 @@ class Assertion(dict): else: _authn_statement = None - return assertion_factory( + _ass = assertion_factory( issuer=issuer, attribute_statement=[attr_statement], - authn_statement=[_authn_statement], conditions=conds, subject=factory( saml.Subject, @@ -691,6 +692,11 @@ class Assertion(dict): not_on_or_after=policy.not_on_or_after(sp_entity_id)))] ), ) + + if _authn_statement: + _ass.authn_statement = [_authn_statement] + + return _ass def apply_policy(self, sp_entity_id, policy, metadata=None): """ Apply policy to the assertion I'm representing diff --git a/src/saml2/attribute_converter.py b/src/saml2/attribute_converter.py index ab971245..328a9e84 100644 --- a/src/saml2/attribute_converter.py +++ b/src/saml2/attribute_converter.py @@ -19,9 +19,12 @@ import os import sys from importlib import import_module -from saml2.s_utils import factory, do_ava -from saml2 import saml, extension_elements_to_elements, SAMLError -from saml2.saml import NAME_FORMAT_URI, NAME_FORMAT_UNSPECIFIED +from saml2.s_utils import factory +from saml2.s_utils import do_ava +from saml2 import saml +from saml2 import extension_elements_to_elements +from saml2 import SAMLError +from saml2.saml import NAME_FORMAT_UNSPECIFIED import logging logger = logging.getLogger(__name__) @@ -84,7 +87,9 @@ def ac_factory(path=""): atco.from_dict(item) acs.append(atco) else: - for typ in ["basic", "saml_uri", "shibboleth_uri"]: + from saml2 import attributemaps + + for typ in attributemaps.__all__: mod = import_module(".%s" % typ, "saml2.attributemaps") for key, item in mod.__dict__.items(): if key.startswith("__"): diff --git a/src/saml2/attributemaps/__init__.py b/src/saml2/attributemaps/__init__.py index 90a03c1a..d041d3f1 100644 --- a/src/saml2/attributemaps/__init__.py +++ b/src/saml2/attributemaps/__init__.py @@ -1 +1,2 @@ __author__ = 'rohe0002' +__all__ = ["adfs_v1x", "adfs_v20", "basic", "saml_uri", "shibboleth_uri"] diff --git a/src/saml2/attributemaps/saml_uri.py b/src/saml2/attributemaps/saml_uri.py index 1ebe0867..ef1921e8 100644 --- a/src/saml2/attributemaps/saml_uri.py +++ b/src/saml2/attributemaps/saml_uri.py @@ -9,6 +9,7 @@ PKCS_9 = "urn:oid:1.2.840.113549.1.9.1." UMICH = "urn:oid:1.3.6.1.4.1.250.1.57." SCHAC = "urn:oid:1.3.6.1.4.1.25178.2." +#urn:oid:1.3.6.1.4.1.1466.115.121.1.26 MAP = { "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", @@ -223,6 +224,7 @@ MAP = { 'labeledURI': UMICH+'57', 'uid': UCL_DIR_PILOT+'1', 'co': UCL_DIR_PILOT+'43', + 'friendlyCountryName': UCL_DIR_PILOT+'43', 'schacMotherTongue':SCHAC+'1', 'schacGender': SCHAC+'2', 'schacDateOfBirth':SCHAC+'3', diff --git a/src/saml2/authn.py b/src/saml2/authn.py index c4585e6d..45383fa0 100644 --- a/src/saml2/authn.py +++ b/src/saml2/authn.py @@ -199,6 +199,7 @@ class UsernamePasswordMako(UserAuthnMethod): class SocialService(UserAuthnMethod): def __init__(self, social): + UserAuthnMethod.__init__(self, None) self.social = social def __call__(self, server_env, cookie=None, sid="", query="", **kwargs): diff --git a/src/saml2/client.py b/src/saml2/client.py index a9c4e9c0..396f3d20 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -118,7 +118,7 @@ class Saml2Client(Base): def do_logout(self, name_id, entity_ids, reason, expire, sign=None): """ - :param name_id: Identifier of the Subject a NameID instance + :param name_id: Identifier of the Subject (a NameID instance) :param entity_ids: List of entity ids for the IdPs that have provided information concerning the subject :param reason: The reason for doing the logout diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py index 9dcaab4b..aabd26e3 100644 --- a/src/saml2/client_base.py +++ b/src/saml2/client_base.py @@ -117,13 +117,15 @@ class Base(Entity): else: self.state = state_cache + self.logout_requests_signed = False + self.allow_unsolicited = False + self.authn_requests_signed = False + self.want_assertions_signed = False for foo in ["allow_unsolicited", "authn_requests_signed", "logout_requests_signed", "want_assertions_signed"]: v = self.config.getattr(foo, "sp") if v is True or v == 'true': setattr(self, foo, True) - else: - setattr(self, foo, False) self.artifact2response = {} @@ -195,10 +197,10 @@ class Base(Entity): """ return True - def service_url(self, binding=BINDING_HTTP_POST): + def service_urls(self, binding=BINDING_HTTP_POST): _res = self.config.endpoint("assertion_consumer_service", binding, "sp") if _res: - return _res[0] + return _res else: return None @@ -232,19 +234,24 @@ class Base(Entity): args = {} try: args["assertion_consumer_service_url"] = kwargs[ - "assertion_consumer_service_url"] - del kwargs["assertion_consumer_service_url"] + "assertion_consumer_service_urls"][0] + del kwargs["assertion_consumer_service_urls"] except KeyError: try: - args["attribute_consuming_service_index"] = str(kwargs[ - "attribute_consuming_service_index"]) - del kwargs["attribute_consuming_service_index"] + args["assertion_consumer_service_url"] = kwargs[ + "assertion_consumer_service_url"] + del kwargs["assertion_consumer_service_urls"] except KeyError: - if service_url_binding is None: - service_url = self.service_url(binding) - else: - service_url = self.service_url(service_url_binding) - args["assertion_consumer_service_url"] = service_url + try: + args["attribute_consuming_service_index"] = str(kwargs[ + "attribute_consuming_service_index"]) + del kwargs["attribute_consuming_service_index"] + except KeyError: + if service_url_binding is None: + service_urls = self.service_urls(binding) + else: + service_urls = self.service_urls(service_url_binding) + args["assertion_consumer_service_url"] = service_urls[0] try: args["provider_name"] = kwargs["provider_name"] @@ -508,7 +515,7 @@ class Base(Entity): "outstanding_queries": outstanding, "allow_unsolicited": self.allow_unsolicited, "want_assertions_signed": self.want_assertions_signed, - "return_addr": self.service_url(), + "return_addrs": self.service_urls(), "entity_id": self.config.entityid, "attribute_converters": self.config.attribute_converters, "allow_unknown_attributes": self.config.allow_unknown_attributes, @@ -608,7 +615,7 @@ class Base(Entity): # ---------------------------------------- # <paos:Request> # ---------------------------------------- - my_url = self.service_url(BINDING_PAOS) + my_url = self.service_urls(BINDING_PAOS)[0] # must_understand and act according to the standard # diff --git a/src/saml2/ecp_client.py b/src/saml2/ecp_client.py index 39e075d2..beb638a5 100644 --- a/src/saml2/ecp_client.py +++ b/src/saml2/ecp_client.py @@ -23,10 +23,11 @@ programs. import cookielib import logging -from saml2 import soap, SAMLError +from saml2 import soap from saml2 import saml from saml2 import samlp -from saml2 import BINDING_PAOS +from saml2 import SAMLError +from saml2 import BINDING_SOAP from saml2.client_base import MIME_PAOS from saml2.config import Config from saml2.entity import Entity @@ -112,10 +113,10 @@ class Client(Entity): """ _, destination = self.pick_binding("single_sign_on_service", - [BINDING_PAOS], "idpsso", + [BINDING_SOAP], "idpsso", entity_id=idp_entity_id) - ht_args = self.apply_binding(BINDING_PAOS, authn_request, destination, + ht_args = self.apply_binding(BINDING_SOAP, authn_request, destination, sign=sign) if headers: @@ -162,7 +163,8 @@ class Client(Entity): return idp_response - def parse_sp_ecp_response(self, respdict): + @staticmethod + def parse_sp_ecp_response(respdict): if respdict is None: raise SAMLError("Unexpected reply from the SP") diff --git a/src/saml2/entity.py b/src/saml2/entity.py index d7a13150..8e519a65 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -614,7 +614,7 @@ class Entity(HTTPBase): return self._message(LogoutRequest, destination, message_id, consent, extensions, sign, name_id=name_id, reason=reason, not_on_or_after=expire, - issuer=self._issuer(issuer_entity_id)) + issuer=self._issuer()) def create_logout_response(self, request, bindings=None, status=None, sign=False, issuer=None): @@ -631,6 +631,9 @@ class Entity(HTTPBase): rinfo = self.response_args(request, bindings) + if not issuer: + issuer = self._issuer() + response = self._status_response(samlp.LogoutResponse, issuer, status, sign, **rinfo) @@ -773,12 +776,12 @@ class Entity(HTTPBase): kwargs["asynchop"] = True if xmlstr: - if "return_addr" not in kwargs: + if "return_addrs" not in kwargs: if binding in [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]: try: # expected return address - kwargs["return_addr"] = self.config.endpoint( - service, binding=binding)[0] + kwargs["return_addrs"] = self.config.endpoint( + service, binding=binding) except Exception: logger.info("Not supposed to handle this!") return None diff --git a/src/saml2/entity_category/swamid.py b/src/saml2/entity_category/swamid.py index 2dabd410..7d07f0fb 100644 --- a/src/saml2/entity_category/swamid.py +++ b/src/saml2/entity_category/swamid.py @@ -17,5 +17,7 @@ HEI = "http://www.swamid.se/category/hei-service" RELEASE = { "": ["eduPersonTargetedID"], SFS_1993_1153: ["norEduPersonNIN"], - RESEARCH_AND_EDUCATION: NAME + STATIC_ORG_INFO + OTHER, + (RESEARCH_AND_EDUCATION, EU): NAME + STATIC_ORG_INFO + OTHER, + (RESEARCH_AND_EDUCATION, NREN): NAME + STATIC_ORG_INFO + OTHER, + (RESEARCH_AND_EDUCATION, HEI): NAME + STATIC_ORG_INFO + OTHER, }
\ No newline at end of file diff --git a/src/saml2/md.py b/src/saml2/md.py index 70c0707c..81b2ef24 100644 --- a/src/saml2/md.py +++ b/src/saml2/md.py @@ -13,6 +13,7 @@ from saml2 import saml NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:metadata' + class EntityIDType_(SamlBase): """The urn:oasis:names:tc:SAML:2.0:metadata:entityIDType element """ @@ -24,6 +25,7 @@ class EntityIDType_(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() + def entity_id_type__from_string(xml_string): return saml2.create_class_from_xml_string(EntityIDType_, xml_string) @@ -43,17 +45,16 @@ class LocalizedNameType_(SamlBase): True) def __init__(self, - lang=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.lang=lang + lang=None, + text=None, + extension_elements=None, + extension_attributes=None): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes) + self.lang = lang + def localized_name_type__from_string(xml_string): return saml2.create_class_from_xml_string(LocalizedNameType_, xml_string) @@ -74,17 +75,15 @@ class LocalizedURIType_(SamlBase): True) def __init__(self, - lang=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.lang=lang + lang=None, + text=None, + extension_elements=None, + extension_attributes=None): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes) + self.lang = lang def localized_uri_type__from_string(xml_string): @@ -120,21 +119,19 @@ class EndpointType_(SamlBase): c_attributes['ResponseLocation'] = ('response_location', 'anyURI', False) def __init__(self, - binding=None, - location=None, - response_location=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.binding=binding - self.location=location - self.response_location=response_location + binding=None, + location=None, + response_location=None, + text=None, + extension_elements=None, + extension_attributes=None): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes) + self.binding = binding + self.location = location + self.response_location = response_location def endpoint_type__from_string(xml_string): @@ -154,25 +151,23 @@ class IndexedEndpointType_(EndpointType_): c_attributes['isDefault'] = ('is_default', 'boolean', False) def __init__(self, - index=None, - is_default=None, - binding=None, - location=None, - response_location=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - EndpointType_.__init__(self, - binding=binding, - location=location, - response_location=response_location, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.index=index - self.is_default=is_default + index=None, + is_default=None, + binding=None, + location=None, + response_location=None, + text=None, + extension_elements=None, + extension_attributes=None): + EndpointType_.__init__(self, + binding=binding, + location=location, + response_location=response_location, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes) + self.index = index + self.is_default = is_default def indexed_endpoint_type__from_string(xml_string): @@ -342,7 +337,7 @@ class AdditionalMetadataLocationType_(SamlBase): SamlBase.__init__(self, text=text, extension_elements=extension_elements, extension_attributes=extension_attributes) - self.namespace=namespace + self.namespace = namespace def additional_metadata_location_type__from_string(xml_string): @@ -591,7 +586,7 @@ class RequestedAttributeType_(saml.AttributeType_): text=text, extension_elements=extension_elements, extension_attributes=extension_attributes) - self.is_required=is_required + self.is_required = is_required def requested_attribute_type__from_string(xml_string): @@ -685,17 +680,17 @@ class OrganizationType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Extensions'] = ( 'extensions', Extensions) - c_cardinality['extensions'] = {"min":0, "max":1} + c_cardinality['extensions'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}OrganizationName'] = ( 'organization_name', [OrganizationName]) - c_cardinality['organization_name'] = {"min":1} + c_cardinality['organization_name'] = {"min": 1} c_children[ '{urn:oasis:names:tc:SAML:2.0:metadata}OrganizationDisplayName'] = ( 'organization_display_name', [OrganizationDisplayName]) - c_cardinality['organization_display_name'] = {"min":1} + c_cardinality['organization_display_name'] = {"min": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}OrganizationURL'] = ( 'organization_url', [OrganizationURL]) - c_cardinality['organization_url'] = {"min":1} + c_cardinality['organization_url'] = {"min": 1} c_child_order.extend(['extensions', 'organization_name', 'organization_display_name', 'organization_url']) @@ -705,10 +700,10 @@ class OrganizationType_(SamlBase): SamlBase.__init__(self, text=text, extension_elements=extension_elements, extension_attributes=extension_attributes) - self.extensions=extensions - self.organization_name=organization_name or [] - self.organization_display_name=organization_display_name or [] - self.organization_url=organization_url or [] + self.extensions = extensions + self.organization_name = organization_name or [] + self.organization_display_name = organization_display_name or [] + self.organization_url = organization_url or [] def organization_type__from_string(xml_string): @@ -726,50 +721,50 @@ class ContactType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Extensions'] = ( 'extensions', Extensions) - c_cardinality['extensions'] = {"min":0, "max":1} + c_cardinality['extensions'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Company'] = ( 'company', Company) - c_cardinality['company'] = {"min":0, "max":1} + c_cardinality['company'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}GivenName'] = ( 'given_name', GivenName) - c_cardinality['given_name'] = {"min":0, "max":1} + c_cardinality['given_name'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}SurName'] = ( 'sur_name', SurName) - c_cardinality['sur_name'] = {"min":0, "max":1} + c_cardinality['sur_name'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}EmailAddress'] = ( 'email_address', [EmailAddress]) - c_cardinality['email_address'] = {"min":0} + c_cardinality['email_address'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}TelephoneNumber'] = ( 'telephone_number', [TelephoneNumber]) - c_cardinality['telephone_number'] = {"min":0} + c_cardinality['telephone_number'] = {"min": 0} c_attributes['contactType'] = ('contact_type', ContactTypeType_, True) c_child_order.extend(['extensions', 'company', 'given_name', 'sur_name', 'email_address', 'telephone_number']) def __init__(self, - extensions=None, - company=None, - given_name=None, - sur_name=None, - email_address=None, - telephone_number=None, - contact_type=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.extensions=extensions - self.company=company - self.given_name=given_name - self.sur_name=sur_name - self.email_address=email_address or [] - self.telephone_number=telephone_number or [] - self.contact_type=contact_type + extensions=None, + company=None, + given_name=None, + sur_name=None, + email_address=None, + telephone_number=None, + contact_type=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.extensions = extensions + self.company = company + self.given_name = given_name + self.sur_name = sur_name + self.email_address = email_address or [] + self.telephone_number = telephone_number or [] + self.contact_type = contact_type def contact_type__from_string(xml_string): @@ -811,21 +806,20 @@ class KeyDescriptorType_(SamlBase): c_child_order.extend(['key_info', 'encryption_method']) def __init__(self, - key_info=None, - encryption_method=None, - use=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.key_info=key_info - self.encryption_method=encryption_method or [] - self.use=use + key_info=None, + encryption_method=None, + use=None, + text=None, + extension_elements=None, + extension_attributes=None): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes) + self.key_info = key_info + self.encryption_method = encryption_method or [] + self.use = use + def key_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(KeyDescriptorType_, xml_string) @@ -841,6 +835,7 @@ class RequestedAttribute(RequestedAttributeType_): c_child_order = RequestedAttributeType_.c_child_order[:] c_cardinality = RequestedAttributeType_.c_cardinality.copy() + def requested_attribute_from_string(xml_string): return saml2.create_class_from_xml_string(RequestedAttribute, xml_string) @@ -855,6 +850,7 @@ class Organization(OrganizationType_): c_child_order = OrganizationType_.c_child_order[:] c_cardinality = OrganizationType_.c_cardinality.copy() + def organization_from_string(xml_string): return saml2.create_class_from_xml_string(Organization, xml_string) @@ -869,6 +865,7 @@ class ContactPerson(ContactType_): c_child_order = ContactType_.c_child_order[:] c_cardinality = ContactType_.c_cardinality.copy() + def contact_person_from_string(xml_string): return saml2.create_class_from_xml_string(ContactPerson, xml_string) @@ -883,6 +880,7 @@ class KeyDescriptor(KeyDescriptorType_): c_child_order = KeyDescriptorType_.c_child_order[:] c_cardinality = KeyDescriptorType_.c_cardinality.copy() + def key_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(KeyDescriptor, xml_string) @@ -896,24 +894,21 @@ class RoleDescriptorType_(SamlBase): c_attributes = SamlBase.c_attributes.copy() c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() - c_children['{http://www.w3.org/2000/09/xmldsig#}Signature'] = ('signature', - ds.Signature) - c_cardinality['signature'] = {"min":0, "max":1} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Extensions'] = ('extensions', - Extensions) - c_cardinality['extensions'] = {"min":0, "max":1} + c_children['{http://www.w3.org/2000/09/xmldsig#}Signature'] = ( + 'signature', ds.Signature) + c_cardinality['signature'] = {"min": 0, "max": 1} + c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Extensions'] = ( + 'extensions', Extensions) + c_cardinality['extensions'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}KeyDescriptor'] = ( - 'key_descriptor', - [KeyDescriptor]) - c_cardinality['key_descriptor'] = {"min":0} + 'key_descriptor', [KeyDescriptor]) + c_cardinality['key_descriptor'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Organization'] = ( - 'organization', - Organization) - c_cardinality['organization'] = {"min":0, "max":1} + 'organization', Organization) + c_cardinality['organization'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}ContactPerson'] = ( - 'contact_person', - [ContactPerson]) - c_cardinality['contact_person'] = {"min":0} + 'contact_person', [ContactPerson]) + c_cardinality['contact_person'] = {"min": 0} c_attributes['ID'] = ('id', 'ID', False) c_attributes['validUntil'] = ('valid_until', 'dateTime', False) c_attributes['cacheDuration'] = ('cache_duration', 'duration', False) @@ -924,35 +919,33 @@ class RoleDescriptorType_(SamlBase): 'organization', 'contact_person']) def __init__(self, - signature=None, - extensions=None, - key_descriptor=None, - organization=None, - contact_person=None, - id=None, - valid_until=None, - cache_duration=None, - protocol_support_enumeration=None, - error_url=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.signature=signature - self.extensions=extensions - self.key_descriptor=key_descriptor or [] - self.organization=organization - self.contact_person=contact_person or [] - self.id=id - self.valid_until=valid_until - self.cache_duration=cache_duration - self.protocol_support_enumeration=protocol_support_enumeration - self.error_url=error_url + signature=None, + extensions=None, + key_descriptor=None, + organization=None, + contact_person=None, + id=None, + valid_until=None, + cache_duration=None, + protocol_support_enumeration=None, + error_url=None, + text=None, + extension_elements=None, + extension_attributes=None): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes) + self.signature = signature + self.extensions = extensions + self.key_descriptor = key_descriptor or [] + self.organization = organization + self.contact_person = contact_person or [] + self.id = id + self.valid_until = valid_until + self.cache_duration = cache_duration + self.protocol_support_enumeration = protocol_support_enumeration + self.error_url = error_url class SSODescriptorType_(RoleDescriptorType_): @@ -964,22 +957,19 @@ class SSODescriptorType_(RoleDescriptorType_): c_attributes = RoleDescriptorType_.c_attributes.copy() c_child_order = RoleDescriptorType_.c_child_order[:] c_cardinality = RoleDescriptorType_.c_cardinality.copy() - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}ArtifactResolutionService'] = ( - 'artifact_resolution_service', - [ArtifactResolutionService]) - c_cardinality['artifact_resolution_service'] = {"min":0} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}ArtifactResolutionService'] = ( + 'artifact_resolution_service', [ArtifactResolutionService]) + c_cardinality['artifact_resolution_service'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}SingleLogoutService'] = ( - 'single_logout_service', - [SingleLogoutService]) - c_cardinality['single_logout_service'] = {"min":0} + 'single_logout_service', [SingleLogoutService]) + c_cardinality['single_logout_service'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}ManageNameIDService'] = ( - 'manage_name_id_service', - [ManageNameIDService]) - c_cardinality['manage_name_id_service'] = {"min":0} + 'manage_name_id_service', [ManageNameIDService]) + c_cardinality['manage_name_id_service'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}NameIDFormat'] = ( - 'name_id_format', - [NameIDFormat]) - c_cardinality['name_id_format'] = {"min":0} + 'name_id_format', [NameIDFormat]) + c_cardinality['name_id_format'] = {"min": 0} c_child_order.extend(['artifact_resolution_service', 'single_logout_service', 'manage_name_id_service', 'name_id_format']) @@ -1002,8 +992,7 @@ class SSODescriptorType_(RoleDescriptorType_): error_url=None, text=None, extension_elements=None, - extension_attributes=None, - ): + extension_attributes=None): RoleDescriptorType_.__init__( self, signature=signature, @@ -1018,12 +1007,11 @@ class SSODescriptorType_(RoleDescriptorType_): error_url=error_url, text=text, extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.artifact_resolution_service=artifact_resolution_service or [] - self.single_logout_service=single_logout_service or [] - self.manage_name_id_service=manage_name_id_service or [] - self.name_id_format=name_id_format or [] + extension_attributes=extension_attributes) + self.artifact_resolution_service = artifact_resolution_service or [] + self.single_logout_service = single_logout_service or [] + self.manage_name_id_service = manage_name_id_service or [] + self.name_id_format = name_id_format or [] class IDPSSODescriptorType_(SSODescriptorType_): @@ -1036,25 +1024,21 @@ class IDPSSODescriptorType_(SSODescriptorType_): c_child_order = SSODescriptorType_.c_child_order[:] c_cardinality = SSODescriptorType_.c_cardinality.copy() c_children['{urn:oasis:names:tc:SAML:2.0:metadata}SingleSignOnService'] = ( - 'single_sign_on_service', - [SingleSignOnService]) - c_cardinality['single_sign_on_service'] = {"min":1} + 'single_sign_on_service', [SingleSignOnService]) + c_cardinality['single_sign_on_service'] = {"min": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}NameIDMappingService'] = ( - 'name_id_mapping_service', - [NameIDMappingService]) - c_cardinality['name_id_mapping_service'] = {"min":0} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( - 'assertion_id_request_service', - [AssertionIDRequestService]) - c_cardinality['assertion_id_request_service'] = {"min":0} + 'name_id_mapping_service', [NameIDMappingService]) + c_cardinality['name_id_mapping_service'] = {"min": 0} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( + 'assertion_id_request_service', [AssertionIDRequestService]) + c_cardinality['assertion_id_request_service'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AttributeProfile'] = ( - 'attribute_profile', - [AttributeProfile]) - c_cardinality['attribute_profile'] = {"min":0} + 'attribute_profile', [AttributeProfile]) + c_cardinality['attribute_profile'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:assertion}Attribute'] = ( - 'attribute', - [saml.Attribute]) - c_cardinality['attribute'] = {"min":0} + 'attribute', [saml.Attribute]) + c_cardinality['attribute'] = {"min": 0} c_attributes['WantAuthnRequestsSigned'] = ('want_authn_requests_signed', 'boolean', False) c_child_order.extend(['single_sign_on_service', 'name_id_mapping_service', @@ -1062,62 +1046,64 @@ class IDPSSODescriptorType_(SSODescriptorType_): 'attribute']) def __init__(self, - single_sign_on_service=None, - name_id_mapping_service=None, - assertion_id_request_service=None, - attribute_profile=None, - attribute=None, - want_authn_requests_signed=None, - artifact_resolution_service=None, - single_logout_service=None, - manage_name_id_service=None, - name_id_format=None, - signature=None, - extensions=None, - key_descriptor=None, - organization=None, - contact_person=None, - id=None, - valid_until=None, - cache_duration=None, - protocol_support_enumeration=None, - error_url=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SSODescriptorType_.__init__(self, - artifact_resolution_service=artifact_resolution_service, - single_logout_service=single_logout_service, - manage_name_id_service=manage_name_id_service, - name_id_format=name_id_format, - signature=signature, - extensions=extensions, - key_descriptor=key_descriptor, - organization=organization, - contact_person=contact_person, - id=id, - valid_until=valid_until, - cache_duration=cache_duration, - protocol_support_enumeration=protocol_support_enumeration, - error_url=error_url, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.single_sign_on_service=single_sign_on_service or [] - self.name_id_mapping_service=name_id_mapping_service or [] - self.assertion_id_request_service=assertion_id_request_service or [] - self.attribute_profile=attribute_profile or [] - self.attribute=attribute or [] - self.want_authn_requests_signed=want_authn_requests_signed + single_sign_on_service=None, + name_id_mapping_service=None, + assertion_id_request_service=None, + attribute_profile=None, + attribute=None, + want_authn_requests_signed=None, + artifact_resolution_service=None, + single_logout_service=None, + manage_name_id_service=None, + name_id_format=None, + signature=None, + extensions=None, + key_descriptor=None, + organization=None, + contact_person=None, + id=None, + valid_until=None, + cache_duration=None, + protocol_support_enumeration=None, + error_url=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + SSODescriptorType_.__init__(self, + artifact_resolution_service=artifact_resolution_service, + single_logout_service=single_logout_service, + manage_name_id_service=manage_name_id_service, + name_id_format=name_id_format, + signature=signature, + extensions=extensions, + key_descriptor=key_descriptor, + organization=organization, + contact_person=contact_person, + id=id, + valid_until=valid_until, + cache_duration=cache_duration, + protocol_support_enumeration=protocol_support_enumeration, + error_url=error_url, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.single_sign_on_service = single_sign_on_service or [] + self.name_id_mapping_service = name_id_mapping_service or [] + self.assertion_id_request_service = assertion_id_request_service or [] + self.attribute_profile = attribute_profile or [] + self.attribute = attribute or [] + self.want_authn_requests_signed = want_authn_requests_signed + def idpsso_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(IDPSSODescriptorType_, xml_string) class AttributeConsumingServiceType_(SamlBase): - """The urn:oasis:names:tc:SAML:2.0:metadata:AttributeConsumingServiceType element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:AttributeConsumingServiceType + element """ c_tag = 'AttributeConsumingServiceType' c_namespace = NAMESPACE @@ -1126,42 +1112,43 @@ class AttributeConsumingServiceType_(SamlBase): c_child_order = SamlBase.c_child_order[:] c_cardinality = SamlBase.c_cardinality.copy() c_children['{urn:oasis:names:tc:SAML:2.0:metadata}ServiceName'] = ( - 'service_name', - [ServiceName]) - c_cardinality['service_name'] = {"min":1} + 'service_name', + [ServiceName]) + c_cardinality['service_name'] = {"min": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}ServiceDescription'] = ( - 'service_description', - [ServiceDescription]) - c_cardinality['service_description'] = {"min":0} + 'service_description', + [ServiceDescription]) + c_cardinality['service_description'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}RequestedAttribute'] = ( - 'requested_attribute', - [RequestedAttribute]) - c_cardinality['requested_attribute'] = {"min":1} + 'requested_attribute', + [RequestedAttribute]) + c_cardinality['requested_attribute'] = {"min": 1} c_attributes['index'] = ('index', 'unsignedShort', True) c_attributes['isDefault'] = ('is_default', 'boolean', False) c_child_order.extend(['service_name', 'service_description', 'requested_attribute']) def __init__(self, - service_name=None, - service_description=None, - requested_attribute=None, - index=None, - is_default=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.service_name=service_name or [] - self.service_description=service_description or [] - self.requested_attribute=requested_attribute or [] - self.index=index - self.is_default=is_default + service_name=None, + service_description=None, + requested_attribute=None, + index=None, + is_default=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.service_name = service_name or [] + self.service_description = service_description or [] + self.requested_attribute = requested_attribute or [] + self.index = index + self.is_default = is_default + def attribute_consuming_service_type__from_string(xml_string): return saml2.create_class_from_xml_string(AttributeConsumingServiceType_, @@ -1169,7 +1156,8 @@ def attribute_consuming_service_type__from_string(xml_string): class AuthnAuthorityDescriptorType_(RoleDescriptorType_): - """The urn:oasis:names:tc:SAML:2.0:metadata:AuthnAuthorityDescriptorType element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:AuthnAuthorityDescriptorType + element """ c_tag = 'AuthnAuthorityDescriptorType' c_namespace = NAMESPACE @@ -1178,56 +1166,58 @@ class AuthnAuthorityDescriptorType_(RoleDescriptorType_): c_child_order = RoleDescriptorType_.c_child_order[:] c_cardinality = RoleDescriptorType_.c_cardinality.copy() c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AuthnQueryService'] = ( - 'authn_query_service', - [AuthnQueryService]) - c_cardinality['authn_query_service'] = {"min":1} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( - 'assertion_id_request_service', - [AssertionIDRequestService]) - c_cardinality['assertion_id_request_service'] = {"min":0} + 'authn_query_service', + [AuthnQueryService]) + c_cardinality['authn_query_service'] = {"min": 1} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( + 'assertion_id_request_service', + [AssertionIDRequestService]) + c_cardinality['assertion_id_request_service'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}NameIDFormat'] = ( - 'name_id_format', - [NameIDFormat]) - c_cardinality['name_id_format'] = {"min":0} + 'name_id_format', + [NameIDFormat]) + c_cardinality['name_id_format'] = {"min": 0} c_child_order.extend(['authn_query_service', 'assertion_id_request_service', 'name_id_format']) def __init__(self, - authn_query_service=None, - assertion_id_request_service=None, - name_id_format=None, - signature=None, - extensions=None, - key_descriptor=None, - organization=None, - contact_person=None, - id=None, - valid_until=None, - cache_duration=None, - protocol_support_enumeration=None, - error_url=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - RoleDescriptorType_.__init__(self, - signature=signature, - extensions=extensions, - key_descriptor=key_descriptor, - organization=organization, - contact_person=contact_person, - id=id, - valid_until=valid_until, - cache_duration=cache_duration, - protocol_support_enumeration=protocol_support_enumeration, - error_url=error_url, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.authn_query_service=authn_query_service or [] - self.assertion_id_request_service=assertion_id_request_service or [] - self.name_id_format=name_id_format or [] + authn_query_service=None, + assertion_id_request_service=None, + name_id_format=None, + signature=None, + extensions=None, + key_descriptor=None, + organization=None, + contact_person=None, + id=None, + valid_until=None, + cache_duration=None, + protocol_support_enumeration=None, + error_url=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + RoleDescriptorType_.__init__(self, + signature=signature, + extensions=extensions, + key_descriptor=key_descriptor, + organization=organization, + contact_person=contact_person, + id=id, + valid_until=valid_until, + cache_duration=cache_duration, + protocol_support_enumeration=protocol_support_enumeration, + error_url=error_url, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.authn_query_service = authn_query_service or [] + self.assertion_id_request_service = assertion_id_request_service or [] + self.name_id_format = name_id_format or [] + def authn_authority_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(AuthnAuthorityDescriptorType_, @@ -1244,63 +1234,66 @@ class PDPDescriptorType_(RoleDescriptorType_): c_child_order = RoleDescriptorType_.c_child_order[:] c_cardinality = RoleDescriptorType_.c_cardinality.copy() c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AuthzService'] = ( - 'authz_service', - [AuthzService]) - c_cardinality['authz_service'] = {"min":1} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( - 'assertion_id_request_service', - [AssertionIDRequestService]) - c_cardinality['assertion_id_request_service'] = {"min":0} + 'authz_service', + [AuthzService]) + c_cardinality['authz_service'] = {"min": 1} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( + 'assertion_id_request_service', + [AssertionIDRequestService]) + c_cardinality['assertion_id_request_service'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}NameIDFormat'] = ( - 'name_id_format', - [NameIDFormat]) - c_cardinality['name_id_format'] = {"min":0} + 'name_id_format', + [NameIDFormat]) + c_cardinality['name_id_format'] = {"min": 0} c_child_order.extend(['authz_service', 'assertion_id_request_service', 'name_id_format']) def __init__(self, - authz_service=None, - assertion_id_request_service=None, - name_id_format=None, - signature=None, - extensions=None, - key_descriptor=None, - organization=None, - contact_person=None, - id=None, - valid_until=None, - cache_duration=None, - protocol_support_enumeration=None, - error_url=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - RoleDescriptorType_.__init__(self, - signature=signature, - extensions=extensions, - key_descriptor=key_descriptor, - organization=organization, - contact_person=contact_person, - id=id, - valid_until=valid_until, - cache_duration=cache_duration, - protocol_support_enumeration=protocol_support_enumeration, - error_url=error_url, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.authz_service=authz_service or [] - self.assertion_id_request_service=assertion_id_request_service or [] - self.name_id_format=name_id_format or [] + authz_service=None, + assertion_id_request_service=None, + name_id_format=None, + signature=None, + extensions=None, + key_descriptor=None, + organization=None, + contact_person=None, + id=None, + valid_until=None, + cache_duration=None, + protocol_support_enumeration=None, + error_url=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + RoleDescriptorType_.__init__(self, + signature=signature, + extensions=extensions, + key_descriptor=key_descriptor, + organization=organization, + contact_person=contact_person, + id=id, + valid_until=valid_until, + cache_duration=cache_duration, + protocol_support_enumeration=protocol_support_enumeration, + error_url=error_url, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.authz_service = authz_service or [] + self.assertion_id_request_service = assertion_id_request_service or [] + self.name_id_format = name_id_format or [] + def pdp_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(PDPDescriptorType_, xml_string) class AttributeAuthorityDescriptorType_(RoleDescriptorType_): - """The urn:oasis:names:tc:SAML:2.0:metadata:AttributeAuthorityDescriptorType element """ + """The urn:oasis:names:tc:SAML:2 + .0:metadata:AttributeAuthorityDescriptorType element """ c_tag = 'AttributeAuthorityDescriptorType' c_namespace = NAMESPACE @@ -1309,68 +1302,70 @@ class AttributeAuthorityDescriptorType_(RoleDescriptorType_): c_child_order = RoleDescriptorType_.c_child_order[:] c_cardinality = RoleDescriptorType_.c_cardinality.copy() c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AttributeService'] = ( - 'attribute_service', - [AttributeService]) - c_cardinality['attribute_service'] = {"min":1} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( - 'assertion_id_request_service', - [AssertionIDRequestService]) - c_cardinality['assertion_id_request_service'] = {"min":0} + 'attribute_service', + [AttributeService]) + c_cardinality['attribute_service'] = {"min": 1} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AssertionIDRequestService'] = ( + 'assertion_id_request_service', + [AssertionIDRequestService]) + c_cardinality['assertion_id_request_service'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}NameIDFormat'] = ( - 'name_id_format', - [NameIDFormat]) - c_cardinality['name_id_format'] = {"min":0} + 'name_id_format', + [NameIDFormat]) + c_cardinality['name_id_format'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AttributeProfile'] = ( - 'attribute_profile', - [AttributeProfile]) - c_cardinality['attribute_profile'] = {"min":0} + 'attribute_profile', + [AttributeProfile]) + c_cardinality['attribute_profile'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:assertion}Attribute'] = ( - 'attribute', - [saml.Attribute]) - c_cardinality['attribute'] = {"min":0} + 'attribute', + [saml.Attribute]) + c_cardinality['attribute'] = {"min": 0} c_child_order.extend(['attribute_service', 'assertion_id_request_service', 'name_id_format', 'attribute_profile', 'attribute']) def __init__(self, - attribute_service=None, - assertion_id_request_service=None, - name_id_format=None, - attribute_profile=None, - attribute=None, - signature=None, - extensions=None, - key_descriptor=None, - organization=None, - contact_person=None, - id=None, - valid_until=None, - cache_duration=None, - protocol_support_enumeration=None, - error_url=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - RoleDescriptorType_.__init__(self, - signature=signature, - extensions=extensions, - key_descriptor=key_descriptor, - organization=organization, - contact_person=contact_person, - id=id, - valid_until=valid_until, - cache_duration=cache_duration, - protocol_support_enumeration=protocol_support_enumeration, - error_url=error_url, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.attribute_service=attribute_service or [] - self.assertion_id_request_service=assertion_id_request_service or [] - self.name_id_format=name_id_format or [] - self.attribute_profile=attribute_profile or [] - self.attribute=attribute or [] + attribute_service=None, + assertion_id_request_service=None, + name_id_format=None, + attribute_profile=None, + attribute=None, + signature=None, + extensions=None, + key_descriptor=None, + organization=None, + contact_person=None, + id=None, + valid_until=None, + cache_duration=None, + protocol_support_enumeration=None, + error_url=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + RoleDescriptorType_.__init__(self, + signature=signature, + extensions=extensions, + key_descriptor=key_descriptor, + organization=organization, + contact_person=contact_person, + id=id, + valid_until=valid_until, + cache_duration=cache_duration, + protocol_support_enumeration=protocol_support_enumeration, + error_url=error_url, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.attribute_service = attribute_service or [] + self.assertion_id_request_service = assertion_id_request_service or [] + self.name_id_format = name_id_format or [] + self.attribute_profile = attribute_profile or [] + self.attribute = attribute or [] + def attribute_authority_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(AttributeAuthorityDescriptorType_, @@ -1378,7 +1373,8 @@ def attribute_authority_descriptor_type__from_string(xml_string): class AffiliationDescriptorType_(SamlBase): - """The urn:oasis:names:tc:SAML:2.0:metadata:AffiliationDescriptorType element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:AffiliationDescriptorType + element """ c_tag = 'AffiliationDescriptorType' c_namespace = NAMESPACE @@ -1388,19 +1384,19 @@ class AffiliationDescriptorType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}Signature'] = ('signature', ds.Signature) - c_cardinality['signature'] = {"min":0, "max":1} + c_cardinality['signature'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Extensions'] = ( - 'extensions', - Extensions) - c_cardinality['extensions'] = {"min":0, "max":1} + 'extensions', + Extensions) + c_cardinality['extensions'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AffiliateMember'] = ( - 'affiliate_member', - [AffiliateMember]) - c_cardinality['affiliate_member'] = {"min":1} + 'affiliate_member', + [AffiliateMember]) + c_cardinality['affiliate_member'] = {"min": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}KeyDescriptor'] = ( - 'key_descriptor', - [KeyDescriptor]) - c_cardinality['key_descriptor'] = {"min":0} + 'key_descriptor', + [KeyDescriptor]) + c_cardinality['key_descriptor'] = {"min": 0} c_attributes['affiliationOwnerID'] = ('affiliation_owner_id', EntityIDType_, True) c_attributes['validUntil'] = ('valid_until', 'dateTime', False) @@ -1410,31 +1406,32 @@ class AffiliationDescriptorType_(SamlBase): 'key_descriptor']) def __init__(self, - signature=None, - extensions=None, - affiliate_member=None, - key_descriptor=None, - affiliation_owner_id=None, - valid_until=None, - cache_duration=None, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.signature=signature - self.extensions=extensions - self.affiliate_member=affiliate_member or [] - self.key_descriptor=key_descriptor or [] - self.affiliation_owner_id=affiliation_owner_id - self.valid_until=valid_until - self.cache_duration=cache_duration - self.id=id + signature=None, + extensions=None, + affiliate_member=None, + key_descriptor=None, + affiliation_owner_id=None, + valid_until=None, + cache_duration=None, + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.signature = signature + self.extensions = extensions + self.affiliate_member = affiliate_member or [] + self.key_descriptor = key_descriptor or [] + self.affiliation_owner_id = affiliation_owner_id + self.valid_until = valid_until + self.cache_duration = cache_duration + self.id = id + def affiliation_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(AffiliationDescriptorType_, @@ -1451,6 +1448,7 @@ class RoleDescriptor(RoleDescriptorType_): c_child_order = RoleDescriptorType_.c_child_order[:] c_cardinality = RoleDescriptorType_.c_cardinality.copy() + def role_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(RoleDescriptor, xml_string) @@ -1465,12 +1463,14 @@ class IDPSSODescriptor(IDPSSODescriptorType_): c_child_order = IDPSSODescriptorType_.c_child_order[:] c_cardinality = IDPSSODescriptorType_.c_cardinality.copy() + def idpsso_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(IDPSSODescriptor, xml_string) class AttributeConsumingService(AttributeConsumingServiceType_): - """The urn:oasis:names:tc:SAML:2.0:metadata:AttributeConsumingService element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:AttributeConsumingService + element """ c_tag = 'AttributeConsumingService' c_namespace = NAMESPACE @@ -1479,13 +1479,15 @@ class AttributeConsumingService(AttributeConsumingServiceType_): c_child_order = AttributeConsumingServiceType_.c_child_order[:] c_cardinality = AttributeConsumingServiceType_.c_cardinality.copy() + def attribute_consuming_service_from_string(xml_string): return saml2.create_class_from_xml_string(AttributeConsumingService, xml_string) class AuthnAuthorityDescriptor(AuthnAuthorityDescriptorType_): - """The urn:oasis:names:tc:SAML:2.0:metadata:AuthnAuthorityDescriptor element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:AuthnAuthorityDescriptor + element """ c_tag = 'AuthnAuthorityDescriptor' c_namespace = NAMESPACE @@ -1494,6 +1496,7 @@ class AuthnAuthorityDescriptor(AuthnAuthorityDescriptorType_): c_child_order = AuthnAuthorityDescriptorType_.c_child_order[:] c_cardinality = AuthnAuthorityDescriptorType_.c_cardinality.copy() + def authn_authority_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(AuthnAuthorityDescriptor, xml_string) @@ -1509,12 +1512,14 @@ class PDPDescriptor(PDPDescriptorType_): c_child_order = PDPDescriptorType_.c_child_order[:] c_cardinality = PDPDescriptorType_.c_cardinality.copy() + def pdp_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(PDPDescriptor, xml_string) class AttributeAuthorityDescriptor(AttributeAuthorityDescriptorType_): - """The urn:oasis:names:tc:SAML:2.0:metadata:AttributeAuthorityDescriptor element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:AttributeAuthorityDescriptor + element """ c_tag = 'AttributeAuthorityDescriptor' c_namespace = NAMESPACE @@ -1523,13 +1528,15 @@ class AttributeAuthorityDescriptor(AttributeAuthorityDescriptorType_): c_child_order = AttributeAuthorityDescriptorType_.c_child_order[:] c_cardinality = AttributeAuthorityDescriptorType_.c_cardinality.copy() + def attribute_authority_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(AttributeAuthorityDescriptor, xml_string) class AffiliationDescriptor(AffiliationDescriptorType_): - """The urn:oasis:names:tc:SAML:2.0:metadata:AffiliationDescriptor element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:AffiliationDescriptor element + """ c_tag = 'AffiliationDescriptor' c_namespace = NAMESPACE @@ -1538,6 +1545,7 @@ class AffiliationDescriptor(AffiliationDescriptorType_): c_child_order = AffiliationDescriptorType_.c_child_order[:] c_cardinality = AffiliationDescriptorType_.c_cardinality.copy() + def affiliation_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(AffiliationDescriptor, xml_string) @@ -1551,14 +1559,16 @@ class SPSSODescriptorType_(SSODescriptorType_): c_attributes = SSODescriptorType_.c_attributes.copy() c_child_order = SSODescriptorType_.c_child_order[:] c_cardinality = SSODescriptorType_.c_cardinality.copy() - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AssertionConsumerService'] = ( - 'assertion_consumer_service', - [AssertionConsumerService]) - c_cardinality['assertion_consumer_service'] = {"min":1} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AttributeConsumingService'] = ( - 'attribute_consuming_service', - [AttributeConsumingService]) - c_cardinality['attribute_consuming_service'] = {"min":0} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AssertionConsumerService'] = ( + 'assertion_consumer_service', + [AssertionConsumerService]) + c_cardinality['assertion_consumer_service'] = {"min": 1} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AttributeConsumingService'] = ( + 'attribute_consuming_service', + [AttributeConsumingService]) + c_cardinality['attribute_consuming_service'] = {"min": 0} c_attributes['AuthnRequestsSigned'] = ('authn_requests_signed', 'boolean', False) c_attributes['WantAssertionsSigned'] = ('want_assertions_signed', 'boolean', @@ -1567,51 +1577,52 @@ class SPSSODescriptorType_(SSODescriptorType_): 'attribute_consuming_service']) def __init__(self, - assertion_consumer_service=None, - attribute_consuming_service=None, - authn_requests_signed=None, - want_assertions_signed=None, - artifact_resolution_service=None, - single_logout_service=None, - manage_name_id_service=None, - name_id_format=None, - signature=None, - extensions=None, - key_descriptor=None, - organization=None, - contact_person=None, - id=None, - valid_until=None, - cache_duration=None, - protocol_support_enumeration=None, - error_url=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SSODescriptorType_.__init__(self, - artifact_resolution_service=artifact_resolution_service, - single_logout_service=single_logout_service, - manage_name_id_service=manage_name_id_service, - name_id_format=name_id_format, - signature=signature, - extensions=extensions, - key_descriptor=key_descriptor, - organization=organization, - contact_person=contact_person, - id=id, - valid_until=valid_until, - cache_duration=cache_duration, - protocol_support_enumeration=protocol_support_enumeration, - error_url=error_url, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.assertion_consumer_service=assertion_consumer_service or [] - self.attribute_consuming_service=attribute_consuming_service or [] - self.authn_requests_signed=authn_requests_signed - self.want_assertions_signed=want_assertions_signed + assertion_consumer_service=None, + attribute_consuming_service=None, + authn_requests_signed=None, + want_assertions_signed=None, + artifact_resolution_service=None, + single_logout_service=None, + manage_name_id_service=None, + name_id_format=None, + signature=None, + extensions=None, + key_descriptor=None, + organization=None, + contact_person=None, + id=None, + valid_until=None, + cache_duration=None, + protocol_support_enumeration=None, + error_url=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + SSODescriptorType_.__init__(self, + artifact_resolution_service=artifact_resolution_service, + single_logout_service=single_logout_service, + manage_name_id_service=manage_name_id_service, + name_id_format=name_id_format, + signature=signature, + extensions=extensions, + key_descriptor=key_descriptor, + organization=organization, + contact_person=contact_person, + id=id, + valid_until=valid_until, + cache_duration=cache_duration, + protocol_support_enumeration=protocol_support_enumeration, + error_url=error_url, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.assertion_consumer_service = assertion_consumer_service or [] + self.attribute_consuming_service = attribute_consuming_service or [] + self.authn_requests_signed = authn_requests_signed + self.want_assertions_signed = want_assertions_signed + def spsso_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(SPSSODescriptorType_, xml_string) @@ -1627,6 +1638,7 @@ class SPSSODescriptor(SPSSODescriptorType_): c_child_order = SPSSODescriptorType_.c_child_order[:] c_cardinality = SPSSODescriptorType_.c_cardinality.copy() + def spsso_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(SPSSODescriptor, xml_string) @@ -1642,51 +1654,56 @@ class EntityDescriptorType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}Signature'] = ('signature', ds.Signature) - c_cardinality['signature'] = {"min":0, "max":1} + c_cardinality['signature'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Extensions'] = ( - 'extensions', - Extensions) - c_cardinality['extensions'] = {"min":0, "max":1} + 'extensions', + Extensions) + c_cardinality['extensions'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}RoleDescriptor'] = ( - 'role_descriptor', - [RoleDescriptor]) - c_cardinality['role_descriptor'] = {"min":0} + 'role_descriptor', + [RoleDescriptor]) + c_cardinality['role_descriptor'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}IDPSSODescriptor'] = ( - 'idpsso_descriptor', - [IDPSSODescriptor]) - c_cardinality['idpsso_descriptor'] = {"min":0} + 'idpsso_descriptor', + [IDPSSODescriptor]) + c_cardinality['idpsso_descriptor'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}SPSSODescriptor'] = ( - 'spsso_descriptor', - [SPSSODescriptor]) - c_cardinality['spsso_descriptor'] = {"min":0} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AuthnAuthorityDescriptor'] = ( - 'authn_authority_descriptor', - [AuthnAuthorityDescriptor]) - c_cardinality['authn_authority_descriptor'] = {"min":0} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AttributeAuthorityDescriptor'] = ( - 'attribute_authority_descriptor', - [AttributeAuthorityDescriptor]) - c_cardinality['attribute_authority_descriptor'] = {"min":0} + 'spsso_descriptor', + [SPSSODescriptor]) + c_cardinality['spsso_descriptor'] = {"min": 0} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AuthnAuthorityDescriptor'] = ( + 'authn_authority_descriptor', + [AuthnAuthorityDescriptor]) + c_cardinality['authn_authority_descriptor'] = {"min": 0} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AttributeAuthorityDescriptor']\ + = ( + 'attribute_authority_descriptor', + [AttributeAuthorityDescriptor]) + c_cardinality['attribute_authority_descriptor'] = {"min": 0} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}PDPDescriptor'] = ( - 'pdp_descriptor', - [PDPDescriptor]) - c_cardinality['pdp_descriptor'] = {"min":0} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AffiliationDescriptor'] = ( - 'affiliation_descriptor', - AffiliationDescriptor) - c_cardinality['affiliation_descriptor'] = {"min":0, "max":1} + 'pdp_descriptor', + [PDPDescriptor]) + c_cardinality['pdp_descriptor'] = {"min": 0} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AffiliationDescriptor'] = ( + 'affiliation_descriptor', + AffiliationDescriptor) + c_cardinality['affiliation_descriptor'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Organization'] = ( - 'organization', - Organization) - c_cardinality['organization'] = {"min":0, "max":1} + 'organization', + Organization) + c_cardinality['organization'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}ContactPerson'] = ( - 'contact_person', - [ContactPerson]) - c_cardinality['contact_person'] = {"min":0} - c_children['{urn:oasis:names:tc:SAML:2.0:metadata}AdditionalMetadataLocation'] = ( - 'additional_metadata_location', - [AdditionalMetadataLocation]) - c_cardinality['additional_metadata_location'] = {"min":0} + 'contact_person', + [ContactPerson]) + c_cardinality['contact_person'] = {"min": 0} + c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}AdditionalMetadataLocation'] = ( + 'additional_metadata_location', + [AdditionalMetadataLocation]) + c_cardinality['additional_metadata_location'] = {"min": 0} c_attributes['entityID'] = ('entity_id', EntityIDType_, True) c_attributes['validUntil'] = ('valid_until', 'dateTime', False) c_attributes['cacheDuration'] = ('cache_duration', 'duration', False) @@ -1699,47 +1716,49 @@ class EntityDescriptorType_(SamlBase): 'contact_person', 'additional_metadata_location']) def __init__(self, - signature=None, - extensions=None, - role_descriptor=None, - idpsso_descriptor=None, - spsso_descriptor=None, - authn_authority_descriptor=None, - attribute_authority_descriptor=None, - pdp_descriptor=None, - affiliation_descriptor=None, - organization=None, - contact_person=None, - additional_metadata_location=None, - entity_id=None, - valid_until=None, - cache_duration=None, - id=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.signature=signature - self.extensions=extensions - self.role_descriptor=role_descriptor or [] - self.idpsso_descriptor=idpsso_descriptor or [] - self.spsso_descriptor=spsso_descriptor or [] - self.authn_authority_descriptor=authn_authority_descriptor or [] - self.attribute_authority_descriptor=attribute_authority_descriptor or [] - self.pdp_descriptor=pdp_descriptor or [] - self.affiliation_descriptor=affiliation_descriptor - self.organization=organization - self.contact_person=contact_person or [] - self.additional_metadata_location=additional_metadata_location or [] - self.entity_id=entity_id - self.valid_until=valid_until - self.cache_duration=cache_duration - self.id=id + signature=None, + extensions=None, + role_descriptor=None, + idpsso_descriptor=None, + spsso_descriptor=None, + authn_authority_descriptor=None, + attribute_authority_descriptor=None, + pdp_descriptor=None, + affiliation_descriptor=None, + organization=None, + contact_person=None, + additional_metadata_location=None, + entity_id=None, + valid_until=None, + cache_duration=None, + id=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.signature = signature + self.extensions = extensions + self.role_descriptor = role_descriptor or [] + self.idpsso_descriptor = idpsso_descriptor or [] + self.spsso_descriptor = spsso_descriptor or [] + self.authn_authority_descriptor = authn_authority_descriptor or [] + self.attribute_authority_descriptor = attribute_authority_descriptor \ + or [] + self.pdp_descriptor = pdp_descriptor or [] + self.affiliation_descriptor = affiliation_descriptor + self.organization = organization + self.contact_person = contact_person or [] + self.additional_metadata_location = additional_metadata_location or [] + self.entity_id = entity_id + self.valid_until = valid_until + self.cache_duration = cache_duration + self.id = id + def entity_descriptor_type__from_string(xml_string): return saml2.create_class_from_xml_string(EntityDescriptorType_, xml_string) @@ -1755,6 +1774,7 @@ class EntityDescriptor(EntityDescriptorType_): c_child_order = EntityDescriptorType_.c_child_order[:] c_cardinality = EntityDescriptorType_.c_cardinality.copy() + def entity_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(EntityDescriptor, xml_string) @@ -1762,7 +1782,8 @@ def entity_descriptor_from_string(xml_string): #.................. # ['EntitiesDescriptor', 'EntitiesDescriptorType'] class EntitiesDescriptorType_(SamlBase): - """The urn:oasis:names:tc:SAML:2.0:metadata:EntitiesDescriptorType element """ + """The urn:oasis:names:tc:SAML:2.0:metadata:EntitiesDescriptorType + element """ c_tag = 'EntitiesDescriptorType' c_namespace = NAMESPACE @@ -1772,16 +1793,16 @@ class EntitiesDescriptorType_(SamlBase): c_cardinality = SamlBase.c_cardinality.copy() c_children['{http://www.w3.org/2000/09/xmldsig#}Signature'] = ('signature', ds.Signature) - c_cardinality['signature'] = {"min":0, "max":1} + c_cardinality['signature'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}Extensions'] = ( - 'extensions', - Extensions) - c_cardinality['extensions'] = {"min":0, "max":1} + 'extensions', + Extensions) + c_cardinality['extensions'] = {"min": 0, "max": 1} c_children['{urn:oasis:names:tc:SAML:2.0:metadata}EntityDescriptor'] = ( - 'entity_descriptor', - [EntityDescriptor]) - c_cardinality['entity_descriptor'] = {"min":0} - c_cardinality['entities_descriptor'] = {"min":0} + 'entity_descriptor', + [EntityDescriptor]) + c_cardinality['entity_descriptor'] = {"min": 0} + c_cardinality['entities_descriptor'] = {"min": 0} c_attributes['validUntil'] = ('valid_until', 'dateTime', False) c_attributes['cacheDuration'] = ('cache_duration', 'duration', False) c_attributes['ID'] = ('id', 'ID', False) @@ -1790,34 +1811,36 @@ class EntitiesDescriptorType_(SamlBase): 'entities_descriptor']) def __init__(self, - signature=None, - extensions=None, - entity_descriptor=None, - entities_descriptor=None, - valid_until=None, - cache_duration=None, - id=None, - name=None, - text=None, - extension_elements=None, - extension_attributes=None, - ): - SamlBase.__init__(self, - text=text, - extension_elements=extension_elements, - extension_attributes=extension_attributes, - ) - self.signature=signature - self.extensions=extensions - self.entity_descriptor=entity_descriptor or [] - self.entities_descriptor=entities_descriptor or [] - self.valid_until=valid_until - self.cache_duration=cache_duration - self.id=id - self.name=name + signature=None, + extensions=None, + entity_descriptor=None, + entities_descriptor=None, + valid_until=None, + cache_duration=None, + id=None, + name=None, + text=None, + extension_elements=None, + extension_attributes=None, + ): + SamlBase.__init__(self, + text=text, + extension_elements=extension_elements, + extension_attributes=extension_attributes, + ) + self.signature = signature + self.extensions = extensions + self.entity_descriptor = entity_descriptor or [] + self.entities_descriptor = entities_descriptor or [] + self.valid_until = valid_until + self.cache_duration = cache_duration + self.id = id + self.name = name + def entities_descriptor_type__from_string(xml_string): - return saml2.create_class_from_xml_string(EntitiesDescriptorType_, xml_string) + return saml2.create_class_from_xml_string(EntitiesDescriptorType_, + xml_string) class EntitiesDescriptor(EntitiesDescriptorType_): @@ -1830,17 +1853,20 @@ class EntitiesDescriptor(EntitiesDescriptorType_): c_child_order = EntitiesDescriptorType_.c_child_order[:] c_cardinality = EntitiesDescriptorType_.c_cardinality.copy() + def entities_descriptor_from_string(xml_string): return saml2.create_class_from_xml_string(EntitiesDescriptor, xml_string) # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -EntitiesDescriptorType_.c_children['{urn:oasis:names:tc:SAML:2.0:metadata}EntitiesDescriptor'] = ( - 'entities_descriptor', - [EntitiesDescriptor]) -EntitiesDescriptor.c_children['{urn:oasis:names:tc:SAML:2.0:metadata}EntitiesDescriptor'] = ( - 'entities_descriptor', - [EntitiesDescriptor]) +EntitiesDescriptorType_.c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}EntitiesDescriptor'] = ( + 'entities_descriptor', + [EntitiesDescriptor]) +EntitiesDescriptor.c_children[ + '{urn:oasis:names:tc:SAML:2.0:metadata}EntitiesDescriptor'] = ( + 'entities_descriptor', + [EntitiesDescriptor]) # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ELEMENT_FROM_STRING = { @@ -1869,7 +1895,8 @@ ELEMENT_FROM_STRING = { TelephoneNumber.c_tag: telephone_number_from_string, ContactTypeType_.c_tag: contact_type_type__from_string, AdditionalMetadataLocation.c_tag: additional_metadata_location_from_string, - AdditionalMetadataLocationType_.c_tag: additional_metadata_location_type__from_string, + AdditionalMetadataLocationType_.c_tag: + additional_metadata_location_type__from_string, RoleDescriptor.c_tag: role_descriptor_from_string, AnyURIListType_.c_tag: any_uri_list_type__from_string, KeyDescriptor.c_tag: key_descriptor_from_string, @@ -1890,19 +1917,23 @@ ELEMENT_FROM_STRING = { SPSSODescriptorType_.c_tag: spsso_descriptor_type__from_string, AssertionConsumerService.c_tag: assertion_consumer_service_from_string, AttributeConsumingService.c_tag: attribute_consuming_service_from_string, - AttributeConsumingServiceType_.c_tag: attribute_consuming_service_type__from_string, + AttributeConsumingServiceType_.c_tag: + attribute_consuming_service_type__from_string, ServiceName.c_tag: service_name_from_string, ServiceDescription.c_tag: service_description_from_string, RequestedAttribute.c_tag: requested_attribute_from_string, RequestedAttributeType_.c_tag: requested_attribute_type__from_string, AuthnAuthorityDescriptor.c_tag: authn_authority_descriptor_from_string, - AuthnAuthorityDescriptorType_.c_tag: authn_authority_descriptor_type__from_string, + AuthnAuthorityDescriptorType_.c_tag: + authn_authority_descriptor_type__from_string, AuthnQueryService.c_tag: authn_query_service_from_string, PDPDescriptor.c_tag: pdp_descriptor_from_string, PDPDescriptorType_.c_tag: pdp_descriptor_type__from_string, AuthzService.c_tag: authz_service_from_string, - AttributeAuthorityDescriptor.c_tag: attribute_authority_descriptor_from_string, - AttributeAuthorityDescriptorType_.c_tag: attribute_authority_descriptor_type__from_string, + AttributeAuthorityDescriptor.c_tag: + attribute_authority_descriptor_from_string, + AttributeAuthorityDescriptorType_.c_tag: + attribute_authority_descriptor_type__from_string, AttributeService.c_tag: attribute_service_from_string, AffiliationDescriptor.c_tag: affiliation_descriptor_from_string, AffiliationDescriptorType_.c_tag: affiliation_descriptor_type__from_string, diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py index 28f5c8a0..0b1f6bfc 100644 --- a/src/saml2/metadata.py +++ b/src/saml2/metadata.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +from saml2.sigver import security_context +from saml2.config import Config +from saml2.validate import valid_instance from saml2.time_util import in_a_while from saml2.extension import mdui, idpdisc, shibmd, mdattr from saml2.saml import NAME_FORMAT_URI, AttributeValue, Attribute @@ -10,7 +13,8 @@ from saml2 import BINDING_SOAP from saml2 import samlp from saml2 import class_name import xmldsig as ds - +import sys +import os from saml2.sigver import pre_signature_part from saml2.s_utils import factory @@ -41,6 +45,55 @@ ORG_ATTR_TRANSL = { "organization_url": ("url", md.OrganizationURL) } +def metadata_tostring_fix(desc, nspair): + MDNS = '"urn:oasis:names:tc:SAML:2.0:metadata"' + XMLNSXS = " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"" + xmlstring = desc.to_string(nspair) + if "\"xs:string\"" in xmlstring and XMLNSXS not in xmlstring: + xmlstring = xmlstring.replace(MDNS, MDNS+XMLNSXS) + return xmlstring + + +def create_metadata_string(configfile, config, valid, cert, keyfile, id, name, sign): + valid_for = 0 + nspair = {"xs": "http://www.w3.org/2001/XMLSchema"} + paths = [".", "/opt/local/bin"] + + if valid: + valid_for = int(valid) #Hours + + + eds = [] + if config is not None: + eds.append(entity_descriptor(config)) + else: + if configfile.endswith(".py"): + configfile = configfile[:-3] + config = Config().load_file(configfile, metadata_construction=True) + eds.append(entity_descriptor(config)) + + conf = Config() + conf.key_file = keyfile + conf.cert_file = cert + conf.debug = 1 + conf.xmlsec_binary = config.xmlsec_binary + secc = security_context(conf) + + if id: + desc = entities_descriptor(eds, valid_for, name, id, + sign, secc) + valid_instance(desc) + + return metadata_tostring_fix(desc, nspair) + else: + for eid in eds: + if sign: + desc = sign_entity_descriptor(eid, id, secc) + else: + desc = eid + valid_instance(desc) + return metadata_tostring_fix(desc, nspair) + def _localized_name(val, klass): """If no language is defined 'en' is the default""" diff --git a/src/saml2/pack.py b/src/saml2/pack.py index 7ce2d5d2..8f28d341 100644 --- a/src/saml2/pack.py +++ b/src/saml2/pack.py @@ -135,7 +135,7 @@ def http_redirect_message(message, location, relay_state="", typ="SAMLRequest", if sigalg == RSA_SHA1: signer = RSASigner(sha1_digest, "sha1") - string = "&".join([urllib.urlencode({k: args[k]}) for k in _order]) + string = "&".join([urllib.urlencode({k: args[k]}) for k in _order if k in args]) args["Signature"] = base64.b64encode(signer.sign(string, key)) string = urllib.urlencode(args) else: @@ -265,4 +265,4 @@ def packager(identifier): def factory(binding, message, location, relay_state="", typ="SAMLRequest"): - return PACKING[binding](message, location, relay_state, typ)
\ No newline at end of file + return PACKING[binding](message, location, relay_state, typ) diff --git a/src/saml2/request.py b/src/saml2/request.py index 0df0d24c..c6804344 100644 --- a/src/saml2/request.py +++ b/src/saml2/request.py @@ -77,7 +77,7 @@ class Request(object): assert self.message.version == "2.0" if self.message.destination and \ self.message.destination not in self.receiver_addrs: - logger.error("%s != %s" % (self.message.destination, + logger.error("%s not in %s" % (self.message.destination, self.receiver_addrs)) raise OtherError("Not destined for me!") @@ -232,4 +232,4 @@ SERVICE2REQUEST = { "name_id_mapping_service": NameIDMappingRequest, #"artifact_resolve_service": ArtifactResolve, "single_logout_service": LogoutRequest -}
\ No newline at end of file +} diff --git a/src/saml2/response.py b/src/saml2/response.py index 005a0dfa..4c30cff4 100644 --- a/src/saml2/response.py +++ b/src/saml2/response.py @@ -220,7 +220,7 @@ def for_me(conditions, myself): return False -def authn_response(conf, return_addr, outstanding_queries=None, timeslack=0, +def authn_response(conf, return_addrs, outstanding_queries=None, timeslack=0, asynchop=True, allow_unsolicited=False, want_assertions_signed=False): sec = security_context(conf) if not timeslack: @@ -230,13 +230,13 @@ def authn_response(conf, return_addr, outstanding_queries=None, timeslack=0, timeslack = 0 return AuthnResponse(sec, conf.attribute_converters, conf.entityid, - return_addr, outstanding_queries, timeslack, + return_addrs, outstanding_queries, timeslack, asynchop=asynchop, allow_unsolicited=allow_unsolicited, want_assertions_signed=want_assertions_signed) # comes in over SOAP so synchronous -def attribute_response(conf, return_addr, timeslack=0, asynchop=False, +def attribute_response(conf, return_addrs, timeslack=0, asynchop=False, test=False): sec = security_context(conf) if not timeslack: @@ -246,17 +246,17 @@ def attribute_response(conf, return_addr, timeslack=0, asynchop=False, timeslack = 0 return AttributeResponse(sec, conf.attribute_converters, conf.entityid, - return_addr, timeslack, asynchop=asynchop, + return_addrs, timeslack, asynchop=asynchop, test=test) class StatusResponse(object): msgtype = "status_response" - def __init__(self, sec_context, return_addr=None, timeslack=0, + def __init__(self, sec_context, return_addrs=None, timeslack=0, request_id=0, asynchop=True): self.sec = sec_context - self.return_addr = return_addr + self.return_addrs = return_addrs self.timeslack = timeslack self.request_id = request_id @@ -382,9 +382,9 @@ class StatusResponse(object): if self.asynchop: if self.response.destination and \ - self.response.destination != self.return_addr: - logger.error("%s != %s" % (self.response.destination, - self.return_addr)) + self.response.destination not in self.return_addrs: + logger.error("%s not in %s" % (self.response.destination, + self.return_addrs)) return None assert self.issue_instant_ok() @@ -413,9 +413,9 @@ class StatusResponse(object): class LogoutResponse(StatusResponse): msgtype = "logout_response" - def __init__(self, sec_context, return_addr=None, timeslack=0, + def __init__(self, sec_context, return_addrs=None, timeslack=0, asynchop=True): - StatusResponse.__init__(self, sec_context, return_addr, timeslack, + StatusResponse.__init__(self, sec_context, return_addrs, timeslack, asynchop=asynchop) self.signature_check = self.sec.correctly_signed_logout_response @@ -423,9 +423,9 @@ class LogoutResponse(StatusResponse): class NameIDMappingResponse(StatusResponse): msgtype = "name_id_mapping_response" - def __init__(self, sec_context, return_addr=None, timeslack=0, + def __init__(self, sec_context, return_addrs=None, timeslack=0, request_id=0, asynchop=True): - StatusResponse.__init__(self, sec_context, return_addr, timeslack, + StatusResponse.__init__(self, sec_context, return_addrs, timeslack, request_id, asynchop) self.signature_check = self.sec.correctly_signed_name_id_mapping_response @@ -433,9 +433,9 @@ class NameIDMappingResponse(StatusResponse): class ManageNameIDResponse(StatusResponse): msgtype = "manage_name_id_response" - def __init__(self, sec_context, return_addr=None, timeslack=0, + def __init__(self, sec_context, return_addrs=None, timeslack=0, request_id=0, asynchop=True): - StatusResponse.__init__(self, sec_context, return_addr, timeslack, + StatusResponse.__init__(self, sec_context, return_addrs, timeslack, request_id, asynchop) self.signature_check = self.sec.correctly_signed_manage_name_id_response @@ -449,12 +449,12 @@ class AuthnResponse(StatusResponse): msgtype = "authn_response" def __init__(self, sec_context, attribute_converters, entity_id, - return_addr=None, outstanding_queries=None, + return_addrs=None, outstanding_queries=None, timeslack=0, asynchop=True, allow_unsolicited=False, test=False, allow_unknown_attributes=False, want_assertions_signed=False, **kwargs): - StatusResponse.__init__(self, sec_context, return_addr, timeslack, + StatusResponse.__init__(self, sec_context, return_addrs, timeslack, asynchop=asynchop) self.entity_id = entity_id self.attribute_converters = attribute_converters @@ -875,10 +875,10 @@ class AuthnQueryResponse(AuthnResponse): msgtype = "authn_query_response" def __init__(self, sec_context, attribute_converters, entity_id, - return_addr=None, timeslack=0, asynchop=False, test=False): + return_addrs=None, timeslack=0, asynchop=False, test=False): AuthnResponse.__init__(self, sec_context, attribute_converters, - entity_id, return_addr, timeslack=timeslack, + entity_id, return_addrs, timeslack=timeslack, asynchop=asynchop, test=test) self.entity_id = entity_id self.attribute_converters = attribute_converters @@ -893,10 +893,10 @@ class AttributeResponse(AuthnResponse): msgtype = "attribute_response" def __init__(self, sec_context, attribute_converters, entity_id, - return_addr=None, timeslack=0, asynchop=False, test=False): + return_addrs=None, timeslack=0, asynchop=False, test=False): AuthnResponse.__init__(self, sec_context, attribute_converters, - entity_id, return_addr, timeslack=timeslack, + entity_id, return_addrs, timeslack=timeslack, asynchop=asynchop, test=test) self.entity_id = entity_id self.attribute_converters = attribute_converters @@ -910,9 +910,9 @@ class AuthzResponse(AuthnResponse): msgtype = "authz_decision_response" def __init__(self, sec_context, attribute_converters, entity_id, - return_addr=None, timeslack=0, asynchop=False): + return_addrs=None, timeslack=0, asynchop=False): AuthnResponse.__init__(self, sec_context, attribute_converters, - entity_id, return_addr, timeslack=timeslack, + entity_id, return_addrs, timeslack=timeslack, asynchop=asynchop) self.entity_id = entity_id self.attribute_converters = attribute_converters @@ -924,10 +924,10 @@ class ArtifactResponse(AuthnResponse): msgtype = "artifact_response" def __init__(self, sec_context, attribute_converters, entity_id, - return_addr=None, timeslack=0, asynchop=False, test=False): + return_addrs=None, timeslack=0, asynchop=False, test=False): AuthnResponse.__init__(self, sec_context, attribute_converters, - entity_id, return_addr, timeslack=timeslack, + entity_id, return_addrs, timeslack=timeslack, asynchop=asynchop, test=test) self.entity_id = entity_id self.attribute_converters = attribute_converters @@ -935,7 +935,7 @@ class ArtifactResponse(AuthnResponse): self.context = "ArtifactResolve" -def response_factory(xmlstr, conf, return_addr=None, outstanding_queries=None, +def response_factory(xmlstr, conf, return_addrs=None, outstanding_queries=None, timeslack=0, decode=True, request_id=0, origxml=None, asynchop=True, allow_unsolicited=False, want_assertions_signed=False): sec_context = security_context(conf) @@ -949,13 +949,13 @@ def response_factory(xmlstr, conf, return_addr=None, outstanding_queries=None, entity_id = conf.entityid extension_schema = conf.extension_schema - response = StatusResponse(sec_context, return_addr, timeslack, request_id, + response = StatusResponse(sec_context, return_addrs, timeslack, request_id, asynchop) try: response.loads(xmlstr, decode, origxml) if response.response.assertion or response.response.encrypted_assertion: authnresp = AuthnResponse(sec_context, attribute_converters, - entity_id, return_addr, + entity_id, return_addrs, outstanding_queries, timeslack, asynchop, allow_unsolicited, extension_schema=extension_schema, @@ -965,7 +965,7 @@ def response_factory(xmlstr, conf, return_addr=None, outstanding_queries=None, except TypeError: response.signature_check = sec_context.correctly_signed_logout_response response.loads(xmlstr, decode, origxml) - logoutresp = LogoutResponse(sec_context, return_addr, timeslack, + logoutresp = LogoutResponse(sec_context, return_addrs, timeslack, asynchop=asynchop) logoutresp.update(response) return logoutresp diff --git a/src/saml2/samlp.py b/src/saml2/samlp.py index 67e1c550..e9ce3343 100644 --- a/src/saml2/samlp.py +++ b/src/saml2/samlp.py @@ -576,12 +576,11 @@ class AuthzDecisionQueryType_(SubjectQueryAbstractType_): c_attributes = SubjectQueryAbstractType_.c_attributes.copy() c_child_order = SubjectQueryAbstractType_.c_child_order[:] c_cardinality = SubjectQueryAbstractType_.c_cardinality.copy() - c_children['{urn:oasis:names:tc:SAML:2.0:assertion}Action'] = ('action', - [ - saml.Action]) + c_children['{urn:oasis:names:tc:SAML:2.0:assertion}Action'] = ( + 'action', [saml.Action]) c_cardinality['action'] = {"min": 1} - c_children['{urn:oasis:names:tc:SAML:2.0:assertion}Evidence'] = ('evidence', - saml.Evidence) + c_children['{urn:oasis:names:tc:SAML:2.0:assertion}Evidence'] = ( + 'evidence', saml.Evidence) c_cardinality['evidence'] = {"min": 0, "max": 1} c_attributes['Resource'] = ('resource', 'anyURI', True) c_child_order.extend(['action', 'evidence']) diff --git a/src/saml2/server.py b/src/saml2/server.py index 8a601734..97dad779 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -61,6 +61,7 @@ class Server(Entity): def __init__(self, config_file="", config=None, cache=None, stype="idp", symkey=""): Entity.__init__(self, stype, config, config_file) + self.eptid = None self.init_config(stype) self.cache = cache self.ticket = {} @@ -70,7 +71,6 @@ class Server(Entity): self.symkey = symkey self.seed = rndstr() self.iv = os.urandom(16) - self.eptid = None def support_AssertionIDRequest(self): return True @@ -207,9 +207,10 @@ class Server(Entity): "attribute_service", binding) def parse_authz_decision_query(self, xml_string, binding): - """ Parse an attribute query + """ Parse an authorization decision query :param xml_string: The Authz decision Query as an XML string + :param binding: Which binding that was used when receiving this query :return: Query instance """ @@ -220,6 +221,7 @@ class Server(Entity): """ Parse an assertion id query :param xml_string: The AssertionIDRequest as an XML string + :param binding: Which binding that was used when receiving this request :return: Query instance """ @@ -230,6 +232,7 @@ class Server(Entity): """ Parse an authn query :param xml_string: The AuthnQuery as an XML string + :param binding: Which binding that was used when receiving this query :return: Query instance """ @@ -240,6 +243,7 @@ class Server(Entity): """ Parse a nameid mapping request :param xml_string: The NameIDMappingRequest as an XML string + :param binding: Which binding that was used when receiving this request :return: Query instance """ diff --git a/src/saml2/userinfo/__init__.py b/src/saml2/userinfo/__init__.py new file mode 100644 index 00000000..4521e04b --- /dev/null +++ b/src/saml2/userinfo/__init__.py @@ -0,0 +1,55 @@ +# Interface to external user info resources + +import copy + + +class UserInfo(object): + """ Read only interface to a user info store """ + + def __init__(self): + pass + + def __call__(self, **kwargs): + pass + + +class UserInfoDB(UserInfo): + """ Read only interface to a user info store """ + + def __init__(self, db=None): + self.db = db + + @staticmethod + def filter(userinfo, user_info_claims=None): + """ + Return only those claims that are asked for. + It's a best effort task; if essential claims are not present + no error is flagged. + + :param userinfo: A dictionary containing the available user info. + :param user_info_claims: A dictionary specifying the asked for claims + :return: A dictionary of filtered claims. + """ + + if user_info_claims is None: + return copy.copy(userinfo) + else: + result = {} + missing = [] + optional = [] + for key, restr in user_info_claims.items(): + try: + result[key] = userinfo[key] + except KeyError: + if restr == {"essential": True}: + missing.append(key) + else: + optional.append(key) + return result + + def __call__(self, userid, user_info_claims=None, **kwargs): + try: + return self.filter(self.db[userid], user_info_claims) + except KeyError: + return {} + diff --git a/src/saml2/userinfo/ldapinfo.py b/src/saml2/userinfo/ldapinfo.py new file mode 100644 index 00000000..17b0905a --- /dev/null +++ b/src/saml2/userinfo/ldapinfo.py @@ -0,0 +1,37 @@ +import ldap +from ldap import SCOPE_SUBTREE +from saml2.userinfo import UserInfo + + +class UserInfoLDAP(UserInfo): + def __init__(self, uri, base, filter_pattern, scope=SCOPE_SUBTREE, + tls=False, user="", passwd="", attr=None, attrsonly=False): + UserInfo.__init__(self) + self.ldapuri = uri + self.base = base + self.filter_pattern = filter_pattern + self.scope = scope + self.tls = tls + self.attr = attr + self.attrsonly = attrsonly + self.ld = ldap.initialize(uri) + self.ld.protocol_version = ldap.VERSION3 + self.ld.simple_bind_s(user, passwd) + + def __call__(self, userid, base="", filter_pattern="", scope=SCOPE_SUBTREE, + tls=False, attr=None, attrsonly=False, **kwargs): + + if filter_pattern: + _filter = filter_pattern % userid + else: + _filter = self.filter_pattern % userid + + _base = base or self.base + _scope = scope or self.scope + _attr = attr or self.attr + _attrsonly = attrsonly or self.attrsonly + arg = [_base, _scope, _filter, _attr, _attrsonly] + res = self.ld.search_s(*arg) + # should only be one entry and the information per entry is + # the tuple (dn, ava) + return res[0][1]
\ No newline at end of file diff --git a/tests/entity_cat_re.xml b/tests/entity_cat_re.xml new file mode 100644 index 00000000..c8ce2cfe --- /dev/null +++ b/tests/entity_cat_re.xml @@ -0,0 +1,84 @@ +<?xml version='1.0' encoding='UTF-8'?> +<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:ns1="urn:oasis:names:tc:SAML:metadata:attribute" + xmlns:ns2="urn:oasis:names:tc:SAML:2.0:assertion" + xmlns:ns5="http://www.w3.org/2000/09/xmldsig#" + xmlns:ns4="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + entityID="urn:mace:example.com:saml:roland:sp"> + <ns0:Extensions> + <ns1:EntityAttributes> + <ns2:Attribute Name="http://macedir.org/entity-category"> + <ns2:AttributeValue xsi:type="xs:string"> + http://www.swamid.se/category/research-and-education + </ns2:AttributeValue> + </ns2:Attribute> + </ns1:EntityAttributes> + </ns0:Extensions> + <ns0:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" + protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> + <ns0:Extensions> + <ns4:DiscoveryResponse + Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" + Location="https://xenosmilus2.umdc.umu.se:8086/disco" + index="1"/> + </ns0:Extensions> + <ns0:KeyDescriptor use="encryption"> + <ns5:KeyInfo> + <ns5:X509Data> + <ns5:X509Certificate> + MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV + BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx + EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz + MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l + YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw + DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 + bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC + FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR + mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW + BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 + o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW + BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE + AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF + BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO + zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN + +vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= + </ns5:X509Certificate> + </ns5:X509Data> + </ns5:KeyInfo> + </ns0:KeyDescriptor> + <ns0:KeyDescriptor use="signing"> + <ns5:KeyInfo> + <ns5:X509Data> + <ns5:X509Certificate> + MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV + BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx + EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz + MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l + YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw + DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 + bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC + FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR + mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW + BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 + o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW + BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE + AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF + BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO + zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN + +vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= + </ns5:X509Certificate> + </ns5:X509Data> + </ns5:KeyInfo> + </ns0:KeyDescriptor> + <ns0:AssertionConsumerService + Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + Location="https://xenosmilus2.umdc.umu.se:8086/acs/sfs/re_nren/redirect" + index="1"/> + <ns0:AssertionConsumerService + Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + Location="https://xenosmilus2.umdc.umu.se:8086/acs/sfs/re_nren/post" + index="2"/> + </ns0:SPSSODescriptor> +</ns0:EntityDescriptor> diff --git a/tests/entity_cat_re_nren.xml b/tests/entity_cat_re_nren.xml new file mode 100644 index 00000000..ea45a8b4 --- /dev/null +++ b/tests/entity_cat_re_nren.xml @@ -0,0 +1,87 @@ +<?xml version='1.0' encoding='UTF-8'?> +<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xmlns:ns1="urn:oasis:names:tc:SAML:metadata:attribute" + xmlns:ns2="urn:oasis:names:tc:SAML:2.0:assertion" + xmlns:ns5="http://www.w3.org/2000/09/xmldsig#" + xmlns:ns4="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + entityID="urn:mace:example.com:saml:roland:sp"> + <ns0:Extensions> + <ns1:EntityAttributes> + <ns2:Attribute Name="http://macedir.org/entity-category"> + <ns2:AttributeValue xsi:type="xs:string"> + http://www.swamid.se/category/research-and-education + </ns2:AttributeValue> + <ns2:AttributeValue xsi:type="xs:string"> + http://www.swamid.se/category/nren-service + </ns2:AttributeValue> + </ns2:Attribute> + </ns1:EntityAttributes> + </ns0:Extensions> + <ns0:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" + protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> + <ns0:Extensions> + <ns4:DiscoveryResponse + Binding="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol" + Location="https://xenosmilus2.umdc.umu.se:8086/disco" + index="1"/> + </ns0:Extensions> + <ns0:KeyDescriptor use="encryption"> + <ns5:KeyInfo> + <ns5:X509Data> + <ns5:X509Certificate> + MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV + BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx + EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz + MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l + YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw + DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 + bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC + FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR + mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW + BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 + o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW + BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE + AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF + BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO + zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN + +vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= + </ns5:X509Certificate> + </ns5:X509Data> + </ns5:KeyInfo> + </ns0:KeyDescriptor> + <ns0:KeyDescriptor use="signing"> + <ns5:KeyInfo> + <ns5:X509Data> + <ns5:X509Certificate> + MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV + BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx + EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz + MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l + YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw + DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 + bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC + FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR + mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW + BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 + o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW + BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE + AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF + BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO + zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN + +vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= + </ns5:X509Certificate> + </ns5:X509Data> + </ns5:KeyInfo> + </ns0:KeyDescriptor> + <ns0:AssertionConsumerService + Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" + Location="https://xenosmilus2.umdc.umu.se:8086/acs/sfs/re_nren/redirect" + index="1"/> + <ns0:AssertionConsumerService + Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" + Location="https://xenosmilus2.umdc.umu.se:8086/acs/sfs/re_nren/post" + index="2"/> + </ns0:SPSSODescriptor> +</ns0:EntityDescriptor> diff --git a/tests/test_37_entity_categories.py b/tests/test_37_entity_categories.py index 85c5cd70..e62118bc 100644 --- a/tests/test_37_entity_categories.py +++ b/tests/test_37_entity_categories.py @@ -102,6 +102,53 @@ def test_filter_ava3(): assert _eq(ava.keys(), ['eduPersonTargetedID', "norEduPersonNIN"]) +def test_filter_ava4(): + policy = Policy({ + "default": { + "lifetime": {"minutes": 15}, + #"attribute_restrictions": None # means all I have + "entity_categories": ["swamid"] + } + }) + + mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config, + disable_ssl_certificate_validation=True) + mds.imp({"local": [full_path("entity_cat_re_nren.xml")]}) + + ava = {"givenName": ["Derek"], "sn": ["Jeter"], + "mail": ["derek@nyy.mlb.com"], "c": ["USA"], + "eduPersonTargetedID": "foo!bar!xyz", + "norEduPersonNIN": "19800101134"} + + ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", mds) + + assert _eq(ava.keys(), ['eduPersonTargetedID', "givenName", "c", "mail", + "sn"]) + + +def test_filter_ava5(): + policy = Policy({ + "default": { + "lifetime": {"minutes": 15}, + #"attribute_restrictions": None # means all I have + "entity_categories": ["swamid"] + } + }) + + mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config, + disable_ssl_certificate_validation=True) + mds.imp({"local": [full_path("entity_cat_re.xml")]}) + + ava = {"givenName": ["Derek"], "sn": ["Jeter"], + "mail": ["derek@nyy.mlb.com"], "c": ["USA"], + "eduPersonTargetedID": "foo!bar!xyz", + "norEduPersonNIN": "19800101134"} + + ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", mds) + + assert _eq(ava.keys(), ['eduPersonTargetedID']) + + def test_idp_policy_filter(): idp = Server("idp_conf_ec") diff --git a/tests/vo_metadata.xml b/tests/vo_metadata.xml index c6167ab2..2a2c80b7 100644 --- a/tests/vo_metadata.xml +++ b/tests/vo_metadata.xml @@ -1,7 +1,7 @@ <?xml version='1.0' encoding='UTF-8'?> <ns0:EntitiesDescriptor name="urn:mace:example.com:votest" - validUntil="2010-11-28T09:10:09Z" + validUntil="2014-11-28T09:10:09Z" xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata"> <ns0:EntityDescriptor entityID="urn:mace:example.com:it:tek"> diff --git a/tools/mdexport.py b/tools/mdexport.py index 93dce704..348335ad 100755 --- a/tools/mdexport.py +++ b/tools/mdexport.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -import sys from saml2.sigver import _get_xmlsec_cryptobackend, SecurityContext from saml2.httpbase import HTTPBase |