summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFredrik Thulin <fredrik@thulin.net>2013-11-29 12:42:16 +0100
committerFredrik Thulin <fredrik@thulin.net>2013-11-29 12:42:16 +0100
commite8ebab62c8520492019f713e66852b310b90164a (patch)
tree9153acf208d86dbb38e4d5374e8bc2addd0b0d80
parent89ed3e3ab849b43ce76ad06a15e38ba9f16b7609 (diff)
parent94b574c56a7c2fe5b03d7ca948823c4b8af9fb39 (diff)
downloadpysaml2-e8ebab62c8520492019f713e66852b310b90164a.tar.gz
Merge branch 'master' of https://github.com/rohe/pysaml2
-rw-r--r--.gitignore24
-rwxr-xr-xexample/idp2/idp.py43
-rw-r--r--example/idp2/idp_user.py19
-rwxr-xr-xexample/sp/sp.py43
-rwxr-xr-xsetup.py3
-rw-r--r--src/s2repoze/plugins/sp.py22
-rw-r--r--src/saml2/assertion.py48
-rw-r--r--src/saml2/attribute_converter.py13
-rw-r--r--src/saml2/attributemaps/__init__.py1
-rw-r--r--src/saml2/attributemaps/saml_uri.py2
-rw-r--r--src/saml2/authn.py1
-rw-r--r--src/saml2/client.py2
-rw-r--r--src/saml2/client_base.py39
-rw-r--r--src/saml2/ecp_client.py12
-rw-r--r--src/saml2/entity.py11
-rw-r--r--src/saml2/entity_category/swamid.py4
-rw-r--r--src/saml2/md.py1299
-rw-r--r--src/saml2/metadata.py55
-rw-r--r--src/saml2/pack.py4
-rw-r--r--src/saml2/request.py4
-rw-r--r--src/saml2/response.py58
-rw-r--r--src/saml2/samlp.py9
-rw-r--r--src/saml2/server.py8
-rw-r--r--src/saml2/userinfo/__init__.py55
-rw-r--r--src/saml2/userinfo/ldapinfo.py37
-rw-r--r--tests/entity_cat_re.xml84
-rw-r--r--tests/entity_cat_re_nren.xml87
-rw-r--r--tests/test_37_entity_categories.py47
-rw-r--r--tests/vo_metadata.xml2
-rwxr-xr-xtools/mdexport.py1
30 files changed, 1299 insertions, 738 deletions
diff --git a/.gitignore b/.gitignore
index 02d5cce4..e4c06e56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/setup.py b/setup.py
index 7bc6ec96..019611bd 100755
--- a/setup.py
+++ b/setup.py
@@ -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