Skip to content

Commit 634644e

Browse files
committed
Enable NameQualifier and SPNameQualifier attributes for ePTID
The attribute value for eduPersonTargetedID (ePTID) is a NameID element. The SAML specification allows the NameID element to include the two optional attributes 'NameQualifier' and 'SPNameQualifier'. This patch enables specifying a dictionary as the internal or local attribute value instead of a string. When the local attribute value is a dictionary with keys 'value', 'NameQualifier', and 'SPNameQualifier' then the resulting XML NameID element will include the 'NameQualifier' and 'SPNameQualifier' attributes with values taken from the values of the dictionary. The value for the NameID element is taken from the value associated with tthe 'value' key.
1 parent 1cc23fd commit 634644e

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

src/saml2/attribute_converter.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,12 +432,7 @@ def to_(self, attrvals):
432432
if name:
433433
if name == "urn:oid:1.3.6.1.4.1.5923.1.1.1.10":
434434
# special case for eduPersonTargetedID
435-
attr_value = []
436-
for v in value:
437-
extension_element = ExtensionElement("NameID", NAMESPACE,
438-
attributes={'Format': NAMEID_FORMAT_PERSISTENT}, text=v)
439-
attrval = saml.AttributeValue(extension_elements=[extension_element])
440-
attr_value.append(attrval)
435+
attr_value = self.to_eptid_value(value)
441436
else:
442437
attr_value = do_ava(value)
443438
attributes.append(factory(saml.Attribute,
@@ -452,6 +447,41 @@ def to_(self, attrvals):
452447

453448
return attributes
454449

450+
def to_eptid_value(self, value):
451+
"""
452+
Special handling for the attribute with name
453+
urn:oid:1.3.6.1.4.1.5923.1.1.1.10, usually known by the friendly
454+
name eduPersonTargetedID. Create the AttributeValue instance(s)
455+
for the attribute.
456+
457+
value is either a string or a dictionary with keys 'value',
458+
'NameQualifier', and 'SPNameQualifier'.
459+
460+
Returns a list of AttributeValue instances.
461+
"""
462+
attribute_values = []
463+
464+
for v in value:
465+
if isinstance(v, dict):
466+
element_attributes = {
467+
'Format': NAMEID_FORMAT_PERSISTENT,
468+
'NameQualifier': v['NameQualifier'],
469+
'SPNameQualifier': v['SPNameQualifier']
470+
}
471+
text = v['value']
472+
else:
473+
element_attributes = {'Format': NAMEID_FORMAT_PERSISTENT}
474+
text = v
475+
476+
element = ExtensionElement("NameID", NAMESPACE, element_attributes,
477+
text=text)
478+
479+
attrval = saml.AttributeValue(extension_elements=[element])
480+
481+
attribute_values.append(attrval)
482+
483+
return attribute_values
484+
455485

456486
class AttributeConverterNOOP(AttributeConverter):
457487
""" Does a NOOP conversion, that is no conversion is made """

tests/test_19_attribute_converter.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,24 @@ def test_from_local_nest_eduPersonTargetedID_in_NameID(self):
221221
assert attributes[0].attribute_value[0].extension_elements[0].text == "test value1"
222222
assert attributes[0].attribute_value[1].extension_elements[0].text == "test value2"
223223

224+
def test_from_local_eduPersonTargetedID_with_qualifiers(self):
225+
IDP_ENTITY_ID = 'https://some.org/idp'
226+
SP_ENTITY_ID = 'https://some.org/sp'
227+
228+
ava = {"edupersontargetedid": [{
229+
'value': "test value1",
230+
'NameQualifier': IDP_ENTITY_ID,
231+
'SPNameQualifier': SP_ENTITY_ID}]}
232+
attributes = from_local(self.acs, ava, URI_NF)
233+
234+
assert len(attributes) == 1
235+
236+
element = attributes[0].attribute_value[0].extension_elements[0]
237+
238+
assert element.text == "test value1"
239+
assert element.attributes['NameQualifier'] == IDP_ENTITY_ID
240+
assert element.attributes['SPNameQualifier'] == SP_ENTITY_ID
241+
224242

225243
def test_noop_attribute_conversion():
226244
ava = {"urn:oid:2.5.4.4": "Roland", "urn:oid:2.5.4.42": "Hedberg"}

0 commit comments

Comments
 (0)