diff options
author | Roland Hedberg <roland@catalogix.se> | 2017-10-11 08:32:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-11 08:32:10 +0200 |
commit | b71f1443991c94099ff49226c92b8671d657fade (patch) | |
tree | 69cb8fb94681a3273d1fe995e0e79bb047d307cf /tests | |
parent | 546f9d4ca82c8b4ae5cf7aa0fb80f0bedf385c89 (diff) | |
parent | 9e6ddc0030828a17fe44a3ecdc5c95b6b6c8d741 (diff) | |
download | pysaml2-b71f1443991c94099ff49226c92b8671d657fade.tar.gz |
Merge branch 'master' into master
Diffstat (limited to 'tests')
-rw-r--r-- | tests/SWITCHaaiRootCA.crt.pem | 22 | ||||
-rw-r--r-- | tests/conftest.py | 11 | ||||
-rw-r--r-- | tests/server_conf.py | 13 | ||||
-rw-r--r-- | tests/sp_conf_nameidpolicy.py | 64 | ||||
-rw-r--r-- | tests/sp_mdext_conf.py | 2 | ||||
-rw-r--r-- | tests/test_19_attribute_converter.py | 95 | ||||
-rw-r--r-- | tests/test_20_assertion.py | 37 | ||||
-rw-r--r-- | tests/test_30_mdstore.py | 11 | ||||
-rw-r--r-- | tests/test_31_config.py | 11 | ||||
-rw-r--r-- | tests/test_50_server.py | 26 | ||||
-rw-r--r-- | tests/test_51_client.py | 81 | ||||
-rw-r--r-- | tests/test_65_authn_query.py | 2 | ||||
-rw-r--r-- | tests/test_68_assertion_id.py | 2 | ||||
-rw-r--r-- | tests/test_83_md_extensions.py | 12 | ||||
-rw-r--r-- | tests/test_requirements.txt | 1 |
15 files changed, 316 insertions, 74 deletions
diff --git a/tests/SWITCHaaiRootCA.crt.pem b/tests/SWITCHaaiRootCA.crt.pem new file mode 100644 index 00000000..66c9e5d0 --- /dev/null +++ b/tests/SWITCHaaiRootCA.crt.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgINSWITCHaai+Root+CAzANBgkqhkiG9w0BAQUFADBrMQsw
+CQYDVQQGEwJDSDFAMD4GA1UEChM3U3dpdGNoIC0gVGVsZWluZm9ybWF0aWtkaWVu
+c3RlIGZ1ZXIgTGVocmUgdW5kIEZvcnNjaHVuZzEaMBgGA1UEAxMRU1dJVENIYWFp
+IFJvb3QgQ0EwHhcNMDgwNTE1MDYzMDAwWhcNMjgwNTE1MDYyOTU5WjBrMQswCQYD
+VQQGEwJDSDFAMD4GA1UEChM3U3dpdGNoIC0gVGVsZWluZm9ybWF0aWtkaWVuc3Rl
+IGZ1ZXIgTGVocmUgdW5kIEZvcnNjaHVuZzEaMBgGA1UEAxMRU1dJVENIYWFpIFJv
+b3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUSWbn/rhWew/s
+LJRyciyRKDGyFXSgiDO/EohYuZLw6EAKLLlhZorNtEHQbbn0Oo13S33MclHMvGWT
+KJM0u1hG+6gLy78EPmJbqAE1Uv23wVEH4SX0VJfl3JVqIebiAH/CjuLubgMUspDI
+jOdQHNLS7pthTbm7Tgh7zMsiLPyMTZJep5CGbqv8NoK6bMaF0Z+Bt7e1JRlhHFCV
+iJJaR/+hfpzLsJ8NWVivvrpRGaGJ1XR+9FGsTkjNdMCirNJJZ6XvUOe5w7pHSd9M
+cppFP0eyLs02AMzMXI4iz6PK/w3EdzXGXpK+gSgvLxWYct4xHpv1e2NXhNgdJOSN
+9ra/wJLVAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
+MB0GA1UdDgQWBBTpmuIGWOsP14EDXVyXubG1k307hDANBgkqhkiG9w0BAQUFAAOC
+AQEAMV/eIW6pFB+mbk7rD7hUPTWDRaoca3kHqmFGFnHfuY8+c0/Mqjh8Y/jyX1yb
+f58crTSWrbyGbUZ3oxDGQ34tuZSkmeR32NqryiX3sP5qlNSozVguQKt8o4vhS1Qe
+WPsXALs3em2pdKuIGSOpbuDnopPcmU2g5Zi2R5P7qpKDKAKtNUEwV+LW7GBMEksO
+Nj7BFXk4AFBFBijaYJGgHmoKSImVgeNIvsV+BSv5HJ4q6vcxfnwuvvGHM0AGphYO
+6f5qtHMUgvAblI8M/2QsBgethaGrirtKJ3aCRLdaR2R1QfaGRpck/Ron5/MpMxiJ
+wLT8YlW/zjx2yNABhPSAjfzeMw==
+-----END CERTIFICATE-----
diff --git a/tests/conftest.py b/tests/conftest.py index 3a895627..5048394c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,15 +1,18 @@ import os +import pytest #TODO: On my system this function seems to be returning an incorrect location -def pytest_funcarg__xmlsec(request): +@pytest.fixture +def xmlsec(request): for path in os.environ["PATH"].split(":"): fil = os.path.join(path, "xmlsec1") if os.access(fil,os.X_OK): return fil raise Exception("Can't find xmlsec1") - -def pytest_funcarg__AVA(request): + +@pytest.fixture +def AVA(request): return [ { "surName": ["Jeter"], @@ -27,4 +30,4 @@ def pytest_funcarg__AVA(request): "surName": ["Hedberg"], "givenName": ["Roland"], }, - ] + ] diff --git a/tests/server_conf.py b/tests/server_conf.py index aa34d8f7..4b528119 100644 --- a/tests/server_conf.py +++ b/tests/server_conf.py @@ -14,6 +14,19 @@ CONFIG = { "required_attributes": ["surName", "givenName", "mail"], "optional_attributes": ["title"], "idp": ["urn:mace:example.com:saml:roland:idp"], + "requested_attributes": [ + { + "name": "http://eidas.europa.eu/attributes/naturalperson/DateOfBirth", + "required": False, + }, + { + "friendly_name": "PersonIdentifier", + "required": True, + }, + { + "friendly_name": "PlaceOfBirth", + }, + ], } }, "debug": 1, diff --git a/tests/sp_conf_nameidpolicy.py b/tests/sp_conf_nameidpolicy.py new file mode 100644 index 00000000..d15989c2 --- /dev/null +++ b/tests/sp_conf_nameidpolicy.py @@ -0,0 +1,64 @@ +from pathutils import full_path +from pathutils import xmlsec_path + +CONFIG = { + "entityid": "urn:mace:example.com:saml:roland:sp", + "name": "urn:mace:example.com:saml:roland:sp", + "description": "My own SP", + "service": { + "sp": { + "endpoints": { + "assertion_consumer_service": [ + "http://lingon.catalogix.se:8087/"], + }, + "required_attributes": ["surName", "givenName", "mail"], + "optional_attributes": ["title"], + "idp": ["urn:mace:example.com:saml:roland:idp"], + "name_id_format": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "name_id_format_allow_create": "true" + } + }, + "debug": 1, + "key_file": full_path("test.key"), + "cert_file": full_path("test.pem"), + "encryption_keypairs": [{"key_file": full_path("test_1.key"), "cert_file": full_path("test_1.crt")}, + {"key_file": full_path("test_2.key"), "cert_file": full_path("test_2.crt")}], + "ca_certs": full_path("cacerts.txt"), + "xmlsec_binary": xmlsec_path, + "metadata": [{ + "class": "saml2.mdstore.MetaDataFile", + "metadata": [(full_path("idp.xml"), ), (full_path("vo_metadata.xml"), )], + }], + "virtual_organization": { + "urn:mace:example.com:it:tek": { + "nameid_format": "urn:oid:1.3.6.1.4.1.1466.115.121.1.15-NameID", + "common_identifier": "umuselin", + } + }, + "subject_data": "subject_data.db", + "accepted_time_diff": 60, + "attribute_map_dir": full_path("attributemaps"), + "valid_for": 6, + "organization": { + "name": ("AB Exempel", "se"), + "display_name": ("AB Exempel", "se"), + "url": "http://www.example.org", + }, + "contact_person": [{ + "given_name": "Roland", + "sur_name": "Hedberg", + "telephone_number": "+46 70 100 0000", + "email_address": ["tech@eample.com", + "tech@example.org"], + "contact_type": "technical" + }, + ], + "logger": { + "rotating": { + "filename": full_path("sp.log"), + "maxBytes": 100000, + "backupCount": 5, + }, + "loglevel": "info", + } +} diff --git a/tests/sp_mdext_conf.py b/tests/sp_mdext_conf.py index 67e33414..b1f0cf42 100644 --- a/tests/sp_mdext_conf.py +++ b/tests/sp_mdext_conf.py @@ -6,6 +6,8 @@ CONFIG = { "description": "My own SP", "service": { "sp": { + "sp_type": "public", + "sp_type_in_metadata": True, "endpoints": { "assertion_consumer_service": [ "http://lingon.catalogix.se:8087/"], diff --git a/tests/test_19_attribute_converter.py b/tests/test_19_attribute_converter.py index 0fa807b7..8662feee 100644 --- a/tests/test_19_attribute_converter.py +++ b/tests/test_19_attribute_converter.py @@ -10,6 +10,7 @@ from saml2.attribute_converter import AttributeConverter from saml2.attribute_converter import to_local from saml2.saml import attribute_from_string, name_id_from_string, NameID, NAMEID_FORMAT_PERSISTENT from saml2.saml import attribute_statement_from_string +import saml2.attributemaps.saml_uri as saml_map def _eq(l1, l2): @@ -139,12 +140,14 @@ class TestAC(): def test_to_local_name_from_unspecified(self): _xml = """<?xml version='1.0' encoding='UTF-8'?> <ns0:AttributeStatement xmlns:ns0="urn:oasis:names:tc:SAML:2.0:assertion"> -<ns0:Attribute - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - Name="EmailAddress" - NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"> - <ns0:AttributeValue xsi:type="xs:string">foo@bar.com</ns0:AttributeValue> -</ns0:Attribute></ns0:AttributeStatement>""" + <ns0:Attribute + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + Name="EmailAddress" + NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified"> + <ns0:AttributeValue xsi:type="xs:string">foo@bar.com</ns0:AttributeValue> + </ns0:Attribute> + </ns0:AttributeStatement> + """ attr = attribute_statement_from_string(_xml) ava = attribute_converter.to_local(self.acs, attr) @@ -236,26 +239,70 @@ def test_noop_attribute_conversion(): assert attr.attribute_value[0].text == "Roland" -ava = """<?xml version='1.0' encoding='UTF-8'?> -<ns0:Attribute xmlns:ns0="urn:oasis:names:tc:SAML:2.0:assertion" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - FriendlyName="schacHomeOrganization" Name="urn:oid:1.3.6.1.4.1.25178.1.2.9" - NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"> - <ns0:AttributeValue xsi:nil="true" xsi:type="xs:string"> - uu.se - </ns0:AttributeValue> -</ns0:Attribute>""" +class BuilderAVA(): + def __init__(self, name, friendly_name, name_format): + template = """<?xml version='1.0' encoding='UTF-8'?> + <ns0:Attribute xmlns:ns0="urn:oasis:names:tc:SAML:2.0:assertion" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + Name="{attr_name}" + FriendlyName="{attr_friendly_name}" + NameFormat="{attr_name_format}"> + <ns0:AttributeValue xsi:nil="true" xsi:type="xs:string"> + uu.se + </ns0:AttributeValue> + </ns0:Attribute> + """ + + self.ava = template.format( + attr_name=name, + attr_friendly_name=friendly_name, + attr_name_format=name_format) + + +class TestSchac(): + def test(self): + failures = 0 + friendly_name = "schacHomeOrganization" + ava_schac = BuilderAVA( + "urn:oid:1.3.6.1.4.1.25178.1.2.9", + friendly_name, + saml_map.MAP['identifier']) + + attr = attribute_from_string(ava_schac.ava) + acs = attribute_converter.ac_factory() + + for ac in acs: + try: + res = ac.ava_from(attr) + except KeyError: + failures += 1 + else: + assert res[0] == "schacHomeOrganization" + assert failures != len(acs) -def test_schac(): - attr = attribute_from_string(ava) - acs = attribute_converter.ac_factory() - for ac in acs: - try: - res = ac.ava_from(attr) - assert res[0] == "schacHomeOrganization" - except KeyError: - pass + +class TestEIDAS(): + def test(self): + failures = 0 + friendly_name = 'PersonIdentifier' + ava_eidas = BuilderAVA( + saml_map.EIDAS_NATURALPERSON + friendly_name, + friendly_name, + saml_map.MAP['identifier']) + + attr = attribute_from_string(ava_eidas.ava) + acs = attribute_converter.ac_factory() + + for ac in acs: + try: + res = ac.ava_from(attr) + except KeyError: + failures += 1 + else: + assert res[0] == friendly_name + + assert failures != len(acs) if __name__ == "__main__": diff --git a/tests/test_20_assertion.py b/tests/test_20_assertion.py index ae661d53..5fc36f6b 100644 --- a/tests/test_20_assertion.py +++ b/tests/test_20_assertion.py @@ -64,7 +64,7 @@ def test_filter_on_attributes_0(): required = [a] ava = {"serialNumber": ["12345"]} - ava = filter_on_attributes(ava, required) + ava = filter_on_attributes(ava, required, acs=ac_factory()) assert list(ava.keys()) == ["serialNumber"] assert ava["serialNumber"] == ["12345"] @@ -76,11 +76,23 @@ def test_filter_on_attributes_1(): required = [a] ava = {"serialNumber": ["12345"], "givenName": ["Lars"]} - ava = filter_on_attributes(ava, required) + ava = filter_on_attributes(ava, required, acs=ac_factory()) assert list(ava.keys()) == ["serialNumber"] assert ava["serialNumber"] == ["12345"] +def test_filter_on_attributes_2(): + + a = to_dict(Attribute(friendly_name="surName",name="urn:oid:2.5.4.4", + name_format=NAME_FORMAT_URI), ONTS) + required = [a] + ava = {"sn":["kakavas"]} + + ava = filter_on_attributes(ava,required,acs=ac_factory()) + assert list(ava.keys()) == ['sn'] + assert ava["sn"] == ["kakavas"] + + def test_filter_on_attributes_without_friendly_name(): ava = {"eduPersonTargetedID": "test@example.com", "eduPersonAffiliation": "test", @@ -106,7 +118,7 @@ def test_filter_on_attributes_with_missing_required_attribute(): name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10", name_format=NAME_FORMAT_URI), ONTS) with pytest.raises(MissingValue): - filter_on_attributes(ava, required=[eptid]) + filter_on_attributes(ava, required=[eptid], acs=ac_factory()) def test_filter_on_attributes_with_missing_optional_attribute(): @@ -115,7 +127,7 @@ def test_filter_on_attributes_with_missing_optional_attribute(): friendly_name="eduPersonTargetedID", name="urn:oid:1.3.6.1.4.1.5923.1.1.1.10", name_format=NAME_FORMAT_URI), ONTS) - assert filter_on_attributes(ava, optional=[eptid]) == {} + assert filter_on_attributes(ava, optional=[eptid], acs=ac_factory()) == {} # ---------------------------------------------------------------------- @@ -420,7 +432,7 @@ def test_filter_values_req_2(): required = [a1, a2] ava = {"serialNumber": ["12345"], "givenName": ["Lars"]} - raises(MissingValue, filter_on_attributes, ava, required) + raises(MissingValue, filter_on_attributes, ava, required, acs=ac_factory()) def test_filter_values_req_3(): @@ -432,7 +444,7 @@ def test_filter_values_req_3(): required = [a] ava = {"serialNumber": ["12345"]} - ava = filter_on_attributes(ava, required) + ava = filter_on_attributes(ava, required, acs=ac_factory()) assert list(ava.keys()) == ["serialNumber"] assert ava["serialNumber"] == ["12345"] @@ -446,7 +458,7 @@ def test_filter_values_req_4(): required = [a] ava = {"serialNumber": ["12345"]} - raises(MissingValue, filter_on_attributes, ava, required) + raises(MissingValue, filter_on_attributes, ava, required, acs=ac_factory()) def test_filter_values_req_5(): @@ -458,7 +470,7 @@ def test_filter_values_req_5(): required = [a] ava = {"serialNumber": ["12345", "54321"]} - ava = filter_on_attributes(ava, required) + ava = filter_on_attributes(ava, required, acs=ac_factory()) assert list(ava.keys()) == ["serialNumber"] assert ava["serialNumber"] == ["12345"] @@ -472,7 +484,7 @@ def test_filter_values_req_6(): required = [a] ava = {"serialNumber": ["12345", "54321"]} - ava = filter_on_attributes(ava, required) + ava = filter_on_attributes(ava, required, acs=ac_factory()) assert list(ava.keys()) == ["serialNumber"] assert ava["serialNumber"] == ["54321"] @@ -489,7 +501,7 @@ def test_filter_values_req_opt_0(): ava = {"serialNumber": ["12345", "54321"]} - ava = filter_on_attributes(ava, [r], [o]) + ava = filter_on_attributes(ava, [r], [o], acs=ac_factory()) assert list(ava.keys()) == ["serialNumber"] assert _eq(ava["serialNumber"], ["12345", "54321"]) @@ -507,7 +519,7 @@ def test_filter_values_req_opt_1(): ava = {"serialNumber": ["12345", "54321"]} - ava = filter_on_attributes(ava, [r], [o]) + ava = filter_on_attributes(ava, [r], [o], acs=ac_factory()) assert list(ava.keys()) == ["serialNumber"] assert _eq(ava["serialNumber"], ["12345", "54321"]) @@ -543,7 +555,7 @@ def test_filter_values_req_opt_2(): ava = {"surname": ["Hedberg"], "givenName": ["Roland"], "eduPersonAffiliation": ["staff"], "uid": ["rohe0002"]} - raises(MissingValue, "filter_on_attributes(ava, r, o)") + raises(MissingValue, "filter_on_attributes(ava, r, o, acs=ac_factory())") # --------------------------------------------------------------------------- @@ -923,3 +935,4 @@ def test_assertion_with_authn_instant(): if __name__ == "__main__": test_assertion_2() + diff --git a/tests/test_30_mdstore.py b/tests/test_30_mdstore.py index aadd7726..2a79c86a 100644 --- a/tests/test_30_mdstore.py +++ b/tests/test_30_mdstore.py @@ -7,12 +7,13 @@ from collections import OrderedDict from future.backports.urllib.parse import quote_plus from saml2.config import Config -from saml2.mdstore import MetadataStore +from saml2.mdstore import MetadataStore, MetaDataExtern from saml2.mdstore import MetaDataMDX from saml2.mdstore import SAML_METADATA_CONTENT_TYPE from saml2.mdstore import destinations from saml2.mdstore import name from saml2 import sigver +from saml2.httpbase import HTTPBase from saml2 import BINDING_SOAP from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_HTTP_POST @@ -385,6 +386,14 @@ def test_load_local(): assert cfg +def test_load_remote_encoding(): + crypto = sigver._get_xmlsec_cryptobackend() + sc = sigver.SecurityContext(crypto, key_type="", cert_type="") + httpc = HTTPBase() + mds = MetaDataExtern(ATTRCONV, 'http://metadata.aai.switch.ch/metadata.aaitest.xml', sc, full_path('SWITCHaaiRootCA.crt.pem'), httpc) + mds.load() + + def test_load_string(): sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"]) mds = MetadataStore(ATTRCONV, sec_config, diff --git a/tests/test_31_config.py b/tests/test_31_config.py index 623c944f..eb8480c6 100644 --- a/tests/test_31_config.py +++ b/tests/test_31_config.py @@ -68,6 +68,7 @@ sp2 = { }, "authn_requests_signed": True, "logout_requests_signed": True, + "force_authn": True, } }, #"xmlsec_binary" : "/opt/local/bin/xmlsec1", @@ -408,5 +409,15 @@ def test_crypto_backend(): sec = security_context(idpc) assert isinstance(sec.crypto, CryptoBackendXMLSecurity) +def test_unset_force_authn(): + cnf = SPConfig().load(sp1) + assert bool(cnf.getattr('force_authn', 'sp')) == False + + +def test_set_force_authn(): + cnf = SPConfig().load(sp2) + assert bool(cnf.getattr('force_authn', 'sp')) == True + + if __name__ == "__main__": test_crypto_backend() diff --git a/tests/test_50_server.py b/tests/test_50_server.py index 4aa834c5..f0dcae3c 100644 --- a/tests/test_50_server.py +++ b/tests/test_50_server.py @@ -96,7 +96,7 @@ class TestServer1(): self.client = client.Saml2Client(conf) self.name_id = self.server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") - self.ava = {"givenName": ["Derek"], "surName": ["Jeter"], + self.ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["derek@nyy.mlb.com"], "title": "The man"} def teardown_class(self): @@ -110,7 +110,7 @@ class TestServer1(): assert ava ==\ {'mail': ['derek@nyy.mlb.com'], 'givenName': ['Derek'], - 'surName': ['Jeter'], 'title': ['The man']} + 'sn': ['Jeter'], 'title': ['The man']} def verify_encrypted_assertion(self, assertion, decr_text): @@ -145,7 +145,7 @@ class TestServer1(): format=saml.NAMEID_FORMAT_TRANSIENT)), attribute_statement=do_attribute_statement( { - ("", "", "surName"): ("Jeter", ""), + ("", "", "sn"): ("Jeter", ""), ("", "", "givenName"): ("Derek", ""), } ), @@ -164,12 +164,12 @@ class TestServer1(): attr1 = attribute_statement.attribute[1] if attr0.attribute_value[0].text == "Derek": assert attr0.friendly_name == "givenName" - assert attr1.friendly_name == "surName" + assert attr1.friendly_name == "sn" assert attr1.attribute_value[0].text == "Jeter" else: assert attr1.friendly_name == "givenName" assert attr1.attribute_value[0].text == "Derek" - assert attr0.friendly_name == "surName" + assert attr0.friendly_name == "sn" assert attr0.attribute_value[0].text == "Jeter" # subject = assertion.subject @@ -187,7 +187,7 @@ class TestServer1(): name_id=saml.NAMEID_FORMAT_TRANSIENT), attribute_statement=do_attribute_statement( { - ("", "", "surName"): ("Jeter", ""), + ("", "", "sn"): ("Jeter", ""), ("", "", "givenName"): ("Derek", ""), } ), @@ -277,7 +277,7 @@ class TestServer1(): resp = self.server.create_authn_response( { "eduPersonEntitlement": "Short stop", - "surName": "Jeter", + "sn": "Jeter", "givenName": "Derek", "mail": "derek.jeter@nyy.mlb.com", "title": "The man" @@ -394,7 +394,7 @@ class TestServer1(): conf.load_file("server_conf") self.client = client.Saml2Client(conf) - ava = {"givenName": ["Derek"], "surName": ["Jeter"], + ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["derek@nyy.mlb.com"], "title": "The man"} npolicy = samlp.NameIDPolicy(format=saml.NAMEID_FORMAT_TRANSIENT, @@ -425,7 +425,7 @@ class TestServer1(): def test_signed_response(self): name_id = self.server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") - ava = {"givenName": ["Derek"], "surName": ["Jeter"], + ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["derek@nyy.mlb.com"], "title": "The man"} signed_resp = self.server.create_authn_response( @@ -1139,7 +1139,7 @@ class TestServer1(): "not_on_or_after": soon, "user": { "givenName": "Leo", - "surName": "Laport", + "sn": "Laport", } } self.client.users.add_information_about_person(sinfo) @@ -1163,7 +1163,7 @@ class TestServer1(): "not_on_or_after": soon, "user": { "givenName": "Leo", - "surName": "Laport", + "sn": "Laport", } } @@ -1188,7 +1188,7 @@ class TestServer1(): #------------------------------------------------------------------------ IDENTITY = {"eduPersonAffiliation": ["staff", "member"], - "surName": ["Jeter"], "givenName": ["Derek"], + "sn": ["Jeter"], "givenName": ["Derek"], "mail": ["foo@gmail.com"], "title": "The man"} @@ -1234,7 +1234,7 @@ def _logout_request(conf_file): "not_on_or_after": soon, "user": { "givenName": "Leo", - "surName": "Laport", + "sn": "Laport", } } sp.users.add_information_about_person(sinfo) diff --git a/tests/test_51_client.py b/tests/test_51_client.py index 13cef7cc..2bd4d7cf 100644 --- a/tests/test_51_client.py +++ b/tests/test_51_client.py @@ -22,6 +22,8 @@ from saml2 import samlp from saml2 import sigver from saml2 import s_utils from saml2.assertion import Assertion +from saml2.extension.requested_attributes import RequestedAttributes +from saml2.extension.requested_attributes import RequestedAttribute from saml2.authn_context import INTERNETPROTOCOLPASSWORD from saml2.client import Saml2Client @@ -280,6 +282,51 @@ class TestClient: assert nid_policy.allow_create == "false" assert nid_policy.format == saml.NAMEID_FORMAT_TRANSIENT + node_requested_attributes = None + for e in ar.extensions.extension_elements: + if e.tag == RequestedAttributes.c_tag: + node_requested_attributes = e + break + assert node_requested_attributes is not None + + for c in node_requested_attributes.children: + assert c.tag == RequestedAttribute.c_tag + assert c.attributes['isRequired'] in ['true', 'false'] + assert c.attributes['Name'] + assert c.attributes['FriendlyName'] + assert c.attributes['NameFormat'] + + def test_create_auth_request_unset_force_authn(self): + req_id, req = self.client.create_authn_request( + "http://www.example.com/sso", sign=False, message_id="id1") + assert bool(req.force_authn) == False + + def test_create_auth_request_set_force_authn(self): + req_id, req = self.client.create_authn_request( + "http://www.example.com/sso", sign=False, message_id="id1", + force_authn="true") + assert bool(req.force_authn) == True + + def test_create_auth_request_nameid_policy_allow_create(self): + conf = config.SPConfig() + conf.load_file("sp_conf_nameidpolicy") + client = Saml2Client(conf) + ar_str = "%s" % client.create_authn_request( + "http://www.example.com/sso", message_id="id1")[1] + + ar = samlp.authn_request_from_string(ar_str) + print(ar) + assert ar.assertion_consumer_service_url == ("http://lingon.catalogix" + ".se:8087/") + assert ar.destination == "http://www.example.com/sso" + assert ar.protocol_binding == BINDING_HTTP_POST + assert ar.version == "2.0" + assert ar.provider_name == "urn:mace:example.com:saml:roland:sp" + assert ar.issuer.text == "urn:mace:example.com:saml:roland:sp" + nid_policy = ar.name_id_policy + assert nid_policy.allow_create == "true" + assert nid_policy.format == saml.NAMEID_FORMAT_PERSISTENT + def test_create_auth_request_vo(self): assert list(self.client.config.vorg.keys()) == [ "urn:mace:example.com:it:tek"] @@ -346,7 +393,7 @@ class TestClient: def test_response_1(self): IDP = "urn:mace:example.com:saml:roland:idp" - ava = {"givenName": ["Derek"], "surName": ["Jeter"], + ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["derek@nyy.mlb.com"], "title": ["The man"]} nameid_policy = samlp.NameIDPolicy(allow_create="false", @@ -394,7 +441,7 @@ class TestClient: # --- authenticate another person - ava = {"givenName": ["Alfonson"], "surName": ["Soriano"], + ava = {"givenName": ["Alfonson"], "sn": ["Soriano"], "mail": ["alfonson@chc.mlb.com"], "title": ["outfielder"]} resp_str = "%s" % self.server.create_authn_response( @@ -712,7 +759,7 @@ class TestClient: def setup_verify_authn_response(self): idp = "urn:mace:example.com:saml:roland:idp" - ava = {"givenName": ["Derek"], "surName": ["Jeter"], + ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["derek@nyy.mlb.com"], "title": ["The man"]} ava_verify = {'mail': ['derek@nyy.mlb.com'], 'givenName': ['Derek'], 'sn': ['Jeter'], 'title': ["The man"]} @@ -761,7 +808,7 @@ class TestClient: format=saml.NAMEID_FORMAT_TRANSIENT)), attribute_statement=do_attribute_statement( { - ("", "", "surName"): ("Jeter", ""), + ("", "", "sn"): ("Jeter", ""), ("", "", "givenName"): ("Derek", ""), } ), @@ -825,7 +872,7 @@ class TestClient: nameid_policy = samlp.NameIDPolicy(allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) - asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) + asser = Assertion({"givenName": "Derek", "sn": "Jeter"}) farg = add_path( {}, ['assertion', 'subject', 'subject_confirmation', 'method', @@ -896,7 +943,7 @@ class TestClient: nameid_policy = samlp.NameIDPolicy(allow_create="false", format=saml.NAMEID_FORMAT_PERSISTENT) - asser = Assertion({"givenName": "Derek", "surName": "Jeter"}) + asser = Assertion({"givenName": "Derek", "sn": "Jeter"}) subject_confirmation_specs = { 'recipient': "http://lingon.catalogix.se:8087/", @@ -1027,7 +1074,7 @@ class TestClient: name_id=name_id, farg=farg['assertion']) - asser_2 = Assertion({"surName": "Jeter"}) + asser_2 = Assertion({"sn": "Jeter"}) assertion_2 = asser_2.construct( self.client.config.entityid, @@ -1313,7 +1360,7 @@ class TestClient: "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", - "surName": "Andersson", + "sn": "Andersson", "mail": "anders.andersson@example.com" } } @@ -1350,7 +1397,7 @@ class TestClient: "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", - "surName": "Andersson", + "sn": "Andersson", "mail": "anders.andersson@example.com" }, "session_index": SessionIndex("_foo") @@ -1367,7 +1414,7 @@ class TestClient: binding, info = resp[entity_ids[0]] assert binding == BINDING_HTTP_POST - _dic = unpack_form(info["data"][3]) + _dic = unpack_form(info["data"]) res = self.server.parse_logout_request(_dic["SAMLRequest"], BINDING_HTTP_POST) assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr @@ -1380,7 +1427,7 @@ class TestClient: "not_on_or_after": a_while_ago(minutes=15), "ava": { "givenName": "Anders", - "surName": "Andersson", + "sn": "Andersson", "mail": "anders.andersson@example.com" }, "session_index": SessionIndex("_foo") @@ -1397,7 +1444,7 @@ class TestClient: binding, info = resp[entity_ids[0]] assert binding == BINDING_HTTP_POST - _dic = unpack_form(info["data"][3]) + _dic = unpack_form(info["data"]) res = self.server.parse_logout_request(_dic["SAMLRequest"], BINDING_HTTP_POST) assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr @@ -1473,7 +1520,7 @@ class TestClientWithDummy(): "not_on_or_after": in_a_while(minutes=15), "ava": { "givenName": "Anders", - "surName": "Andersson", + "sn": "Andersson", "mail": "anders.andersson@example.com" } } @@ -1494,7 +1541,7 @@ class TestClientWithDummy(): sid, http_args = self.client.prepare_for_authenticate( "urn:mace:example.com:saml:roland:idp", relay_state="really", binding=binding, response_binding=response_binding) - _dic = unpack_form(http_args["data"][3]) + _dic = unpack_form(http_args["data"]) req = self.server.parse_authn_request(_dic["SAMLRequest"], binding) resp_args = self.server.response_args(req.message, [response_binding]) @@ -1512,7 +1559,7 @@ class TestClientWithDummy(): response = self.client.send(**http_args) print(response.text) - _dic = unpack_form(response.text[3], "SAMLResponse") + _dic = unpack_form(response.text, "SAMLResponse") resp = self.client.parse_authn_request_response(_dic["SAMLResponse"], BINDING_HTTP_POST, {sid: "/"}) @@ -1527,7 +1574,7 @@ class TestClientWithDummy(): sid, auth_binding, http_args = self.client.prepare_for_negotiated_authenticate( "urn:mace:example.com:saml:roland:idp", relay_state="really", binding=binding, response_binding=response_binding) - _dic = unpack_form(http_args["data"][3]) + _dic = unpack_form(http_args["data"]) assert binding == auth_binding @@ -1547,7 +1594,7 @@ class TestClientWithDummy(): response = self.client.send(**http_args) print(response.text) - _dic = unpack_form(response.text[3], "SAMLResponse") + _dic = unpack_form(response.text, "SAMLResponse") resp = self.client.parse_authn_request_response(_dic["SAMLResponse"], BINDING_HTTP_POST, {sid: "/"}) diff --git a/tests/test_65_authn_query.py b/tests/test_65_authn_query.py index 54d529f8..68af10a1 100644 --- a/tests/test_65_authn_query.py +++ b/tests/test_65_authn_query.py @@ -28,7 +28,7 @@ def get_msg(hinfo, binding): if binding == BINDING_SOAP: xmlstr = hinfo["data"] elif binding == BINDING_HTTP_POST: - _inp = hinfo["data"][3] + _inp = hinfo["data"] i = _inp.find(TAG1) i += len(TAG1) + 1 j = _inp.find('"', i) diff --git a/tests/test_68_assertion_id.py b/tests/test_68_assertion_id.py index 52959f3a..283b4da6 100644 --- a/tests/test_68_assertion_id.py +++ b/tests/test_68_assertion_id.py @@ -27,7 +27,7 @@ def get_msg(hinfo, binding, response=False): if binding == BINDING_SOAP: msg = hinfo["data"] elif binding == BINDING_HTTP_POST: - _inp = hinfo["data"][3] + _inp = hinfo["data"] i = _inp.find(TAG1) i += len(TAG1) + 1 j = _inp.find('"', i) diff --git a/tests/test_83_md_extensions.py b/tests/test_83_md_extensions.py index 71f98868..dace10a5 100644 --- a/tests/test_83_md_extensions.py +++ b/tests/test_83_md_extensions.py @@ -1,5 +1,6 @@ from saml2.config import Config from saml2.metadata import entity_descriptor +from saml2.extension.sp_type import SPType __author__ = 'roland' @@ -14,4 +15,13 @@ assert ed.spsso_descriptor.extensions assert len(ed.spsso_descriptor.extensions.extension_elements) == 3 assert ed.extensions -assert len(ed.extensions.extension_elements) > 1
\ No newline at end of file +assert len(ed.extensions.extension_elements) > 1 + +assert any(e.tag is SPType.c_tag for e in ed.extensions.extension_elements) + +cnf.setattr('sp', 'sp_type_in_metadata', False) +ed = entity_descriptor(cnf) + +print(ed) + +assert all(e.tag is not SPType.c_tag for e in ed.extensions.extension_elements) diff --git a/tests/test_requirements.txt b/tests/test_requirements.txt index 2c1ebbbc..33301079 100644 --- a/tests/test_requirements.txt +++ b/tests/test_requirements.txt @@ -2,3 +2,4 @@ mock==2.0.0 pymongo==3.0.1 pytest==3.0.3 responses==0.5.0 +pyasn1==0.2.3 |