summaryrefslogtreecommitdiff
path: root/requests-0.14.0/requests/packages/oauthlib/oauth2/draft25/tokens.py
blob: 74491fb901ad3698e30e6184cc3c1aff816b7303 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from __future__ import absolute_import
"""
oauthlib.oauth2.draft25.tokens
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This module contains methods for adding two types of access tokens to requests.

- Bearer http://tools.ietf.org/html/draft-ietf-oauth-saml2-bearer-08
- MAC http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-00

"""
from binascii import b2a_base64
import hashlib
import hmac
from urlparse import urlparse

from oauthlib.common import add_params_to_uri, add_params_to_qs
from . import utils


def prepare_mac_header(token, uri, key, http_method, nonce=None, headers=None,
        body=None, ext=u'', hash_algorithm=u'hmac-sha-1'):
    """Add an `MAC Access Authentication`_ signature to headers.

    Unlike OAuth 1, this HMAC signature does not require inclusion of the request
    payload/body, neither does it use a combination of client_secret and
    token_secret but rather a mac_key provided together with the access token.

    Currently two algorithms are supported, "hmac-sha-1" and "hmac-sha-256",
    `extension algorithms`_ are not supported.

    Example MAC Authorization header, linebreaks added for clarity

    Authorization: MAC id="h480djs93hd8",
                       nonce="1336363200:dj83hs9s",
                       mac="bhCQXTVyfj5cmA9uKkPFx1zeOXM="

    .. _`MAC Access Authentication`: http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
    .. _`extension algorithms`: http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01#section-7.1

    :param uri: Request URI.
    :param headers: Request headers as a dictionary.
    :param http_method: HTTP Request method.
    :param key: MAC given provided by token endpoint.
    :param algorithm: HMAC algorithm provided by token endpoint.
    :return: headers dictionary with the authorization field added.
    """
    http_method = http_method.upper()
    host, port = utils.host_from_uri(uri)

    if hash_algorithm.lower() == u'hmac-sha-1':
        h = hashlib.sha1
    else:
        h = hashlib.sha256

    nonce = nonce or u'{0}:{1}'.format(utils.generate_nonce(), utils.generate_timestamp())
    sch, net, path, par, query, fra = urlparse(uri)

    if query:
        request_uri = path + u'?' + query
    else:
        request_uri = path

    # Hash the body/payload
    if body is not None:
        bodyhash = b2a_base64(h(body).digest())[:-1].decode('utf-8')
    else:
        bodyhash = u''

    # Create the normalized base string
    base = []
    base.append(nonce)
    base.append(http_method.upper())
    base.append(request_uri)
    base.append(host)
    base.append(port)
    base.append(bodyhash)
    base.append(ext)
    base_string = '\n'.join(base) + u'\n'

    # hmac struggles with unicode strings - http://bugs.python.org/issue5285
    if isinstance(key, unicode):
        key = key.encode('utf-8')
    sign = hmac.new(key, base_string, h)
    sign = b2a_base64(sign.digest())[:-1].decode('utf-8')

    header = []
    header.append(u'MAC id="%s"' % token)
    header.append(u'nonce="%s"' % nonce)
    if bodyhash:
        header.append(u'bodyhash="%s"' % bodyhash)
    if ext:
        header.append(u'ext="%s"' % ext)
    header.append(u'mac="%s"' % sign)

    headers = headers or {}
    headers[u'Authorization'] = u', '.join(header)
    return headers


def prepare_bearer_uri(token, uri):
    """Add a `Bearer Token`_ to the request URI.
    Not recommended, use only if client can't use authorization header or body.

    http://www.example.com/path?access_token=h480djs93hd8

    .. _`Bearer Token`: http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-18
    """
    return add_params_to_uri(uri, [((u'access_token', token))])


def prepare_bearer_headers(token, headers=None):
    """Add a `Bearer Token`_ to the request URI.
    Recommended method of passing bearer tokens.

    Authorization: Bearer h480djs93hd8

    .. _`Bearer Token`: http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-18
    """
    headers = headers or {}
    headers[u'Authorization'] = u'Bearer %s' % token
    return headers


def prepare_bearer_body(token, body=u''):
    """Add a `Bearer Token`_ to the request body.

    access_token=h480djs93hd8

    .. _`Bearer Token`: http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-18
    """
    return add_params_to_qs(body, [((u'access_token', token))])