utils: use iri_to_uri/uri_to_iri to manipulate URLs in make_url (fixes #28935)

This patch add non-ASCII characters to URLs in OIDC and CAS tests to
check make_url() works correctly.
This commit is contained in:
Benjamin Dauvergne 2018-12-12 16:31:55 +01:00
parent c5a273d026
commit 5095f90afc
4 changed files with 12 additions and 10 deletions

View File

@ -35,7 +35,7 @@ from django.utils.formats import localize
from django.contrib import messages
from django.utils.functional import empty
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from django.utils.encoding import iri_to_uri, force_bytes, uri_to_iri
from django.shortcuts import render
@ -269,8 +269,9 @@ def make_url(to, args=(), kwargs={}, keep_params=False, params=None, append=None
url = resolve_url(to, *args, **kwargs)
else:
url = to
url = iri_to_uri(url)
scheme, netloc, path, query_string, o_fragment = urlparse.urlsplit(url)
url = urlparse.urlunsplit((scheme, netloc, path, '', ''))
url = uri_to_iri(urlparse.urlunsplit((scheme, netloc, path, '', '')))
fragment = fragment or o_fragment
# Django < 1.6 compat, query_string is not optional
url_params = QueryDict(query_string=query_string, mutable=True)
@ -295,16 +296,16 @@ def make_url(to, args=(), kwargs={}, keep_params=False, params=None, append=None
else:
url_params.appendlist(key, value)
if url_params:
url += '?%s' % url_params.urlencode(safe='/')
url += u'?%s' % url_params.urlencode(safe='/')
if fragment:
url += '#%s' % fragment
url += u'#%s' % fragment
if absolute:
if request:
url = request.build_absolute_uri(url)
else:
raise TypeError('make_url() absolute cannot be used without request')
# URL must be ASCII, always
return url.encode('ascii')
# keep using unicode
return url
# improvement over django.shortcuts.redirect

View File

@ -28,7 +28,7 @@ class CasTests(Authentic2TestCase):
LAST_NAME = 'Doe'
NAME = 'CAS service'
SLUG = 'cas-service'
URL = 'https://casclient.com/'
URL = 'https://casclient.com/%C3%A9/'
NAME2 = 'CAS service2'
SLUG2 = 'cas-service2'
URL2 = 'https://casclient2.com/ https://other.com/'

View File

@ -117,7 +117,7 @@ def oidc_client(request, superuser, app, simple_user, media):
response.form.set('slug', 'oidcclient')
response.form.set('ou', get_default_ou().pk)
response.form.set('unauthorized_url', 'https://example.com/southpark/')
response.form.set('redirect_uris', 'https://example.com/callback')
response.form.set('redirect_uris', 'https://example.com/callbac%C3%A9')
for key, value in request.param.iteritems():
response.form.set(key, value)
response = response.form.submit().follow()
@ -397,7 +397,7 @@ def test_invalid_request(caplog, oidc_settings, oidc_client, simple_user, app):
fragment=fragment)
logrecord = [rec for rec in caplog.records if rec.funcName == 'authorization_error'][0]
assert logrecord.levelname == 'WARNING'
assert logrecord.redirect_uri == 'https://example.com/callback'
assert logrecord.redirect_uri == 'https://example.com/callbac%C3%A9'
assert 'missing parameter \'response_type\'' in logrecord.message
# missing scope

View File

@ -8,6 +8,7 @@ import pytest
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.conf import settings
from django.utils.encoding import iri_to_uri
from authentic2 import utils
@ -70,7 +71,7 @@ class Authentic2TestCase(TestCase):
value.
'''
splitted1 = urlparse.urlsplit(url1)
url2 = utils.make_url(url2, params=kwargs)
url2 = iri_to_uri(utils.make_url(url2, params=kwargs))
splitted2 = urlparse.urlsplit(url2)
for i, (elt1, elt2) in enumerate(zip(splitted1, splitted2)):
if i == 3: