def generate_authorization_header(oauth_params, realm=None, param_delimiter=","): """ Builds the Authorization header value. Please note that the generated authorization header value will be on a single line. :: {"oauth_b": "http://example.com/c", ...}, "example foo" -> 'OAuth realm="example foo",oauth_b="http%3A%2F%2Fexample.com%2Fc"...' :see: Authorization Header http://tools.ietf.org/html/rfc5849#section-3.5.1 :param oauth_params: Protocol-specific parameters excluding the ``realm`` parameter. :param realm: If specified, the realm is included into the Authorization header. The realm is never percent-encoded according to the OAuth spec. :param param_delimiter: The delimiter used to separate header value parameters. According to the Specification, this must be a comma ",". However, certain services like Yahoo! use "&" instead. Comma is default. See https://github.com/oauth/oauth-ruby/pull/12 :returns: A properly formatted Authorization header value. """ param_delimiter = utf8_encode_if_unicode(param_delimiter) if realm: value = b('OAuth realm="') + utf8_encode_if_unicode(realm) + \ SYMBOL_INVERTED_DOUBLE_QUOTE + param_delimiter else: value = b("OAuth ") oauth_params = request_query_remove_non_oauth(oauth_params) normalized_param_pairs = urlencode_sl(oauth_params) value += param_delimiter.join([k + SYMBOL_EQUAL + SYMBOL_INVERTED_DOUBLE_QUOTE + v + SYMBOL_INVERTED_DOUBLE_QUOTE for k, v in normalized_param_pairs]) return value
def urlparse_normalized(url): """ Like :func:`urlparse.urlparse` but also normalizes scheme, netloc, port, and the path. Use with OAuth URLs. :see: Base String URI (http://tools.ietf.org/html/rfc5849#section-3.4.1.2) :param url: The URL to split and normalize. :returns: Tuple that contains these elements: ``(scheme, netloc, path, params, query, fragment)`` """ if not url: raise InvalidUrlError("Invalid URL `%r`" % (url,)) parts = urlparse(url) scheme = parts.scheme.lower() # Netloc. username = parts.username or SYMBOL_EMPTY_BYTES password = (b(":") + parts.password) if parts.password \ else SYMBOL_EMPTY_BYTES credentials = username + password credentials = (credentials + b("@")) if credentials else SYMBOL_EMPTY_BYTES hostname = utf8_encode_if_unicode(parts.hostname.lower()) # Exclude default port numbers. # See: if parts.port: if (scheme == b("http") and parts.port == 80) \ or (scheme == b("https") and parts.port == 443): port = SYMBOL_EMPTY_BYTES else: port = (b(":") + str(parts.port).encode("ascii")) if parts.port \ else SYMBOL_EMPTY_BYTES else: port = SYMBOL_EMPTY_BYTES netloc = credentials + hostname + port # http://tools.ietf.org/html/rfc3986#section-3 # and http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.2 path = parts.path or b("/") matrix_params = parts.params or SYMBOL_EMPTY_BYTES fragment = parts.fragment or SYMBOL_EMPTY_BYTES query = parts.query or SYMBOL_EMPTY_BYTES return scheme, netloc, path, matrix_params, query, fragment
def parse_qs(query_string): """ Parses a query parameter string according to the OAuth spec. Use only with OAuth query strings. :see: Parameter Sources (http://tools.ietf.org/html/rfc5849#section-3.4.1.3.1) :param query_string: Query string to parse. If ``query_string`` starts with a ``?`` character it will be ignored for convenience. """ query_string = utf8_encode_if_unicode(query_string) or SYMBOL_EMPTY_BYTES if query_string.startswith(SYMBOL_QUESTION_MARK): logging.warning( "Ignoring `?` query string prefix -- `%r`", query_string) query_string = query_string[1:] return _parse_qs(query_string, keep_blank_values=True)
def test_does_not_encode_else_to_utf8(self): self.assertEqual(text.utf8_encode_if_unicode(constants.UTF8_BYTES), constants.UTF8_BYTES) self.assertTrue(builtins.is_bytes(text.utf8_encode_if_unicode(constants.UTF8_BYTES))) self.assertEqual(text.utf8_encode_if_unicode(constants.UTF8_BYTES2), constants.UTF8_BYTES2) self.assertTrue(builtins.is_bytes(text.utf8_encode_if_unicode(constants.UTF8_BYTES2))) self.assertEqual(text.utf8_encode_if_unicode(None), None) self.assertEqual(text.utf8_encode_if_unicode(False), False) self.assertEqual(text.utf8_encode_if_unicode(5), 5) self.assertEqual(text.utf8_encode_if_unicode([]), []) self.assertEqual(text.utf8_encode_if_unicode(()), ()) self.assertEqual(text.utf8_encode_if_unicode({}), {}) self.assertEqual(text.utf8_encode_if_unicode(object), object)
def test_encodes_unicode_strings(self): self.assertEqual(text.utf8_encode_if_unicode(constants.UNICODE_STRING), constants.UTF8_BYTES) self.assertTrue(builtins.is_bytes(text.utf8_encode_if_unicode(constants.UNICODE_STRING))) self.assertEqual(text.utf8_encode_if_unicode(constants.UNICODE_STRING2), constants.UTF8_BYTES2) self.assertTrue(builtins.is_bytes(text.utf8_encode_if_unicode(constants.UNICODE_STRING2)))
def test_does_not_encode_else_to_utf8(self): self.assertEqual(utf8_encode_if_unicode(utf8_bytes), utf8_bytes) self.assertTrue(is_bytes(utf8_encode_if_unicode(utf8_bytes))) self.assertEqual(utf8_encode_if_unicode(utf8_bytes2), utf8_bytes2) self.assertTrue(is_bytes(utf8_encode_if_unicode(utf8_bytes2))) self.assertEqual(utf8_encode_if_unicode(None), None) self.assertEqual(utf8_encode_if_unicode(False), False) self.assertEqual(utf8_encode_if_unicode(5), 5) self.assertEqual(utf8_encode_if_unicode([]), []) self.assertEqual(utf8_encode_if_unicode(()), ()) self.assertEqual(utf8_encode_if_unicode({}), {}) self.assertEqual(utf8_encode_if_unicode(object), object)
def test_encodes_unicode_strings(self): self.assertEqual(utf8_encode_if_unicode(unicode_string), utf8_bytes) self.assertTrue(is_bytes(utf8_encode_if_unicode(unicode_string))) self.assertEqual(utf8_encode_if_unicode(unicode_string2), utf8_bytes2) self.assertTrue(is_bytes(utf8_encode_if_unicode(unicode_string2)))