Skip to content

Commit 27a5feb

Browse files
committed
Implement BasicAuth decode classmethod.
1 parent 078fafd commit 27a5feb

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

aiohttp/helpers.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Various helper functions"""
22
import base64
3+
import binascii
34
import datetime
45
import functools
56
import io
@@ -31,6 +32,41 @@ def __new__(cls, login, password='', encoding='latin1'):
3132

3233
return super().__new__(cls, login, password, encoding)
3334

35+
@classmethod
36+
def decode(cls, auth_header, encoding='latin1'):
37+
"""Create a :class:`BasicAuth` object from an ``Authorization`` HTTP
38+
header.
39+
40+
:param auth_header: The value of the ``Authorization`` header.
41+
:type auth_header: str
42+
:param encoding: The character encoding used on the password.
43+
:type encoding: str
44+
45+
:returns: The decoded authentication.
46+
:rtype: :class:`BasicAuth`
47+
48+
:raises ValueError: if the headers are unable to be decoded.
49+
50+
"""
51+
split = auth_header.strip().split(' ')
52+
if len(split) == 2:
53+
if split[0].strip().lower() != 'basic':
54+
raise ValueError('Unknown authorization method %s' % split[0])
55+
to_decode = split[1]
56+
elif len(split) == 1:
57+
to_decode = split[0]
58+
else:
59+
raise ValueError('Could not parse authorization header.')
60+
61+
try:
62+
username, _, password = base64.b64decode(
63+
to_decode.encode('ascii')
64+
).decode(encoding).partition(':')
65+
except binascii.Error:
66+
raise ValueError('Invalid base64 encoding.')
67+
68+
return cls(username, password)
69+
3470
def encode(self):
3571
"""Encode credentials."""
3672
creds = ('%s:%s' % (self.login, self.password)).encode(self.encoding)

tests/test_helpers.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ def test_basic_auth4():
7171
assert auth.encode() == 'Basic bmtpbTpwd2Q='
7272

7373

74+
def test_basic_auth_decode():
75+
auth = helpers.BasicAuth.decode('Basic bmtpbTpwd2Q=')
76+
assert auth.login == 'nkim'
77+
assert auth.password == 'pwd'
78+
79+
80+
def test_basic_auth_decode_not_basic():
81+
with pytest.raises(ValueError):
82+
helpers.BasicAuth.decode('Complex bmtpbTpwd2Q=')
83+
84+
85+
def test_basic_auth_decode_bad_base64():
86+
with pytest.raises(ValueError):
87+
helpers.BasicAuth.decode('Basic bmtpbTpwd2Q')
88+
89+
7490
def test_invalid_formdata_params():
7591
with pytest.raises(TypeError):
7692
helpers.FormData('asdasf')

0 commit comments

Comments
 (0)