@@ -200,14 +200,15 @@ def all_locations(srvs):
200
200
return values
201
201
202
202
203
- def attribute_requirement (entity , index = None ):
203
+ def attribute_requirement (entity_descriptor , index = None ):
204
204
res = {"required" : [], "optional" : []}
205
- for acs in entity ["attribute_consuming_service" ]:
205
+ acss = entity_descriptor .get ("attribute_consuming_service" ) or []
206
+ for acs in acss :
206
207
if index is not None and acs ["index" ] != index :
207
208
continue
208
209
209
210
for attr in acs ["requested_attribute" ]:
210
- if "is_required" in attr and attr [ "is_required" ] == "true" :
211
+ if attr . get ( "is_required" ) == "true" :
211
212
res ["required" ].append (attr )
212
213
else :
213
214
res ["optional" ].append (attr )
@@ -676,24 +677,26 @@ def service(self, entity_id, typ, service, binding=None):
676
677
return res
677
678
678
679
def attribute_requirement (self , entity_id , index = None ):
679
- """Returns what attributes the SP requires and which are optional
680
+ """
681
+ Returns what attributes the SP requires and which are optional
680
682
if any such demands are registered in the Metadata.
681
683
684
+ In case the metadata have multiple SPSSODescriptor elements,
685
+ the sum of the required and optional attributes is returned.
686
+
682
687
:param entity_id: The entity id of the SP
683
688
:param index: which of the attribute consumer services its all about
684
689
if index=None then return all attributes expected by all
685
690
attribute_consuming_services.
686
- :return: 2-tuple, list of required and list of optional attributes
691
+ :return: dict of required and optional list of attributes
687
692
"""
688
693
res = {"required" : [], "optional" : []}
689
694
690
- try :
691
- for sp in self [entity_id ]["spsso_descriptor" ]:
692
- _res = attribute_requirement (sp , index )
693
- res ["required" ].extend (_res ["required" ])
694
- res ["optional" ].extend (_res ["optional" ])
695
- except KeyError :
696
- return None
695
+ sp_descriptors = self [entity_id ].get ("spsso_descriptor" ) or []
696
+ for sp_desc in sp_descriptors :
697
+ _res = attribute_requirement (sp_desc , index )
698
+ res ["required" ].extend (_res .get ("required" ) or [])
699
+ res ["optional" ].extend (_res .get ("optional" ) or [])
697
700
698
701
return res
699
702
@@ -1297,35 +1300,56 @@ def discovery_response(self, entity_id, binding=None, _="spsso"):
1297
1300
)
1298
1301
1299
1302
def attribute_requirement (self , entity_id , index = None ):
1300
- for _md in self .metadata .values ():
1301
- if entity_id in _md :
1302
- return _md .attribute_requirement (entity_id , index )
1303
+ for md_source in self .metadata .values ():
1304
+ if entity_id in md_source :
1305
+ return md_source .attribute_requirement (entity_id , index )
1303
1306
1304
1307
def subject_id_requirement (self , entity_id ):
1305
1308
try :
1306
1309
entity_attributes = self .entity_attributes (entity_id )
1307
1310
except KeyError :
1308
- return None
1311
+ return []
1309
1312
1310
- if "urn:oasis:names:tc:SAML:profiles:subject-id:req" in entity_attributes :
1311
- subject_id_req = entity_attributes ["urn:oasis:names:tc:SAML:profiles:subject-id:req" ][0 ]
1312
- if subject_id_req == "any" or subject_id_req == "pairwise-id" :
1313
- return {
1313
+ subject_id_reqs = entity_attributes .get ("urn:oasis:names:tc:SAML:profiles:subject-id:req" ) or []
1314
+ subject_id_req = next (iter (subject_id_reqs ), None )
1315
+ if subject_id_req == "any" :
1316
+ return [
1317
+ {
1318
+ "__class__" : "urn:oasis:names:tc:SAML:2.0:metadata&RequestedAttribute" ,
1319
+ "name" : "urn:oasis:names:tc:SAML:attribute:pairwise-id" ,
1320
+ "name_format" : "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" ,
1321
+ "friendly_name" : "pairwise-id" ,
1322
+ "is_required" : "true" ,
1323
+ },
1324
+ {
1325
+ "__class__" : "urn:oasis:names:tc:SAML:2.0:metadata&RequestedAttribute" ,
1326
+ "name" : "urn:oasis:names:tc:SAML:attribute:subject-id" ,
1327
+ "name_format" : "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" ,
1328
+ "friendly_name" : "subject-id" ,
1329
+ "is_required" : "true" ,
1330
+ }
1331
+ ]
1332
+ elif subject_id_req == "pairwise-id" :
1333
+ return [
1334
+ {
1314
1335
"__class__" : "urn:oasis:names:tc:SAML:2.0:metadata&RequestedAttribute" ,
1315
1336
"name" : "urn:oasis:names:tc:SAML:attribute:pairwise-id" ,
1316
1337
"name_format" : "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" ,
1317
1338
"friendly_name" : "pairwise-id" ,
1318
1339
"is_required" : "true" ,
1319
1340
}
1320
- elif subject_id_req == "subject-id" :
1321
- return {
1341
+ ]
1342
+ elif subject_id_req == "subject-id" :
1343
+ return [
1344
+ {
1322
1345
"__class__" : "urn:oasis:names:tc:SAML:2.0:metadata&RequestedAttribute" ,
1323
1346
"name" : "urn:oasis:names:tc:SAML:attribute:subject-id" ,
1324
1347
"name_format" : "urn:oasis:names:tc:SAML:2.0:attrname-format:uri" ,
1325
1348
"friendly_name" : "subject-id" ,
1326
1349
"is_required" : "true" ,
1327
1350
}
1328
- return None
1351
+ ]
1352
+ return []
1329
1353
1330
1354
def keys (self ):
1331
1355
res = []
0 commit comments