views: ignore XML content in SAML attributes (#43193)
This commit is contained in:
parent
92703b3105
commit
c05f4a3129
|
@ -209,16 +209,24 @@ class LoginView(ProfileMixin, LogMixin, View):
|
|||
'error_redirect_after_timeout': error_redirect_after_timeout,
|
||||
})
|
||||
|
||||
def get_attribute_value(self, attribute, attribute_value):
|
||||
# check attribute_value contains only text
|
||||
for node in attribute_value.any:
|
||||
if not isinstance(node, lasso.MiscTextNode) or not node.textChild:
|
||||
self.log.warning('unsupported attribute %s', attribute.exportToXml())
|
||||
return None
|
||||
return ''.join(lasso_decode(node.content) for node in attribute_value.any)
|
||||
|
||||
def sso_success(self, request, login):
|
||||
attributes = {}
|
||||
attribute_statements = login.assertion.attributeStatement
|
||||
for ats in attribute_statements:
|
||||
for at in ats.attribute:
|
||||
values = attributes.setdefault(at.name, [])
|
||||
for value in at.attributeValue:
|
||||
contents = [lasso_decode(any.exportToXml()) for any in value.any]
|
||||
content = ''.join(contents)
|
||||
values.append(content)
|
||||
for attribute_value in at.attributeValue:
|
||||
content = self.get_attribute_value(at, attribute_value)
|
||||
if content is not None:
|
||||
values.append(content)
|
||||
attributes['issuer'] = login.remoteProviderId
|
||||
if login.nameIdentifier:
|
||||
name_id = login.nameIdentifier
|
||||
|
|
|
@ -32,6 +32,7 @@ from django.utils.six.moves.urllib import parse as urlparse
|
|||
from django.utils.encoding import force_str
|
||||
|
||||
from mellon.utils import create_metadata
|
||||
from mellon.views import lasso_decode
|
||||
|
||||
from httmock import all_requests, HTTMock, response as mock_response
|
||||
|
||||
|
@ -121,6 +122,7 @@ class MockIdp(object):
|
|||
break
|
||||
else:
|
||||
attribute = lasso.Saml2Attribute()
|
||||
attribute.name = name
|
||||
attributes.append(attribute)
|
||||
statement.attribute = attributes
|
||||
attribute_values = list(attribute.attributeValue)
|
||||
|
@ -138,6 +140,7 @@ class MockIdp(object):
|
|||
atv.any = value_any
|
||||
add_attribute('email', 'john', '.doe@gmail.com')
|
||||
add_attribute('wtf', 'john', lasso.MiscTextNode.newWithXmlNode('<a>coucou</a>'))
|
||||
add_attribute('first_name', '<i>Fr\xe9d\xe9ric</i>')
|
||||
|
||||
if not auth_result and msg:
|
||||
login.response.status.statusMessage = msg
|
||||
|
@ -164,8 +167,8 @@ class MockIdp(object):
|
|||
del self.artifact
|
||||
del self.artifact_message
|
||||
login.buildResponseMsg()
|
||||
assert 'rsa-sha256' in login.msgBody
|
||||
return '<?xml version="1.0"?>\n' + login.msgBody
|
||||
assert 'rsa-sha256' in lasso_decode(login.msgBody)
|
||||
return '<?xml version="1.0"?>\n' + lasso_decode(login.msgBody)
|
||||
|
||||
def mock_artifact_resolver(self):
|
||||
@all_requests
|
||||
|
@ -204,6 +207,9 @@ def test_sso(db, app, idp, caplog, sp_settings):
|
|||
assert 'created new user' in caplog.text
|
||||
assert 'logged in using SAML' in caplog.text
|
||||
assert urlparse.urlparse(response['Location']).path == sp_settings.LOGIN_REDIRECT_URL
|
||||
assert app.session['mellon_session']['first_name'] == ['<i>Fr\xe9d\xe9ric</i>']
|
||||
assert app.session['mellon_session']['email'] == ['john.doe@gmail.com']
|
||||
assert app.session['mellon_session']['wtf'] == []
|
||||
|
||||
|
||||
def test_sso_request_denied(db, app, idp, caplog, sp_settings):
|
||||
|
|
Loading…
Reference in New Issue