Fix unicode sandwich issue in cas_server.utils.update_url. Fix #82
This commit is contained in:
parent
6212ba5f2a
commit
a82d348b20
3 changed files with 35 additions and 16 deletions
|
@ -13,6 +13,10 @@ Added
|
||||||
-----
|
-----
|
||||||
* Support for Django 4.0 and 4.1
|
* Support for Django 4.0 and 4.1
|
||||||
|
|
||||||
|
Fixes
|
||||||
|
-----
|
||||||
|
* Fix unicode sandwich issue in cas_server.utils.update_url
|
||||||
|
|
||||||
Removed
|
Removed
|
||||||
-------
|
-------
|
||||||
* Drop support for Django 1.11 (now deprecated for more than 2 years)
|
* Drop support for Django 1.11 (now deprecated for more than 2 years)
|
||||||
|
|
|
@ -262,7 +262,7 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
|
||||||
# check that the service pattern registered on the ticket is the on we use for tests
|
# check that the service pattern registered on the ticket is the on we use for tests
|
||||||
self.assertEqual(ticket.service_pattern, self.service_pattern)
|
self.assertEqual(ticket.service_pattern, self.service_pattern)
|
||||||
|
|
||||||
def assert_service_ticket(self, client, response):
|
def assert_service_ticket(self, client, response, service="https://www.example.com"):
|
||||||
"""check that a ticket is well emited when requested on a allowed service"""
|
"""check that a ticket is well emited when requested on a allowed service"""
|
||||||
# On ticket emission, we should be redirected to the service url, setting the ticket
|
# On ticket emission, we should be redirected to the service url, setting the ticket
|
||||||
# GET parameter
|
# GET parameter
|
||||||
|
@ -270,7 +270,7 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
|
||||||
self.assertTrue(response.has_header('Location'))
|
self.assertTrue(response.has_header('Location'))
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
response['Location'].startswith(
|
response['Location'].startswith(
|
||||||
"https://www.example.com?ticket=%s-" % settings.CAS_SERVICE_TICKET_PREFIX
|
"%s?ticket=%s-" % (service, settings.CAS_SERVICE_TICKET_PREFIX)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# check that the value of the ticket GET parameter match the value of the ticket
|
# check that the value of the ticket GET parameter match the value of the ticket
|
||||||
|
@ -337,14 +337,17 @@ class LoginTestCase(TestCase, BaseServicePattern, CanLogin):
|
||||||
self.assertFalse(b"Service https://www.example.net not allowed" in response.content)
|
self.assertFalse(b"Service https://www.example.net not allowed" in response.content)
|
||||||
|
|
||||||
def test_view_login_get_auth_allowed_service(self):
|
def test_view_login_get_auth_allowed_service(self):
|
||||||
"""Request a ticket for an allowed service by an authenticated client containing non ascii char in url"""
|
"""
|
||||||
|
Request a ticket for an allowed service by an authenticated client containing
|
||||||
|
non ascii char in url
|
||||||
|
"""
|
||||||
# get a client that is already authenticated
|
# get a client that is already authenticated
|
||||||
client = get_auth_client()
|
client = get_auth_client()
|
||||||
# ask for a ticket for https://www.example.com
|
# ask for a ticket for https://www.example.com
|
||||||
response = client.get("/login?service=https://www.example.com/é")
|
response = client.get("/login?service=https://www.example.com/é")
|
||||||
# as https://www.example.com/é is a valid service a ticket should be created and the
|
# as https://www.example.com/é is a valid service a ticket should be created and the
|
||||||
# user redirected to the service url
|
# user redirected to the service url
|
||||||
self.assert_service_ticket(client, response)
|
self.assert_service_ticket(client, response, service="https://www.example.com/%C3%A9")
|
||||||
|
|
||||||
def test_view_login_get_auth_allowed_service_non_ascii(self):
|
def test_view_login_get_auth_allowed_service_non_ascii(self):
|
||||||
"""Request a ticket for an allowed service by an authenticated client"""
|
"""Request a ticket for an allowed service by an authenticated client"""
|
||||||
|
|
|
@ -249,15 +249,25 @@ def update_url(url, params):
|
||||||
:return: The URL with an updated querystring
|
:return: The URL with an updated querystring
|
||||||
:rtype: unicode
|
:rtype: unicode
|
||||||
"""
|
"""
|
||||||
if not isinstance(url, bytes):
|
def to_unicode(data):
|
||||||
url = url.encode('utf-8')
|
if isinstance(data, bytes):
|
||||||
for key, value in list(params.items()):
|
return data.decode('utf-8')
|
||||||
if not isinstance(key, bytes):
|
else:
|
||||||
del params[key]
|
return data
|
||||||
key = key.encode('utf-8')
|
|
||||||
if not isinstance(value, bytes):
|
def to_bytes(data):
|
||||||
value = value.encode('utf-8')
|
if not isinstance(data, bytes):
|
||||||
params[key] = value
|
return data.encode('utf-8')
|
||||||
|
else:
|
||||||
|
return data
|
||||||
|
|
||||||
|
if six.PY3:
|
||||||
|
url = to_unicode(url)
|
||||||
|
params = {to_unicode(key): to_unicode(value) for (key, value) in params.items()}
|
||||||
|
else:
|
||||||
|
url = to_bytes(url)
|
||||||
|
params = {to_bytes(key): to_bytes(value) for (key, value) in params.items()}
|
||||||
|
|
||||||
url_parts = list(urlparse(url))
|
url_parts = list(urlparse(url))
|
||||||
query = dict(parse_qsl(url_parts[4], keep_blank_values=True))
|
query = dict(parse_qsl(url_parts[4], keep_blank_values=True))
|
||||||
query.update(params)
|
query.update(params)
|
||||||
|
@ -265,10 +275,12 @@ def update_url(url, params):
|
||||||
query = list(query.items())
|
query = list(query.items())
|
||||||
query.sort()
|
query.sort()
|
||||||
url_query = urlencode(query)
|
url_query = urlencode(query)
|
||||||
if not isinstance(url_query, bytes): # pragma: no cover in python3 urlencode return an unicode
|
|
||||||
url_query = url_query.encode("utf-8")
|
|
||||||
url_parts[4] = url_query
|
url_parts[4] = url_query
|
||||||
return urlunparse(url_parts).decode('utf-8')
|
url = urlunparse(url_parts)
|
||||||
|
|
||||||
|
if isinstance(url, bytes):
|
||||||
|
url = url.decode('utf-8')
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
def unpack_nested_exception(error):
|
def unpack_nested_exception(error):
|
||||||
|
|
Loading…
Reference in a new issue