utils.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # -*- coding: utf-8 -*-
  2. """
  3. oauthlib.utils
  4. ~~~~~~~~~~~~~~
  5. This module contains utility methods used by various parts of the OAuth
  6. spec.
  7. """
  8. from __future__ import absolute_import, unicode_literals
  9. try:
  10. import urllib2
  11. except ImportError:
  12. import urllib.request as urllib2
  13. from oauthlib.common import quote, unquote, bytes_type, unicode_type
  14. UNICODE_ASCII_CHARACTER_SET = ('abcdefghijklmnopqrstuvwxyz'
  15. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  16. '0123456789')
  17. def filter_params(target):
  18. """Decorator which filters params to remove non-oauth_* parameters
  19. Assumes the decorated method takes a params dict or list of tuples as its
  20. first argument.
  21. """
  22. def wrapper(params, *args, **kwargs):
  23. params = filter_oauth_params(params)
  24. return target(params, *args, **kwargs)
  25. wrapper.__doc__ = target.__doc__
  26. return wrapper
  27. def filter_oauth_params(params):
  28. """Removes all non oauth parameters from a dict or a list of params."""
  29. is_oauth = lambda kv: kv[0].startswith("oauth_")
  30. if isinstance(params, dict):
  31. return list(filter(is_oauth, list(params.items())))
  32. else:
  33. return list(filter(is_oauth, params))
  34. def escape(u):
  35. """Escape a unicode string in an OAuth-compatible fashion.
  36. Per `section 3.6`_ of the spec.
  37. .. _`section 3.6`: http://tools.ietf.org/html/rfc5849#section-3.6
  38. """
  39. if not isinstance(u, unicode_type):
  40. raise ValueError('Only unicode objects are escapable. ' +
  41. 'Got %s of type %s.' % (u, type(u)))
  42. # Letters, digits, and the characters '_.-' are already treated as safe
  43. # by urllib.quote(). We need to add '~' to fully support rfc5849.
  44. return quote(u, safe=b'~')
  45. def unescape(u):
  46. if not isinstance(u, unicode_type):
  47. raise ValueError('Only unicode objects are unescapable.')
  48. return unquote(u)
  49. def parse_keqv_list(l):
  50. """A unicode-safe version of urllib2.parse_keqv_list"""
  51. # With Python 2.6, parse_http_list handles unicode fine
  52. return urllib2.parse_keqv_list(l)
  53. def parse_http_list(u):
  54. """A unicode-safe version of urllib2.parse_http_list"""
  55. # With Python 2.6, parse_http_list handles unicode fine
  56. return urllib2.parse_http_list(u)
  57. def parse_authorization_header(authorization_header):
  58. """Parse an OAuth authorization header into a list of 2-tuples"""
  59. auth_scheme = 'OAuth '.lower()
  60. if authorization_header[:len(auth_scheme)].lower().startswith(auth_scheme):
  61. items = parse_http_list(authorization_header[len(auth_scheme):])
  62. try:
  63. return list(parse_keqv_list(items).items())
  64. except (IndexError, ValueError):
  65. pass
  66. raise ValueError('Malformed authorization header')