Skip to content

Commit c6ddfa8

Browse files
committed
Add tests for eIDAS support
- Adds configs and test classes for eIDAS support
1 parent b1e8b65 commit c6ddfa8

File tree

4 files changed

+222
-0
lines changed

4 files changed

+222
-0
lines changed

tests/eidas/idp_conf.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from saml2 import BINDING_SOAP
2+
from saml2 import BINDING_HTTP_REDIRECT
3+
from saml2 import BINDING_HTTP_POST
4+
from saml2.saml import NAMEID_FORMAT_PERSISTENT, NAME_FORMAT_BASIC
5+
from saml2.saml import NAME_FORMAT_URI
6+
7+
from pathutils import full_path
8+
from pathutils import xmlsec_path
9+
10+
BASE = "http://localhost:8088"
11+
12+
CONFIG = {
13+
"entityid": "urn:mace:example.com:saml:roland:idp",
14+
"name": "Rolands IdP",
15+
"service": {
16+
"idp": {
17+
"endpoints": {
18+
"single_sign_on_service": [
19+
("%s/sso" % BASE, BINDING_HTTP_REDIRECT)],
20+
"single_logout_service": [
21+
("%s/slo" % BASE, BINDING_SOAP),
22+
("%s/slop" % BASE, BINDING_HTTP_POST)]
23+
},
24+
"policy": {
25+
"default": {
26+
"lifetime": {"minutes": 15},
27+
"attribute_restrictions": None, # means all I have
28+
"name_form": NAME_FORMAT_URI,
29+
},
30+
"urn:mace:example.com:saml:roland:sp": {
31+
"lifetime": {"minutes": 5},
32+
"nameid_format": NAMEID_FORMAT_PERSISTENT,
33+
},
34+
"https://example.com/sp": {
35+
"lifetime": {"minutes": 5},
36+
"nameid_format": NAMEID_FORMAT_PERSISTENT,
37+
"name_form": NAME_FORMAT_BASIC
38+
}
39+
},
40+
"subject_data": full_path("subject_data.db"),
41+
"node_country": "GR"
42+
},
43+
},
44+
"debug": 1,
45+
"key_file": full_path("test.key"),
46+
"cert_file": full_path("test.pem"),
47+
"xmlsec_binary": xmlsec_path,
48+
"metadata": [{
49+
"class": "saml2.mdstore.MetaDataFile",
50+
"metadata": [(full_path("metadata_sp_1.xml"), ),
51+
(full_path("metadata_sp_2.xml"), ),
52+
(full_path("vo_metadata.xml"), )],
53+
}],
54+
"attribute_map_dir": full_path("attributemaps"),
55+
"organization": {
56+
"name": "Exempel AB",
57+
"display_name": [("Exempel AB", "se"), ("Example Co.", "en")],
58+
"url": "http://www.example.com/roland",
59+
},
60+
"contact_person": [
61+
{
62+
"given_name": "John",
63+
"sur_name": "Smith",
64+
"email_address": ["[email protected]"],
65+
"contact_type": "technical",
66+
},
67+
],
68+
}

