|
1 | 1 | """Various helper functions""" |
2 | 2 | import base64 |
| 3 | +import binascii |
3 | 4 | import datetime |
4 | 5 | import functools |
5 | 6 | import io |
@@ -31,6 +32,41 @@ def __new__(cls, login, password='', encoding='latin1'): |
31 | 32 |
|
32 | 33 | return super().__new__(cls, login, password, encoding) |
33 | 34 |
|
| 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 | + |
34 | 70 | def encode(self): |
35 | 71 | """Encode credentials.""" |
36 | 72 | creds = ('%s:%s' % (self.login, self.password)).encode(self.encoding) |
|
0 commit comments