Skip to content

Commit

Permalink
ZPublisher/utils: fix encoding in basic_auth_encode and basic_auth_de…
Browse files Browse the repository at this point in the history
…code (#1064)

Fixes #1062

and backports #1063 for 4.x

Basic authentication header charset is unspecified, but in practice
these days user agents use UTF-8.

On python 2 we also don't want basic_auth_encode to encode the str
because we don't expect an unicode but a native string.
  • Loading branch information
perrinjerome committed Oct 12, 2022
1 parent 337bc76 commit 68f0c12
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ https://zope.readthedocs.io/en/2.13/CHANGES.html
- Change functional testing utilities to support percent encoded and unicode
paths (`#1058 <https://github.com/zopefoundation/Zope/issues/1058>`_).

- Decode basic authentication header as utf-8, not latin1 anymore
(`#1061 <https://github.com/zopefoundation/Zope/issues/1061>`_).

- Make ``ZPublisher.utils.basic_auth_encode`` support non-ascii strings on Python 2
(`#1062 <https://github.com/zopefoundation/Zope/issues/1062>`_).

4.8.2 (2022-06-01)
------------------
Expand Down
14 changes: 14 additions & 0 deletions src/ZPublisher/tests/testHTTPRequest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
##############################################################################
# coding: utf-8
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
Expand Down Expand Up @@ -895,6 +896,19 @@ def test__authUserPW_with_embedded_colon(self):
self.assertEqual(user_id_x, user_id)
self.assertEqual(password_x, password)

def test__authUserPW_non_ascii(self):
user_id = 'usèr'
password = 'pàssword'
auth_header = basic_auth_encode(user_id, password)

environ = {'HTTP_AUTHORIZATION': auth_header}
request = self._makeOne(environ=environ)

user_id_x, password_x = request._authUserPW()

self.assertEqual(user_id_x, user_id)
self.assertEqual(password_x, password)

def test_debug_not_in_qs_still_gets_attr(self):
from zope.publisher.base import DebugFlags
# when accessing request.debug we will see the DebugFlags instance
Expand Down
8 changes: 5 additions & 3 deletions src/ZPublisher/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,11 @@ def basic_auth_encode(user, password=None):
value = user
if password is not None:
value = value + ':' + password
header = b'Basic ' + base64.b64encode(value.encode('latin-1'))
if PY3:
header = header.decode('latin-1')
value = value.encode()
header = b'Basic ' + base64.b64encode(value)
if PY3:
header = header.decode()
return header


Expand All @@ -103,6 +105,6 @@ def basic_auth_decode(token):
value = token.split()[-1] # Strip 'Basic '
plain = base64.b64decode(value)
if PY3:
plain = plain.decode('latin-1')
plain = plain.decode()
user, password = plain.split(':', 1) # Split at most once
return (user, password)

0 comments on commit 68f0c12

Please sign in to comment.