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