Skip to content

Commit

Permalink
Merge pull request #744 from luhn/basic-auth-decode
Browse files Browse the repository at this point in the history
Implement BasicAuth decode classmethod.
  • Loading branch information
fafhrd91 committed May 23, 2016
2 parents 222b2b3 + 46db268 commit bc165f1
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
22 changes: 22 additions & 0 deletions aiohttp/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import asyncio
import base64
import binascii
import datetime
import functools
import io
Expand Down Expand Up @@ -42,6 +43,27 @@ def __new__(cls, login, password='', encoding='latin1'):

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

@classmethod
def decode(cls, auth_header, encoding='latin1'):
"""Create a :class:`BasicAuth` object from an ``Authorization`` HTTP
header."""
split = auth_header.strip().split(' ')
if len(split) == 2:
if split[0].strip().lower() != 'basic':
raise ValueError('Unknown authorization method %s' % split[0])
to_decode = split[1]
else:
raise ValueError('Could not parse authorization header.')

try:
username, _, password = base64.b64decode(
to_decode.encode('ascii')
).decode(encoding).partition(':')
except binascii.Error:
raise ValueError('Invalid base64 encoding.')

return cls(username, password, encoding=encoding)

def encode(self):
"""Encode credentials."""
creds = ('%s:%s' % (self.login, self.password)).encode(self.encoding)
Expand Down
10 changes: 10 additions & 0 deletions docs/client_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,16 @@ BasicAuth
e.g. *auth* parameter for :meth:`ClientSession.request`.


.. classmethod:: decode(auth_header, encoding='latin1')

Decode HTTP basic authentication credentials.

:param str auth_header: The ``Authorization`` header to decode.
:param str encoding: (optional) encoding ('latin1' by default)

:return: decoded authentication data, :class:`BasicAuth`.


.. method:: encode()

Encode credentials into string suitable for ``Authorization``
Expand Down
21 changes: 21 additions & 0 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,27 @@ def test_basic_auth4():
assert auth.encode() == 'Basic bmtpbTpwd2Q='


def test_basic_auth_decode():
auth = helpers.BasicAuth.decode('Basic bmtpbTpwd2Q=')
assert auth.login == 'nkim'
assert auth.password == 'pwd'


def test_basic_auth_invalid():
with pytest.raises(ValueError):
helpers.BasicAuth.decode('bmtpbTpwd2Q=')


def test_basic_auth_decode_not_basic():
with pytest.raises(ValueError):
helpers.BasicAuth.decode('Complex bmtpbTpwd2Q=')


def test_basic_auth_decode_bad_base64():
with pytest.raises(ValueError):
helpers.BasicAuth.decode('Basic bmtpbTpwd2Q')


def test_invalid_formdata_params():
with pytest.raises(TypeError):
helpers.FormData('asdasf')
Expand Down

0 comments on commit bc165f1

Please sign in to comment.