Projet

Général

Profil

0001-views-ignore-XML-content-in-SAML-attributes-43193.patch

Benjamin Dauvergne, 21 mai 2020 21:05

Télécharger (4,08 ko)

Voir les différences:

Subject: [PATCH] views: ignore XML content in SAML attributes (#43193)

 mellon/views.py       | 16 ++++++++++++----
 tests/test_sso_slo.py | 10 ++++++++--
 2 files changed, 20 insertions(+), 6 deletions(-)
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
-