diff options
-rw-r--r-- | src/saml2/attribute_converter.py | 44 | ||||
-rw-r--r-- | tests/test_19_attribute_converter.py | 23 |
2 files changed, 61 insertions, 6 deletions
diff --git a/src/saml2/attribute_converter.py b/src/saml2/attribute_converter.py index 4d411597..bc937702 100644 --- a/src/saml2/attribute_converter.py +++ b/src/saml2/attribute_converter.py @@ -432,12 +432,7 @@ class AttributeConverter(object): if name: if name == "urn:oid:1.3.6.1.4.1.5923.1.1.1.10": # special case for eduPersonTargetedID - attr_value = [] - for v in value: - extension_element = ExtensionElement("NameID", NAMESPACE, - attributes={'Format': NAMEID_FORMAT_PERSISTENT}, text=v) - attrval = saml.AttributeValue(extension_elements=[extension_element]) - attr_value.append(attrval) + attr_value = self.to_eptid_value(value) else: attr_value = do_ava(value) attributes.append(factory(saml.Attribute, @@ -452,6 +447,43 @@ class AttributeConverter(object): return attributes + def to_eptid_value(self, values): + """ + Create AttributeValue instances of NameID from the given values. + + Special handling for the "eptid" attribute + Name=urn:oid:1.3.6.1.4.1.5923.1.1.1.10 + FriendlyName=eduPersonTargetedID + + values is a list of items of type str or dict. When an item is a + dictionary it has the keys: "NameQualifier", "SPNameQualifier", and + "text". + + Returns a list of AttributeValue instances of NameID elements. + """ + + def _create_nameid_ext_el(value): + text = value["text"] if isinstance(value, dict) else value + attributes = ( + { + "Format": NAMEID_FORMAT_PERSISTENT, + "NameQualifier": value["NameQualifier"], + "SPNameQualifier": value["SPNameQualifier"], + } + if isinstance(value, dict) + else {"Format": NAMEID_FORMAT_PERSISTENT} + ) + element = ExtensionElement( + "NameID", NAMESPACE, attributes=attributes, text=text + ) + return element + + attribute_values = [ + saml.AttributeValue(extension_elements=[_create_nameid_ext_el(v)]) + for v in values + ] + return attribute_values + class AttributeConverterNOOP(AttributeConverter): """ Does a NOOP conversion, that is no conversion is made """ diff --git a/tests/test_19_attribute_converter.py b/tests/test_19_attribute_converter.py index 5f60f6d5..fdb9cd96 100644 --- a/tests/test_19_attribute_converter.py +++ b/tests/test_19_attribute_converter.py @@ -221,6 +221,29 @@ class TestAC(): assert attributes[0].attribute_value[0].extension_elements[0].text == "test value1" assert attributes[0].attribute_value[1].extension_elements[0].text == "test value2" + def test_from_local_eduPersonTargetedID_with_qualifiers(self): + IDP_ENTITY_ID = "https://some.org/idp" + SP_ENTITY_ID = "https://some.org/sp" + + ava = { + "edupersontargetedid": [ + { + "text": "test value1", + "NameQualifier": IDP_ENTITY_ID, + "SPNameQualifier": SP_ENTITY_ID, + } + ] + } + attributes = from_local(self.acs, ava, URI_NF) + + assert len(attributes) == 1 + + element = attributes[0].attribute_value[0].extension_elements[0] + + assert element.text == "test value1" + assert element.attributes["NameQualifier"] == IDP_ENTITY_ID + assert element.attributes["SPNameQualifier"] == SP_ENTITY_ID + def test_noop_attribute_conversion(): ava = {"urn:oid:2.5.4.4": "Roland", "urn:oid:2.5.4.42": "Hedberg"} |