2
2
Tests for the SAML frontend module src/frontends/saml2.py.
3
3
"""
4
4
import re
5
+ from collections import Counter
5
6
from urllib import parse
6
7
from urllib .parse import urlparse , parse_qs
7
8
8
9
import pytest
9
10
from saml2 import BINDING_HTTP_REDIRECT , BINDING_HTTP_POST
10
11
from saml2 .authn_context import PASSWORD
11
12
from saml2 .config import SPConfig
13
+ from saml2 .entity_category import refeds , swamid
14
+ from saml2 .entity_category .refeds import RESEARCH_AND_SCHOLARSHIP
15
+ from saml2 .entity_category .swamid import SFS_1993_1153 , RESEARCH_AND_EDUCATION , EU
12
16
from saml2 .saml import NAMEID_FORMAT_PERSISTENT , NAMEID_FORMAT_TRANSIENT
13
17
from saml2 .samlp import NameIDPolicy
14
18
@@ -58,7 +62,7 @@ def setup_for_authn_req(self, idp_conf, sp_conf, nameid_format):
58
62
context = Context ()
59
63
context .state = State ()
60
64
context .request = parse .parse_qs (
61
- urlparse (fakesp .make_auth_req (samlfrontend .idp_config ["entityid" ], nameid_format )).query )
65
+ urlparse (fakesp .make_auth_req (samlfrontend .idp_config ["entityid" ], nameid_format )).query )
62
66
tmp_dict = {}
63
67
for val in context .request :
64
68
if isinstance (context .request [val ], list ):
@@ -86,6 +90,7 @@ def test_register_endpoints(self, idp_conf):
86
90
"""
87
91
Tests the method register_endpoints
88
92
"""
93
+
89
94
def get_path_from_url (url ):
90
95
return urlparse (url ).path .lstrip ("/" )
91
96
@@ -96,7 +101,7 @@ def get_path_from_url(url):
96
101
"publish_metadata" : metadata_url }
97
102
98
103
samlfrontend = SamlFrontend (lambda context , internal_req : (context , internal_req ),
99
- INTERNAL_ATTRIBUTES , config )
104
+ INTERNAL_ATTRIBUTES , config )
100
105
101
106
providers = ["foo" , "bar" ]
102
107
url_map = samlfrontend .register_endpoints (providers )
@@ -188,12 +193,12 @@ def test_get_filter_attributes_with_sp_requested_attributes_without_friendlyname
188
193
"Example SP" )
189
194
filtered_attributes = samlfrontend .get_filter_attributes (samlfrontend .idp ,
190
195
samlfrontend .idp .config .getattr (
191
- "policy" , "idp" ),
196
+ "policy" , "idp" ),
192
197
internal_req .requestor , None )
193
198
194
199
assert set (filtered_attributes ) == set (
195
- ["edupersontargetedid" , "edupersonprincipalname" , "edupersonaffiliation" , "mail" ,
196
- "displayname" , "sn" , "givenname" ])
200
+ ["edupersontargetedid" , "edupersonprincipalname" , "edupersonaffiliation" , "mail" ,
201
+ "displayname" , "sn" , "givenname" ])
197
202
198
203
def test_acr_mapping_in_authn_response (self , idp_conf , sp_conf ):
199
204
eidas_loa_low = "http://eidas.europa.eu/LoA/low"
@@ -275,4 +280,49 @@ def test_acr_mapping_per_idp_in_authn_response(self, idp_conf, sp_conf):
275
280
assert len (resp .assertion .authn_statement ) == 1
276
281
authn_context_class_ref = resp .assertion .authn_statement [
277
282
0 ].authn_context .authn_context_class_ref
278
- assert authn_context_class_ref .text == expected_loa
283
+ assert authn_context_class_ref .text == expected_loa
284
+
285
+ @pytest .mark .parametrize ('entity_category, expected_attributes' , [
286
+ ([RESEARCH_AND_SCHOLARSHIP ], refeds .RELEASE [RESEARCH_AND_SCHOLARSHIP ]),
287
+ ([SFS_1993_1153 ], swamid .RELEASE [SFS_1993_1153 ]),
288
+ ([RESEARCH_AND_EDUCATION , EU ], swamid .RELEASE [(RESEARCH_AND_EDUCATION , EU )])
289
+ ])
290
+ def test_respect_sp_entity_categories (self , entity_category , expected_attributes , idp_conf , sp_conf ):
291
+ base = self .construct_base_url_from_entity_id (idp_conf ["entityid" ])
292
+ conf = {"idp_config" : idp_conf , "endpoints" : ENDPOINTS , "base" : base ,
293
+ "state_id" : "state_id" }
294
+
295
+ internal_attributes = {attr_name : {"saml" : [attr_name .lower ()]} for attr_name in expected_attributes }
296
+ samlfrontend = SamlFrontend (None , dict (attributes = internal_attributes ), conf )
297
+ samlfrontend .register_endpoints (["foo" ])
298
+
299
+ idp_metadata_str = create_metadata_from_config_dict (samlfrontend .idp_config )
300
+ sp_conf ["metadata" ]["inline" ].append (idp_metadata_str )
301
+ sp_conf ["entity_category" ] = entity_category
302
+ fakesp = FakeSP (None , config = SPConfig ().load (sp_conf , metadata_construction = False ))
303
+
304
+ auth_info = AuthenticationInformation (PASSWORD , "2015-09-30T12:21:37Z" , idp_conf ["entityid" ])
305
+ internal_response = InternalResponse (auth_info = auth_info )
306
+
307
+ user_attributes = {k : "foo" for k in expected_attributes }
308
+ user_attributes .update ({k : "bar" for k in ["extra" , "more" , "stuff" ]})
309
+ internal_response .add_attributes (user_attributes )
310
+ context = Context ()
311
+ context .state = State ()
312
+
313
+ resp_args = {
314
+ "name_id_policy" : NameIDPolicy (format = NAMEID_FORMAT_TRANSIENT ),
315
+ "in_response_to" : None ,
316
+ "destination" : "" ,
317
+ "sp_entity_id" : None ,
318
+ "binding" : BINDING_HTTP_REDIRECT
319
+ }
320
+ request_state = samlfrontend .save_state (context , resp_args , "" )
321
+ context .state .add (conf ["state_id" ], request_state )
322
+
323
+ resp = samlfrontend .handle_authn_response (context , internal_response )
324
+ resp_dict = parse_qs (urlparse (resp .message ).query )
325
+ resp = fakesp .parse_authn_request_response (resp_dict ['SAMLResponse' ][0 ],
326
+ BINDING_HTTP_REDIRECT )
327
+
328
+ assert Counter (resp .ava .keys ()) == Counter (expected_attributes )
0 commit comments