0001-views-ignore-XML-content-in-SAML-attributes-43193.patch
mellon/views.py | ||
---|---|---|
209 | 209 |
'error_redirect_after_timeout': error_redirect_after_timeout, |
210 | 210 |
}) |
211 | 211 | |
212 |
def get_attribute_value(self, attribute, attribute_value): |
|
213 |
# check attribute_value contains only text |
|
214 |
for node in attribute_value.any: |
|
215 |
if not isinstance(node, lasso.MiscTextNode) or not node.textChild: |
|
216 |
self.log.warning('unsupported attribute %s', attribute.exportToXml()) |
|
217 |
return None |
|
218 |
return ''.join(lasso_decode(node.content) for node in attribute_value.any) |
|
219 | ||
212 | 220 |
def sso_success(self, request, login): |
213 | 221 |
attributes = {} |
214 | 222 |
attribute_statements = login.assertion.attributeStatement |
215 | 223 |
for ats in attribute_statements: |
216 | 224 |
for at in ats.attribute: |
217 | 225 |
values = attributes.setdefault(at.name, []) |
218 |
for value in at.attributeValue: |
|
219 |
contents = [lasso_decode(any.exportToXml()) for any in value.any]
|
|
220 |
content = ''.join(contents)
|
|
221 |
values.append(content) |
|
226 |
for attribute_value in at.attributeValue:
|
|
227 |
content = self.get_attribute_value(at, attribute_value)
|
|
228 |
if content is not None:
|
|
229 |
values.append(content)
|
|
222 | 230 |
attributes['issuer'] = login.remoteProviderId |
223 | 231 |
if login.nameIdentifier: |
224 | 232 |
name_id = login.nameIdentifier |
tests/test_sso_slo.py | ||
---|---|---|
32 | 32 |
from django.utils.encoding import force_str |
33 | 33 | |
34 | 34 |
from mellon.utils import create_metadata |
35 |
from mellon.views import lasso_decode |
|
35 | 36 | |
36 | 37 |
from httmock import all_requests, HTTMock, response as mock_response |
37 | 38 | |
... | ... | |
121 | 122 |
break |
122 | 123 |
else: |
123 | 124 |
attribute = lasso.Saml2Attribute() |
125 |
attribute.name = name |
|
124 | 126 |
attributes.append(attribute) |
125 | 127 |
statement.attribute = attributes |
126 | 128 |
attribute_values = list(attribute.attributeValue) |
... | ... | |
138 | 140 |
atv.any = value_any |
139 | 141 |
add_attribute('email', 'john', '.doe@gmail.com') |
140 | 142 |
add_attribute('wtf', 'john', lasso.MiscTextNode.newWithXmlNode('<a>coucou</a>')) |
143 |
add_attribute('first_name', '<i>Fr\xe9d\xe9ric</i>') |
|
141 | 144 | |
142 | 145 |
if not auth_result and msg: |
143 | 146 |
login.response.status.statusMessage = msg |
... | ... | |
164 | 167 |
del self.artifact |
165 | 168 |
del self.artifact_message |
166 | 169 |
login.buildResponseMsg() |
167 |
assert 'rsa-sha256' in login.msgBody
|
|
168 |
return '<?xml version="1.0"?>\n' + login.msgBody
|
|
170 |
assert 'rsa-sha256' in lasso_decode(login.msgBody)
|
|
171 |
return '<?xml version="1.0"?>\n' + lasso_decode(login.msgBody)
|
|
169 | 172 | |
170 | 173 |
def mock_artifact_resolver(self): |
171 | 174 |
@all_requests |
... | ... | |
204 | 207 |
assert 'created new user' in caplog.text |
205 | 208 |
assert 'logged in using SAML' in caplog.text |
206 | 209 |
assert urlparse.urlparse(response['Location']).path == sp_settings.LOGIN_REDIRECT_URL |
210 |
assert app.session['mellon_session']['first_name'] == ['<i>Fr\xe9d\xe9ric</i>'] |
|
211 |
assert app.session['mellon_session']['email'] == ['john.doe@gmail.com'] |
|
212 |
assert app.session['mellon_session']['wtf'] == [] |
|
207 | 213 | |
208 | 214 | |
209 | 215 |
def test_sso_request_denied(db, app, idp, caplog, sp_settings): |
210 |
- |