Skip to content

Commit 7dfdcf4

Browse files
committed
Support multiple attributeValues on RequestedAttribute
1 parent fdb40e2 commit 7dfdcf4

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ This is the settings.json file:
228228
"isRequired": false,
229229
"nameFormat": "",
230230
"friendlyName": "",
231-
"attributeValue": ""
231+
"attributeValue": []
232232
}
233233
]
234234
},

src/onelogin/saml2/metadata.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ def builder(sp, authnsign=False, wsign=False, valid_until=None, cache_duration=N
120120
str_contacts = '\n'.join(contacts_info)
121121

122122
str_attribute_consuming_service = ''
123-
124123
if 'attributeConsumingService' in sp and len(sp['attributeConsumingService']):
125124
attr_cs_desc_str = ''
126125
if "serviceDescription" in sp['attributeConsumingService']:
127-
attr_cs_desc_str = """ <md:ServiceDescription xml:lang="en">%s</md:ServiceDescription>\n""" % sp['attributeConsumingService']['serviceDescription']
126+
attr_cs_desc_str = """ <md:ServiceDescription xml:lang="en">%s</md:ServiceDescription>
127+
""" % sp['attributeConsumingService']['serviceDescription']
128128

129129
requested_attribute_data = []
130130
for req_attribs in sp['attributeConsumingService']['requestedAttributes']:
@@ -136,26 +136,37 @@ def builder(sp, authnsign=False, wsign=False, valid_until=None, cache_duration=N
136136
if 'friendlyName' in req_attribs.keys() and req_attribs['friendlyName']:
137137
req_attr_nameformat_str = " FriendlyName=\"%s\"" % req_attribs['friendlyName']
138138
if 'isRequired' in req_attribs.keys() and req_attribs['isRequired']:
139-
req_attr_isrequired_str = " isRequired=\"%s\"" % 'true' if req_attribs['isRequired'] else 'false'
139+
req_attr_isrequired_str = " isRequired=\"%s\"" % req_attribs['isRequired']
140+
140141
if 'attributeValue' in req_attribs.keys() and req_attribs['attributeValue']:
141-
req_attr_aux_str = """ >
142-
<saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion>%(attributeValue)</saml:AttributeValue>
143-
</md:RequestedAttribute>""" % \
144-
{
145-
'attributeValue': req_attribs['attributeValue']
146-
}
147-
148-
requested_attribute = OneLogin_Saml2_Templates.MD_REQUESTED_ATTRIBUTE % \
142+
req_attr_aux_str = ""
143+
if isinstance(req_attribs['attributeValue'], basestring):
144+
req_attribs['attributeValue'] = [req_attribs['attributeValue']]
145+
for attrValue in req_attribs['attributeValue']:
146+
req_attr_aux_str += """
147+
<saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion>%(attributeValue)s</saml:AttributeValue>""" % \
148+
{
149+
'attributeValue': attrValue
150+
}
151+
req_attr_aux_str += """
152+
</md:RequestedAttribute>"""
153+
154+
requested_attribute = """ <md:RequestedAttribute Name="%(req_attr_name)s"%(req_attr_nameformat_str)s%(req_attr_friendlyname_str)s%(req_attr_isrequired_str)s%(req_attr_aux_str)s""" % \
149155
{
150156
'req_attr_name': req_attribs['name'],
151157
'req_attr_nameformat_str': req_attr_nameformat_str,
152158
'req_attr_friendlyname_str': req_attr_friendlyname_str,
153159
'req_attr_isrequired_str': req_attr_isrequired_str,
154160
'req_attr_aux_str': req_attr_aux_str
155161
}
162+
156163
requested_attribute_data.append(requested_attribute)
157164

158-
str_attribute_consuming_service = OneLogin_Saml2_Templates.MD_ATTR_CONSUMER_SERVICE % \
165+
str_attribute_consuming_service = """ <md:AttributeConsumingService index="1">
166+
<md:ServiceName xml:lang="en">%(service_name)s</md:ServiceName>
167+
%(attr_cs_desc)s%(requested_attribute_str)s
168+
</md:AttributeConsumingService>
169+
""" % \
159170
{
160171
'service_name': sp['attributeConsumingService']['serviceName'],
161172
'attr_cs_desc': attr_cs_desc_str,

tests/src/OneLogin/saml2_tests/metadata_test.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,28 @@ def testBuilderAttributeConsumingService(self):
161161
<md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.1" FriendlyName="uid" />
162162
</md:AttributeConsumingService>""", metadata)
163163

164+
def testBuilderAttributeConsumingServiceWithMultipleAttributeValue(self):
165+
settings = OneLogin_Saml2_Settings(self.loadSettingsJSON('settings5.json'))
166+
sp_data = settings.get_sp_data()
167+
security = settings.get_security_data()
168+
organization = settings.get_organization()
169+
contacts = settings.get_contacts()
170+
171+
metadata = OneLogin_Saml2_Metadata.builder(
172+
sp_data, security['authnRequestsSigned'],
173+
security['wantAssertionsSigned'], None, None, contacts,
174+
organization
175+
)
176+
self.assertIn(""" <md:AttributeConsumingService index="1">
177+
<md:ServiceName xml:lang="en">Test Service</md:ServiceName>
178+
<md:ServiceDescription xml:lang="en">Test Service</md:ServiceDescription>
179+
<md:RequestedAttribute Name="userType" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
180+
<saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion>userType</saml:AttributeValue>
181+
<saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion>admin</saml:AttributeValue>
182+
</md:RequestedAttribute>
183+
<md:RequestedAttribute Name="urn:oid:0.9.2342.19200300.100.1.1" FriendlyName="uid" />
184+
</md:AttributeConsumingService>""", metadata)
185+
164186
def testSignMetadata(self):
165187
"""
166188
Tests the signMetadata method of the OneLogin_Saml2_Metadata

0 commit comments

Comments
 (0)