diff --git a/src/saml2/__init__.py b/src/saml2/__init__.py index 3dc9135..77be1c1 100644 --- a/src/saml2/__init__.py +++ b/src/saml2/__init__.py @@ -323,6 +323,60 @@ class ExtensionContainer(object): return results +def make_vals(val, klass, klass_inst=None, prop=None, part=False, + base64encode=False): + """ + Creates a class instance with a specified value, the specified + class instance may be a value on a property in a defined class instance. + + :param val: The value + :param klass: The value class + :param klass_inst: The class instance which has a property on which + what this function returns is a value. + :param prop: The property which the value should be assigned to. + :param part: If the value is one of a possible list of values it should be + handled slightly different compared to if it isn't. + :return: Value class instance + """ + cinst = None + + print "make_vals(%s, %s)" % (val, klass) + + if isinstance(val, dict): + print "+" + cinst = klass().loadd(val, base64encode=base64encode) + else: + print "++" + try: + cinst = klass().set_text(val) + except ValueError, excp: + print "!! %s" % (excp,) + if not part: + cis = [make_vals(sval, klass, klass_inst, prop, True, + base64encode) for sval in val] + setattr(klass_inst, prop, cis) + else: + raise + + print "CINST: %s, part: %s" % (cinst,part) + + if part: + return cinst + else: + if cinst: + cis = [cinst] + setattr(klass_inst, prop, cis) + +def make_instance(klass, spec, base64encode=False): + """ + Constructs a class instance containing the specified information + + :param klass: The class + :param spec: Information to be placed in the instance (a dictionary) + :return: The instance + """ + + return klass().loadd(spec, base64encode) class SamlBase(ExtensionContainer): """A foundation class on which SAML classes are built. It @@ -462,6 +516,54 @@ class SamlBase(ExtensionContainer): childs.append(member) return childs + def set_text(self, val, base64encode=False): + """ """ + print "set_text: %s" % (val,) + if isinstance(val, bool): + if val: + setattr(self, "text", "true") + else: + setattr(self, "text", "false") + elif isinstance(val, int): + setattr(self, "text", "%d" % val) + elif isinstance(val, basestring): + setattr(self, "text", val) + elif val == None: + pass + else: + raise ValueError( "Type it shouldn't be '%s'" % (val,)) + + return self + + def loadd(self, ava, base64encode=False): + """ """ + for prop in self.c_attributes.values(): + print "# %s" % (prop) + if prop in ava: + if isinstance(ava[prop], bool): + setattr(self, prop, "%s" % ava[prop]) + elif isinstance(ava[prop], int): + setattr(self, prop, "%d" % ava[prop]) + else: + setattr(self, prop, ava[prop]) + + if "text" in ava: + self.set_text(ava["text"], base64encode) + + for prop, klassdef in self.c_children.values(): + print "## %s, %s" % (prop, klassdef) + if prop in ava: + print "### %s" % ava[prop] + if isinstance(klassdef, list): # means there can be a list of values + make_vals(ava[prop], klassdef[0], self, prop, + base64encode=base64encode) + else: + cis = make_vals(ava[prop], klassdef, self, prop, True, + base64encode) + setattr(self, prop, cis) + + return self + def extension_element_to_element(extension_element, translation_function, namespace=None): """ """ diff --git a/src/saml2/client.py b/src/saml2/client.py index 0c48487..80bdaa5 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -18,6 +18,7 @@ """Contains classes and functions that a SAML2.0 Service Provider (SP) may use to conclude its tasks. """ + import os import urllib import saml2 @@ -25,11 +26,11 @@ import base64 import time import sys from saml2.time_util import str_to_time, instant -from saml2.utils import sid, deflate_and_base64_encode, make_instance +from saml2.utils import sid, deflate_and_base64_encode from saml2.utils import do_attributes, args2dict from saml2 import samlp, saml, extension_element_to_element -from saml2 import VERSION, class_name +from saml2 import VERSION, class_name, make_instance from saml2.sigver import correctly_signed_response, decrypt from saml2.sigver import pre_signature_part, sign_assertion_using_xmlsec from saml2.sigver import sign_statement_using_xmlsec diff --git a/src/saml2/saml.py b/src/saml2/saml.py index 90434b2..c34d6dd 100644 --- a/src/saml2/saml.py +++ b/src/saml2/saml.py @@ -854,7 +854,7 @@ def _decode_attribute_value(typ, text): if typ == XSD + "float" or typ == XSD + "double": return str(float(text)) if typ == XSD + "boolean": - return "%s" % (text == "true") + return "%s" % (text == "true" or text == "True") if typ == XSD + "base64Binary": import base64 return base64.decodestring(text) @@ -881,7 +881,36 @@ class AttributeValue(SamlBase): self.text = _decode_attribute_value(typ, tree.text) else: self.text = tree.text - + + def set_text(self, val, base64encode=False): + print "AV.set_text(%s)" % (val,) + if base64encode: + import base64 + val = base64.encodestring(val) + setattr(self, "type", "xs:base64Binary") + else: + if isinstance(val, basestring): + setattr(self, "type", "xs:string") + elif isinstance(val, bool): + if val: + val = "true" + else: + val = "false" + setattr(self, "type", "xs:boolean") + elif isinstance(val, int): + val = str(val) + setattr(self, "type", "xs:integer") + elif isinstance(val, float): + val = str(val) + setattr(self, "type", "xs:float") + elif val == None: + val = "" + else: + raise ValueError + + setattr(self, "text", val) + return self + def attribute_value_from_string(xml_string): """ Create AttributeValue instance from an XML string """ return saml2.create_class_from_xml_string(AttributeValue, xml_string) diff --git a/src/saml2/server.py b/src/saml2/server.py index b6a7db9..9234e9d 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -21,9 +21,9 @@ or attribute authority (AA) may use to conclude its tasks. import shelve -from saml2 import saml, samlp, VERSION +from saml2 import saml, samlp, VERSION, make_instance -from saml2.utils import sid, decode_base64_and_inflate, make_instance +from saml2.utils import sid, decode_base64_and_inflate from saml2.utils import response_factory, do_ava_statement from saml2.utils import MissingValue, args2dict from saml2.utils import success_status_factory, assertion_factory diff --git a/src/saml2/utils.py b/src/saml2/utils.py index 755a4c7..0d174ac 100644 --- a/src/saml2/utils.py +++ b/src/saml2/utils.py @@ -98,112 +98,6 @@ def sid(seed=""): ident.update(seed) return ident.hexdigest() -def make_vals(val, klass, klass_inst=None, prop=None, part=False, - base64encode=False): - """ - Creates a class instance with a specified value, the specified - class instance are a value on a property in a defined class instance. - - :param val: The value - :param klass: The value class - :param klass_inst: The class instance which has a property on which - what this function returns is a value. - :param prop: The property which the value should be assigned to. - :param part: If the value is one of a possible list of values it should be - handled slightly different compared to if it isn't. - :return: Value class instance - """ - cinst = None - #print "_make_val: %s %s (%s) [%s]" % (prop,val,klass,part) - if isinstance(val, bool): - cinst = klass(text="%s" % val) - elif isinstance(val, int): - cinst = klass(text="%d" % val) - elif isinstance(val, basestring): - cinst = klass(text=val) - elif val == None: - cinst = klass() - elif isinstance(val, dict): - cinst = make_instance(klass, val, base64encode=base64encode) - elif not part: - cis = [make_vals(sval, klass, klass_inst, prop, True, - base64encode) for sval in val] - setattr(klass_inst, prop, cis) - else: - raise ValueError("strange instance type: %s on %s" % (type(val), val)) - - if part: - return cinst - else: - if cinst: - cis = [cinst] - setattr(klass_inst, prop, cis) - -def make_instance(klass, spec, base64encode=False): - """ - Constructs a class instance containing the specified information - - :param klass: The class - :param spec: Information to be placed in the instance (a dictionary) - :return: The instance - """ - #print "----- %s -----" % klass - #print "..... %s ....." % spec - klass_inst = klass() - for prop in klass.c_attributes.values(): - #print "# %s" % (prop) - if prop in spec: - if isinstance(spec[prop], bool): - setattr(klass_inst, prop,"%s" % spec[prop]) - elif isinstance(spec[prop], int): - setattr(klass_inst, prop, "%d" % spec[prop]) - else: - setattr(klass_inst, prop, spec[prop]) - - if "text" in spec: - val = spec["text"] - print "<<", klass - if klass == saml.AttributeValue: - print ">> AVA" - if base64encode: - import base64 - val = base64.encodestring(val) - setattr(klass_inst, "type", "xs:base64Binary") - else: - if isinstance(val, basestring): - print "basestring" - setattr(klass_inst, "type", "xs:string") - print klass_inst.__dict__ - elif isinstance(val, bool): - print "boolean", val - if val: - val = "true" - else: - val = "false" - setattr(klass_inst, "type", "xs:boolean") - elif isinstance(val, int): - val = str(val) - setattr(klass_inst, "type", "xs:integer") - elif isinstance(val, float): - val = str(val) - setattr(klass_inst, "type", "xs:float") - - setattr(klass_inst, "text", val) - - for prop, klass in klass.c_children.values(): - #print "## %s, %s" % (prop, klass) - if prop in spec: - #print "%s" % spec[prop] - if isinstance(klass, list): # means there can be a list of values - make_vals(spec[prop], klass[0], klass_inst, prop, - base64encode=base64encode) - else: - cis = make_vals(spec[prop], klass, klass_inst, prop, True, - base64encode) - setattr(klass_inst, prop, cis) - #+print ">>> %s <<<" % klass_inst - return klass_inst - def parse_attribute_map(filenames): """ Expects a file with each line being composed of the oid for the attribute diff --git a/tests/test_00_saml2.py b/tests/test_00_saml2.py index 7f035c5..3ff1c45 100644 --- a/tests/test_00_saml2.py +++ b/tests/test_00_saml2.py @@ -1,9 +1,10 @@ #!/usr/bin/env python -from saml2 import create_class_from_xml_string, class_name +from saml2 import create_class_from_xml_string, class_name, make_vals, md from saml2.saml import NameID, Issuer, SubjectLocality, AuthnContextClassRef from saml2.saml import SubjectConfirmationData, SubjectConfirmation import saml2 +from py.test import raises try: from xml.etree import cElementTree as ElementTree @@ -365,4 +366,32 @@ def test_to_fro_string_1(): assert klee.namespace == cpyee.namespace - \ No newline at end of file +def test_make_vals_str(): + kl = make_vals("Jeter",md.GivenName, part=True) + assert isinstance(kl, md.GivenName) + assert kl.text == "Jeter" + +def test_make_vals_int(): + kl = make_vals(1024,md.KeySize, part=True) + assert isinstance(kl, md.KeySize) + assert kl.text == "1024" + +def test_exception_make_vals_int_not_part(): + raises(TypeError, "make_vals(1024,md.KeySize)") + raises(TypeError, "make_vals(1024,md.KeySize,md.EncryptionMethod())") + raises(AttributeError, "make_vals(1024,md.KeySize,prop='key_size')") + +def test_make_vals_list_of_ints(): + em = md.EncryptionMethod() + make_vals([1024,2048], md.KeySize, em, "key_size") + assert len(em.key_size) == 2 + +def test_make_vals_list_of_strs(): + cp = md.ContactPerson() + make_vals(["Derek","Sanderson"], md.GivenName, cp, "given_name") + assert len(cp.given_name) == 2 + assert _eq([i.text for i in cp.given_name],["Sanderson","Derek"]) + +def test_exception_make_vals_value_error(): + raises(ValueError, "make_vals((1024,'xyz'), md.KeySize, part=True)") + diff --git a/tests/test_11_utils.py b/tests/test_11_utils.py index bfd5565..2e32b9b 100644 --- a/tests/test_11_utils.py +++ b/tests/test_11_utils.py @@ -5,8 +5,8 @@ import zlib import base64 import gzip -from saml2 import utils, saml, samlp, md -from saml2.utils import do_attribute_statement, make_instance +from saml2 import utils, saml, samlp, md, make_instance +from saml2.utils import do_attribute_statement from saml2.sigver import make_temp from saml2.config import do_assertions from saml2.saml import Attribute, NAME_FORMAT_URI, AttributeValue @@ -78,39 +78,11 @@ def test_status_from_exception(): print status_text assert status_text == ERROR_STATUS -def test_make_vals_str(): - kl = utils.make_vals("Jeter",md.GivenName, part=True) - assert isinstance(kl, md.GivenName) - assert kl.text == "Jeter" - -def test_make_vals_int(): - kl = utils.make_vals(1024,md.KeySize, part=True) - assert isinstance(kl, md.KeySize) - assert kl.text == "1024" - -def test_exception_make_vals_int_not_part(): - raises(TypeError, "utils.make_vals(1024,md.KeySize)") - raises(TypeError, "utils.make_vals(1024,md.KeySize,md.EncryptionMethod())") - raises(AttributeError, "utils.make_vals(1024,md.KeySize,prop='key_size')") - -def test_make_vals_list_of_ints(): - em = md.EncryptionMethod() - utils.make_vals([1024,2048], md.KeySize, em, "key_size") - assert len(em.key_size) == 2 - -def test_make_vals_list_of_strs(): - cp = md.ContactPerson() - utils.make_vals(["Derek","Sanderson"], md.GivenName, cp, "given_name") - assert len(cp.given_name) == 2 - assert _eq([i.text for i in cp.given_name],["Sanderson","Derek"]) - -def test_exception_make_vals_value_error(): - raises(ValueError, "utils.make_vals((1024,'xyz'), md.KeySize, part=True)") - def test_attribute_sn(): attr = utils.do_attributes({"surName":"Jeter"}) assert len(attr) == 1 + print attr inst = make_instance(saml.Attribute, attr[0]) print inst assert inst.name == "surName" diff --git a/tests/test_30_metadata.py b/tests/test_30_metadata.py index 8e8dd1f..5121f45 100644 --- a/tests/test_30_metadata.py +++ b/tests/test_30_metadata.py @@ -1,6 +1,6 @@ import os -from saml2 import metadata, utils +from saml2 import metadata, utils, make_vals, make_instance from saml2 import NAMESPACE as SAML2_NAMESPACE from saml2 import BINDING_SOAP from saml2 import md, saml, samlp @@ -132,46 +132,46 @@ def test_sp_metadata(): def test_construct_organisation_name(): o = md.Organization() - utils.make_vals({"text":"Exempel AB", "lang":"se"}, + make_vals({"text":"Exempel AB", "lang":"se"}, md.OrganizationName, o, "organization_name") print o assert str(o) == """ Exempel AB""" def test_make_int_value(): - val = utils.make_vals( 1, saml.AttributeValue, part=True) + val = make_vals( 1, saml.AttributeValue, part=True) assert isinstance(val, saml.AttributeValue) assert val.text == "1" def test_make_true_value(): - val = utils.make_vals( True, saml.AttributeValue, part=True ) + val = make_vals( True, saml.AttributeValue, part=True ) assert isinstance(val, saml.AttributeValue) - assert val.text == "True" + assert val.text == "true" def test_make_false_value(): - val = utils.make_vals( False, saml.AttributeValue, part=True ) + val = make_vals( False, saml.AttributeValue, part=True ) assert isinstance(val, saml.AttributeValue) - assert val.text == "False" + assert val.text == "false" NO_VALUE = """ """ def test_make_no_value(): - val = utils.make_vals( None, saml.AttributeValue, part=True ) + val = make_vals( None, saml.AttributeValue, part=True ) assert isinstance(val, saml.AttributeValue) - assert val.text == None + assert val.text == "" print val assert "%s" % val == NO_VALUE def test_make_string(): - val = utils.make_vals( "example", saml.AttributeValue, part=True ) + val = make_vals( "example", saml.AttributeValue, part=True ) assert isinstance(val, saml.AttributeValue) assert val.text == "example" def test_make_list_of_strings(): attr = saml.Attribute() vals = ["foo", "bar"] - val = utils.make_vals(vals, saml.AttributeValue, attr, + val = make_vals(vals, saml.AttributeValue, attr, "attribute_value") assert attr.keyswv() == ["attribute_value"] print attr.attribute_value @@ -180,14 +180,14 @@ def test_make_list_of_strings(): def test_make_dict(): vals = ["foo", "bar"] attrval = { "attribute_value": vals} - attr = utils.make_vals(attrval, saml.Attribute, part=True) + attr = make_vals(attrval, saml.Attribute, part=True) assert attr.keyswv() == ["attribute_value"] assert _eq([val.text for val in attr.attribute_value], vals) # ------------ Constructing metadata ---------------------------------------- def test_construct_contact(): - c = utils.make_instance(md.ContactPerson, { + c = make_instance(md.ContactPerson, { "given_name":"Roland", "sur_name": "Hedberg", "email_address": "roland@catalogix.se", @@ -200,7 +200,7 @@ def test_construct_contact(): def test_construct_organisation(): - c = utils.make_instance( md.Organization, { + c = make_instance( md.Organization, { "organization_name": ["Example Co.", {"text":"Exempel AB", "lang":"se"}], "organization_url": "http://www.example.com/" @@ -213,7 +213,7 @@ def test_construct_organisation(): assert len(c.organization_url) == 1 def test_construct_entity_descr_1(): - ed = utils.make_instance(md.EntityDescriptor, + ed = make_instance(md.EntityDescriptor, {"organization": { "organization_name":"Catalogix", "organization_url": "http://www.catalogix.se/"}, @@ -228,7 +228,7 @@ def test_construct_entity_descr_1(): assert org.organization_url[0].text == "http://www.catalogix.se/" def test_construct_entity_descr_2(): - ed = utils.make_instance(md.EntityDescriptor, + ed = make_instance(md.EntityDescriptor, {"organization": { "organization_name":"Catalogix", "organization_url": "http://www.catalogix.se/"}, @@ -264,7 +264,7 @@ def test_construct_key_descriptor(): } } } - kd = utils.make_instance(md.KeyDescriptor, spec) + kd = make_instance(md.KeyDescriptor, spec) assert _eq(kd.keyswv(), ["use", "key_info"]) assert kd.use == "signing" ki = kd.key_info @@ -286,7 +286,7 @@ def test_construct_key_descriptor_with_key_name(): } } } - kd = utils.make_instance(md.KeyDescriptor, spec) + kd = make_instance(md.KeyDescriptor, spec) assert _eq(kd.keyswv(), ["use", "key_info"]) assert kd.use == "signing" ki = kd.key_info @@ -300,7 +300,7 @@ def test_construct_key_descriptor_with_key_name(): assert len(data.x509_certificate[0].text.strip()) == len(cert) def test_construct_AttributeAuthorityDescriptor(): - aad = utils.make_instance( + aad = make_instance( md.AttributeAuthorityDescriptor, { "valid_until": time_util.in_a_while(30), # 30 days from now "id": "aad.example.com", @@ -354,6 +354,6 @@ def test_status(): }, "status_message": "Error resolving principal", } - status_text = "%s" % utils.make_instance( samlp.Status, input) + status_text = "%s" % make_instance( samlp.Status, input) assert status_text == STATUS_RESULT diff --git a/tests/test_40_sigver.py b/tests/test_40_sigver.py index ed08276..8e2512d 100644 --- a/tests/test_40_sigver.py +++ b/tests/test_40_sigver.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -from saml2 import sigver +from saml2 import sigver, make_instance from saml2 import utils from saml2 import time_util from saml2 import saml @@ -32,14 +32,14 @@ def test_non_verify_2(xmlsec): raises(sigver.SignatureError,sigver.correctly_signed_response, xml_response, xmlsec) -SIGNED_VALUE= """Y88SEXrU3emeoaTgEqUKYAvDtWiLpPMx1sClw0GJV98O6A5QRvB14vNs8xnXNFFZ -XVjksKECcqmf10k/2C3oJfaEOaM4w0DgVLXeuJU08irXfdHcoe1g3276F1If1Kh7 -63F7ihzh2ZeWV9OOO8tXofR9GCLIpPECbK+3/D4eEDY=""" +SIGNED_VALUE= """AS1kHHtA4eTOU2XLTWhLMSJQ6V+TSDymRoTF78CqjrYURNLk9wjdPjAReNn9eykv +ryFiHNk0p9wMBknha5pH8aeCI/LmcVhLa5xteGZrtE/Udh5vv8z4kRQX51Uz/5x8 +ToiobGw83MEW6A0dRUn0O20NBMMTaFZZPXye7RvVlHY=""" -DIGEST_VALUE = "9cQ0c72QfbQr1KkH9MCwL5Wm1EQ=" +DIGEST_VALUE = "WFRXmImfoO3M6JOLE6BGGpU9Ud0=" def test_sign(xmlsec): - ass = utils.make_instance(saml.Assertion, { + ass = make_instance(saml.Assertion, { "version": "2.0", "id": "11111", "issue_instant": "2009-10-30T13:20:28Z", diff --git a/tests/test_50_server.py b/tests/test_50_server.py index e292615..1ff25ae 100644 --- a/tests/test_50_server.py +++ b/tests/test_50_server.py @@ -2,9 +2,9 @@ # -*- coding: utf-8 -*- from saml2.server import Server -from saml2 import server +from saml2 import server, make_instance from saml2 import samlp, saml, client, utils -from saml2.utils import make_instance, OtherError +from saml2.utils import OtherError from saml2.utils import do_attribute_statement from py.test import raises import shelve @@ -77,12 +77,12 @@ class TestServer1(): assertion=utils.assertion_factory( subject = utils.args2dict("_aaa", name_id=saml.NAMEID_FORMAT_TRANSIENT), - attribute_statement = utils.args2dict([ + attribute_statement = [ utils.args2dict(attribute_value="Derek", friendly_name="givenName"), utils.args2dict(attribute_value="Jeter", friendly_name="surName"), - ]), + ], issuer=self.server.issuer(), ), issuer=self.server.issuer(), @@ -132,7 +132,7 @@ class TestServer1(): status = None except OtherError, oe: print oe.args - status = utils.make_instance(samlp.Status, + status = make_instance(samlp.Status, utils.status_from_exception_factory(oe)) assert status @@ -188,6 +188,18 @@ class TestServer1(): assert len(assertion.authn_statement) == 1 assert assertion.conditions assert len(assertion.attribute_statement) == 1 + attribute_statement = assertion.attribute_statement[0] + print attribute_statement + #Bat + assert len(attribute_statement.attribute) == 1 + attribute = attribute_statement.attribute[0] + assert len(attribute.attribute_value) == 1 + assert attribute.friendly_name == "eduPersonEntitlement" + assert attribute.name == "urn:oid:1.3.6.1.4.1.5923.1.1.1.7" + assert attribute.name_format == "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" + value = attribute.attribute_value[0] + assert value.text.strip() == "Bat" + assert value.type == "xs:string" assert assertion.subject assert assertion.subject.name_id assert len(assertion.subject.subject_confirmation) == 1 @@ -340,7 +352,7 @@ class TestServer1(): resp_str = self.server.authn_response(ava, "1", "http://local:8087/", "urn:mace:example.com:saml:roland:sp", - utils.make_instance(samlp.NameIDPolicy, + make_instance(samlp.NameIDPolicy, utils.args2dict( format=saml.NAMEID_FORMAT_TRANSIENT, allow_create="true")), diff --git a/tests/test_51_client.py b/tests/test_51_client.py index 8ff691f..6ae8d00 100644 --- a/tests/test_51_client.py +++ b/tests/test_51_client.py @@ -3,7 +3,7 @@ from saml2.client import Saml2Client from saml2 import samlp, client, BINDING_HTTP_POST -from saml2 import saml, utils, config, class_name +from saml2 import saml, utils, config, class_name, make_instance from saml2.sigver import correctly_signed_authn_request, verify_signature from saml2.sigver import correctly_signed_response from saml2.server import Server @@ -206,7 +206,7 @@ class TestClient: assert req == None def test_idp_entry(self): - idp_entry = utils.make_instance( samlp.IDPEntry, + idp_entry = make_instance( samlp.IDPEntry, self.client.idp_entry(name="Umeå Universitet", location="https://idp.umu.se/")) @@ -214,7 +214,7 @@ class TestClient: assert idp_entry.loc == "https://idp.umu.se/" def test_scope(self): - scope = utils.make_instance(samlp.Scoping, self.client.scoping( + scope = make_instance(samlp.Scoping, self.client.scoping( [self.client.idp_entry(name="Umeå Universitet", location="https://idp.umu.se/")])) diff --git a/tools/make_metadata.py b/tools/make_metadata.py index 8a0f466..d5c7ea5 100755 --- a/tools/make_metadata.py +++ b/tools/make_metadata.py @@ -2,7 +2,7 @@ import os import getopt from saml2 import utils, md, samlp, BINDING_HTTP_POST, BINDING_HTTP_REDIRECT -from saml2 import BINDING_SOAP, class_name +from saml2 import BINDING_SOAP, class_name, make_instance from saml2.time_util import in_a_while from saml2.utils import parse_attribute_map from saml2.saml import NAME_FORMAT_URI @@ -213,7 +213,7 @@ def entities_descriptor(eds, valid_for, name, id, sign, xmlsec, keyfile): if sign: d["signature"] = pre_signature_part(d["id"]) - statement = utils.make_instance(md.EntitiesDescriptor, d) + statement = make_instance(md.EntitiesDescriptor, d) if sign: statement = sign_statement_using_xmlsec("%s" % statement, class_name(statement),