parameters.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. # -*- coding: utf-8 -*-
  2. """
  3. oauthlib.parameters
  4. ~~~~~~~~~~~~~~~~~~~
  5. This module contains methods related to `section 3.5`_ of the OAuth 1.0a spec.
  6. .. _`section 3.5`: http://tools.ietf.org/html/rfc5849#section-3.5
  7. """
  8. from __future__ import absolute_import, unicode_literals
  9. try:
  10. from urlparse import urlparse, urlunparse
  11. except ImportError:
  12. from urllib.parse import urlparse, urlunparse
  13. from . import utils
  14. from oauthlib.common import extract_params, urlencode
  15. # TODO: do we need filter_params now that oauth_params are handled by Request?
  16. # We can easily pass in just oauth protocol params.
  17. @utils.filter_params
  18. def prepare_headers(oauth_params, headers=None, realm=None):
  19. """**Prepare the Authorization header.**
  20. Per `section 3.5.1`_ of the spec.
  21. Protocol parameters can be transmitted using the HTTP "Authorization"
  22. header field as defined by `RFC2617`_ with the auth-scheme name set to
  23. "OAuth" (case insensitive).
  24. For example::
  25. Authorization: OAuth realm="Example",
  26. oauth_consumer_key="0685bd9184jfhq22",
  27. oauth_token="ad180jjd733klru7",
  28. oauth_signature_method="HMAC-SHA1",
  29. oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
  30. oauth_timestamp="137131200",
  31. oauth_nonce="4572616e48616d6d65724c61686176",
  32. oauth_version="1.0"
  33. .. _`section 3.5.1`: http://tools.ietf.org/html/rfc5849#section-3.5.1
  34. .. _`RFC2617`: http://tools.ietf.org/html/rfc2617
  35. """
  36. headers = headers or {}
  37. # Protocol parameters SHALL be included in the "Authorization" header
  38. # field as follows:
  39. authorization_header_parameters_parts = []
  40. for oauth_parameter_name, value in oauth_params:
  41. # 1. Parameter names and values are encoded per Parameter Encoding
  42. # (`Section 3.6`_)
  43. #
  44. # .. _`Section 3.6`: http://tools.ietf.org/html/rfc5849#section-3.6
  45. escaped_name = utils.escape(oauth_parameter_name)
  46. escaped_value = utils.escape(value)
  47. # 2. Each parameter's name is immediately followed by an "=" character
  48. # (ASCII code 61), a """ character (ASCII code 34), the parameter
  49. # value (MAY be empty), and another """ character (ASCII code 34).
  50. part = '{0}="{1}"'.format(escaped_name, escaped_value)
  51. authorization_header_parameters_parts.append(part)
  52. # 3. Parameters are separated by a "," character (ASCII code 44) and
  53. # OPTIONAL linear whitespace per `RFC2617`_.
  54. #
  55. # .. _`RFC2617`: http://tools.ietf.org/html/rfc2617
  56. authorization_header_parameters = ', '.join(
  57. authorization_header_parameters_parts)
  58. # 4. The OPTIONAL "realm" parameter MAY be added and interpreted per
  59. # `RFC2617 section 1.2`_.
  60. #
  61. # .. _`RFC2617 section 1.2`: http://tools.ietf.org/html/rfc2617#section-1.2
  62. if realm:
  63. # NOTE: realm should *not* be escaped
  64. authorization_header_parameters = ('realm="%s", ' % realm +
  65. authorization_header_parameters)
  66. # the auth-scheme name set to "OAuth" (case insensitive).
  67. authorization_header = 'OAuth %s' % authorization_header_parameters
  68. # contribute the Authorization header to the given headers
  69. full_headers = {}
  70. full_headers.update(headers)
  71. full_headers['Authorization'] = authorization_header
  72. return full_headers
  73. def _append_params(oauth_params, params):
  74. """Append OAuth params to an existing set of parameters.
  75. Both params and oauth_params is must be lists of 2-tuples.
  76. Per `section 3.5.2`_ and `3.5.3`_ of the spec.
  77. .. _`section 3.5.2`: http://tools.ietf.org/html/rfc5849#section-3.5.2
  78. .. _`3.5.3`: http://tools.ietf.org/html/rfc5849#section-3.5.3
  79. """
  80. merged = list(params)
  81. merged.extend(oauth_params)
  82. # The request URI / entity-body MAY include other request-specific
  83. # parameters, in which case, the protocol parameters SHOULD be appended
  84. # following the request-specific parameters, properly separated by an "&"
  85. # character (ASCII code 38)
  86. merged.sort(key=lambda i: i[0].startswith('oauth_'))
  87. return merged
  88. def prepare_form_encoded_body(oauth_params, body):
  89. """Prepare the Form-Encoded Body.
  90. Per `section 3.5.2`_ of the spec.
  91. .. _`section 3.5.2`: http://tools.ietf.org/html/rfc5849#section-3.5.2
  92. """
  93. # append OAuth params to the existing body
  94. return _append_params(oauth_params, body)
  95. def prepare_request_uri_query(oauth_params, uri):
  96. """Prepare the Request URI Query.
  97. Per `section 3.5.3`_ of the spec.
  98. .. _`section 3.5.3`: http://tools.ietf.org/html/rfc5849#section-3.5.3
  99. """
  100. # append OAuth params to the existing set of query components
  101. sch, net, path, par, query, fra = urlparse(uri)
  102. query = urlencode(
  103. _append_params(oauth_params, extract_params(query) or []))
  104. return urlunparse((sch, net, path, par, query, fra))