tests/eidas/sp_conf.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
from pathutils import full_path
2+
from pathutils import xmlsec_path
3+
4+
CONFIG = {
5+
"entityid": "urn:mace:example.com:saml:roland:sp",
6+
"name": "urn:mace:example.com:saml:roland:sp",
7+
"description": "My own SP",
8+
"service": {
9+
"sp": {
10+
"endpoints": {
11+
"assertion_consumer_service": [
12+
"http://lingon.catalogix.se:8087/"],
13+
},
14+
"required_attributes": ["surName", "givenName", "mail"],
15+
"optional_attributes": ["title"],
16+
"idp": ["urn:mace:example.com:saml:roland:idp"],
17+
"requested_attributes": [
18+
{
19+
"name": "http://eidas.europa.eu/attributes/naturalperson/DateOfBirth",
20+
"required": False,
21+
},
22+
{
23+
"friendly_name": "PersonIdentifier",
24+
"required": True,
25+
},
26+
{
27+
"friendly_name": "PlaceOfBirth",
28+
},
29+
],
30+
"sp_type": "public",
31+
"sp_type_in_metadata": False,
32+
"force_authn": True,
33+
"node_country": "GR"
34+
}
35+
},
36+
"debug": 1,
37+
"key_file": full_path("test.key"),
38+
"cert_file": full_path("test.pem"),
39+
"encryption_keypairs": [{"key_file": full_path("test_1.key"), "cert_file": full_path("test_1.crt")},
40+
{"key_file": full_path("test_2.key"), "cert_file": full_path("test_2.crt")}],
41+
"ca_certs": full_path("cacerts.txt"),
42+
"xmlsec_binary": xmlsec_path,
43+
"metadata": [{
44+
"class": "saml2.mdstore.MetaDataFile",
45+
"metadata": [(full_path("idp.xml"), ), (full_path("vo_metadata.xml"), )],
46+
}],
47+
"virtual_organization": {
48+
"urn:mace:example.com:it:tek": {
49+
"nameid_format": "urn:oid:1.3.6.1.4.1.1466.115.121.1.15-NameID",
50+
"common_identifier": "umuselin",
51+
}
52+
},
53+
"subject_data": "subject_data.db",
54+
"accepted_time_diff": 60,
55+
"attribute_map_dir": full_path("attributemaps"),
56+
"valid_for": 6,
57+
"organization": {
58+
"name": ("AB Exempel", "se"),
59+
"display_name": ("AB Exempel", "se"),
60+
"url": "http://www.example.org",
61+
},
62+
"contact_person": [{
63+
"given_name": "Roland",
64+
"sur_name": "Hedberg",
65+
"telephone_number": "+46 70 100 0000",
66+
"email_address": ["[email protected]",
67+
68+
"contact_type": "technical"
69+
},
70+
],
71+
"logger": {
72+
"rotating": {
73+
"filename": full_path("sp.log"),
74+
"maxBytes": 100000,
75+
"backupCount": 5,
76+
},
77+
"loglevel": "info",
78+
}
79+
}

tests/eidas/test_idp.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from saml2 import metadata
2+
from saml2.config import IdPConfig
3+
4+
5+
class TestIdP:
6+
def setup_class(self):
7+
self.conf = IdPConfig()
8+
self.conf.load_file("idp_conf")
9+
10+
def test_node_country_in_metadata(self):
11+
entd = metadata.entity_descriptor(self.conf)
12+
assert any(filter(lambda x: x.tag == "NodeCountry",
13+
entd.extensions.extension_elements))

tests/eidas/test_sp.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from saml2 import metadata
2+
from saml2 import samlp
3+
from saml2.client import Saml2Client
4+
from saml2.server import Server
5+
from saml2.config import SPConfig
6+
from eidas.sp_conf import CONFIG
7+
8+
9+
class TestSP:
10+
def setup_class(self):
11+
self.server = Server("idp_conf")
12+
13+
self.conf = SPConfig()
14+
self.conf.load_file("sp_conf")
15+
16+
self.client = Saml2Client(self.conf)
17+
18+
def teardown_class(self):
19+
self.server.close()
20+
21+
def test_authn_request_force_authn(self):
22+
req_str = "{0}".format(self.client.create_authn_request(
23+
"http://www.example.com/sso", message_id="id1")[-1])
24+
req = samlp.authn_request_from_string(req_str)
25+
assert req.force_authn == "true"
26+
27+
def test_sp_type_only_in_request(self):
28+
entd = metadata.entity_descriptor(self.conf)
29+
req_str = "{0}".format(self.client.create_authn_request(
30+
"http://www.example.com/sso", message_id="id1")[-1])
31+
req = samlp.authn_request_from_string(req_str)
32+
sp_type_elements = filter(lambda x: x.tag == "SPType",
33+
req.extensions.extension_elements)
34+
assert any(filter(lambda x: x.text == "public", sp_type_elements))
35+
assert not any(filter(lambda x: x.tag == "SPType",
36+
entd.extensions.extension_elements))
37+
38+
def test_sp_type_in_metadata(self):
39+
CONFIG["service"]["sp"]["sp_type_in_metadata"] = True
40+
sconf = SPConfig()
41+
sconf.load(CONFIG)
42+
custom_client = Saml2Client(sconf)
43+
44+
req_str = "{0}".format(custom_client.create_authn_request(
45+
"http://www.example.com/sso", message_id="id1")[-1])
46+
req = samlp.authn_request_from_string(req_str)
47+
sp_type_elements = filter(lambda x: x.tag == "SPType",
48+
req.extensions.extension_elements)
49+
assert not any(filter(lambda x: x.text == "public", sp_type_elements))
50+
51+
entd = metadata.entity_descriptor(sconf)
52+
assert any(filter(lambda x: x.tag == "SPType",
53+
entd.extensions.extension_elements))
54+
55+
def test_node_country_in_metadata(self):
56+
entd = metadata.entity_descriptor(self.conf)
57+
assert any(filter(lambda x: x.tag == "NodeCountry",
58+
entd.extensions.extension_elements))
59+
60+
61+
if __name__ == '__main__':
62+
TestSP()

0 commit comments

Comments
 (0)