Beispiel #1
0
    def test_filter(self):
        params = {
            "a2": ["r b"],
            "b5": ["=%3D"],
            "a3": ["a", "2 q"],
            "c@": [""],
            "c2": [""],
            "oauth_consumer_key": ["9djdj82h48djs9d2"],
            "oauth_token": ["kkk9d7dh3k39sjv7"],
            "oauth_signature_method": ["HMAC-SHA1"],
            "oauth_timestamp": ["137131201"],
            "oauth_nonce": ["7d8f3e4a"],
        }
        query_string = "?a2=r%20b&a3=2%20q&a3=a&b5=%3D%253D&c%40=&c2=&oauth_consumer_key=9djdj82h48djs9d2&oauth_nonce=7d8f3e4a&oauth_signature_method=HMAC-SHA1&oauth_timestamp=137131201&oauth_token=kkk9d7dh3k39sjv7"
        expected_params = {
            "oauth_consumer_key": ["9djdj82h48djs9d2"],
            "oauth_token": ["kkk9d7dh3k39sjv7"],
            "oauth_signature_method": ["HMAC-SHA1"],
            "oauth_timestamp": ["137131201"],
            "oauth_nonce": ["7d8f3e4a"],
        }
        expected_result = urlencode_s(expected_params)

        assert_equal(urlencode_s(request_protocol_params_sanitize(params)), expected_result)
        assert_equal(urlencode_s(request_protocol_params_sanitize(query_string)), expected_result)
Beispiel #2
0
    def test_ignores_prefixed_question_mark_character_if_included(self):
        query_string = """\
?a2=r%20b\
&a3=2%20q\
&a3=a\
&b5=%3D%253D\
&c%40=\
&c2=\
&oauth_consumer_key=9djdj82h48djs9d2\
&oauth_nonce=7d8f3e4a\
&oauth_signature_method=HMAC-SHA1\
&oauth_timestamp=137131201\
&oauth_token=kkk9d7dh3k39sjv7"""
        expected_params = {
            "a2": ["r b"],
            "b5": ["=%3D"],
            "a3": ["a", "2 q"],
            "c@": [""],
            "c2": [""],
            OAUTH_PARAM_CONSUMER_KEY: ["9djdj82h48djs9d2"],
            OAUTH_PARAM_TOKEN: ["kkk9d7dh3k39sjv7"],
            OAUTH_PARAM_SIGNATURE_METHOD: ["HMAC-SHA1"],
            OAUTH_PARAM_TIMESTAMP: ["137131201"],
            OAUTH_PARAM_NONCE: ["7d8f3e4a"],
        }
        self.assertEqual(urlencode_s(query_unflatten(query_string)),
                         urlencode_s(expected_params))
Beispiel #3
0
 def test_ignores_prefixed_question_mark_character_if_included(self):
     query_string = "?a2=r%20b&a3=2%20q&a3=a&b5=%3D%253D&c%40=&c2=&oauth_consumer_key=9djdj82h48djs9d2&oauth_nonce=7d8f3e4a&oauth_signature_method=HMAC-SHA1&oauth_timestamp=137131201&oauth_token=kkk9d7dh3k39sjv7"
     expected_params = {
         "a2": ["r b"],
         "b5": ["=%3D"],
         "a3": ["a", "2 q"],
         "c@": [""],
         "c2": [""],
         "oauth_consumer_key": ["9djdj82h48djs9d2"],
         "oauth_token": ["kkk9d7dh3k39sjv7"],
         "oauth_signature_method": ["HMAC-SHA1"],
         "oauth_timestamp": ["137131201"],
         "oauth_nonce": ["7d8f3e4a"],
     }
     assert_equal(urlencode_s(query_unflatten(query_string)), urlencode_s(expected_params))
Beispiel #4
0
    def fetch_access_token(self, code, redirect_uri, error=None,
                           method="POST", payload_params=None,
                           async_callback=None):
        """
        Fetches an access token and a refresh token.

        :param code:
            The code returned by the OAuth 2.0 server to your callback URI.
            Set to ``None`` if an error occurred.
        :param redirect_uri:
            The URL to which the OAuth 2.0 server should redirect.
        :param error:
            Set this to the error query parameter from your callback handler
            if available. (Default ``None``.)
        :param method:
            (Default POST). The HTTP method to use.
        :param payload_params:
            Additional params to he URL-encoded into the body. (Existing
            parameters may be overridden).
        :param async_callback:
            (Optional) Asynchronous callback handler that will be called with the
            received token. If none is specified, this function returns
            the token instead.

        :returns:
            Access token and refresh token (if ``async_callback`` is
            unspecified). If ``async_callback`` is specified, ``None``
            will be returned.
        """
        # TODO: Add async_callback signature and example in documentation.
        if error:
            raise OAuthError(error)

        if not code:
            raise ValueError("argument ``code`` not specified")

        params = {
            "code": code,
            "client_id": self._client_credentials.identifier,
            "client_secret": self._client_credentials.shared_secret,
            "redirect_uri": redirect_uri,
            "grant_type": "authorization_code",
        }
        if payload_params:
            params.update(payload_params)
        body = urlencode_s(params)
        headers = {
            HEADER_CONTENT_TYPE: CONTENT_TYPE_FORM_URLENCODED,
        }
        response = self._http_client.fetch(
            RequestAdapter(method=method, url=self._token_uri,
                           body=body, headers=headers))
        if response.error:
            raise HttpError(
                "[fetch access token] OAuth 2.0 server response " \
                "error: %d - %s" % (response.status, response.reason))
        logging.info(response.content_type)
        token = json_decode(response.content)
        logging.info(token)
        return token
Beispiel #5
0
    def test_adds_query_params_properly(self):
        params1 = {
            b("a2"): b("r b"),
            b("b5"): b("=%3D"),
            b("a3"): [b("a")],
            b("c2"): [b("")],
        }
        params2 = {
            b("a3"): [b("2 q")],
            b("c@"): b(""),
        }
        params3 = b("""oauth_nonce=7d8f3e4a\
&oauth_timestamp=137131201\
&oauth_signature_method=HMAC-SHA1\
&oauth_consumer_key=9djdj82h48djs9d2\
&oauth_token=kkk9d7dh3k39sjv7\
""")
        resulting_query_string = b("""\
a2=r%20b\
&a3=2%20q\
&a3=a\
&b5=%3D%253D\
&c%40=\
&c2=\
&oauth_consumer_key=9djdj82h48djs9d2\
&oauth_nonce=7d8f3e4a\
&oauth_signature_method=HMAC-SHA1\
&oauth_timestamp=137131201\
&oauth_token=kkk9d7dh3k39sjv7""")
        self.assertEqual(urlencode_s(query_add(params1, params2, params3)),
                         resulting_query_string)
Beispiel #6
0
    def test_valid_query_string(self):
        params = {
            "a2": "r b",
            "b5": "=%3D",
            "a3": ["a", "2 q"],
            "c@": [""],
            "c2": "",
            OAUTH_PARAM_CONSUMER_KEY: "9djdj82h48djs9d2",
            OAUTH_PARAM_TOKEN: "kkk9d7dh3k39sjv7",
            OAUTH_PARAM_SIGNATURE_METHOD: "HMAC-SHA1",
            OAUTH_PARAM_TIMESTAMP: ["137131201"],
            OAUTH_PARAM_NONCE: "7d8f3e4a",
        }
        valid_query_string = b("""\
a2=r%20b\
&a3=2%20q\
&a3=a\
&b5=%3D%253D\
&c%40=\
&c2=\
&oauth_consumer_key=9djdj82h48djs9d2\
&oauth_nonce=7d8f3e4a\
&oauth_signature_method=HMAC-SHA1\
&oauth_timestamp=137131201\
&oauth_token=kkk9d7dh3k39sjv7""")
        self.assertEqual(urlencode_s(params), valid_query_string)
Beispiel #7
0
def _generate_signature_base_string_query(url_query_params, oauth_params):
    """
    Serializes URL query parameters and OAuth protocol parameters into a valid
    OAuth base string URI query string.

    :see: Parameter Normalization (http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2)
    :param url_query_params:
        A dictionary or string of URL query parameters. Any parameters starting
        with ``oauth_`` will be ignored.
    :param oauth_params:
        A dictionary or string of protocol-specific query parameters. Any parameter
        names that do not begin with ``oauth_`` will be excluded from the
        normalized query string. ``oauth_signature``, ``oauth_consumer_secret``,
        and ``oauth_token_secret`` are also specifically excluded.
    :returns:
        Normalized string of query parameters.
    """
    url_query_params = query_params_sanitize(url_query_params)
    oauth_params = request_protocol_params_sanitize(oauth_params)

    query_params = {}
    query_params.update(url_query_params)
    query_params.update(oauth_params)

    # Now encode the parameters, while ignoring 'oauth_signature' and obviously,
    # the secrets from the entire list of parameters.
    def allow_func(name, value):
        return name not in ("oauth_signature",
                            #"oauth_consumer_secret",    # Already filtered by protocol parameter sanitization above.
                            #"oauth_token_secret",       # Already filtered by protocol parameter sanitization above.
                            )
    query = urlencode_s(query_params, allow_func=allow_func)
    return query
Beispiel #8
0
 def test_sanitization_force_secure_default_and_removes_fragment(self):
     url = "https://www.EXAMPLE.com/request?a2=r%20b&a3=2%20q&a3=a&b5=%3D%253D&c%40=&c2=&oauth_consumer_key=9djdj82h48djs9d2&oauth_nonce=7d8f3e4a&oauth_signature_method=HMAC-SHA1&oauth_timestamp=137131201&oauth_token=kkk9d7dh3k39sjv7#fragment"
     expected_params = {
         "a2": ["r b"],
         "b5": ["=%3D"],
         "a3": ["a", "2 q"],
         "c@": [""],
         "c2": [""],
     }
     expected_result = "https://www.example.com/request?" + urlencode_s(expected_params)  # Fragment ignored.
     assert_equal(oauth_url_sanitize(url), expected_result)
Beispiel #9
0
    def test_filter(self):
        params = {
            "a2": ["r b"],
            "b5": ["=%3D"],
            "a3": ["a", "2 q"],
            "c@": [""],
            "c2": [""],
            OAUTH_PARAM_CONSUMER_KEY: ["9djdj82h48djs9d2"],
            OAUTH_PARAM_TOKEN: ["kkk9d7dh3k39sjv7"],
            OAUTH_PARAM_SIGNATURE_METHOD: ["HMAC-SHA1"],
            OAUTH_PARAM_TIMESTAMP: ["137131201"],
            OAUTH_PARAM_NONCE: ["7d8f3e4a"],
        }
        query_string = """\
?a2=r%20b\
&a3=2%20q\
&a3=a\
&b5=%3D%253D\
&c%40=\
&c2=\
&oauth_consumer_key=9djdj82h48djs9d2\
&oauth_nonce=7d8f3e4a\
&oauth_signature_method=HMAC-SHA1\
&oauth_timestamp=137131201\
&oauth_token=kkk9d7dh3k39sjv7"""
        expected_params = {
            OAUTH_PARAM_CONSUMER_KEY: ["9djdj82h48djs9d2"],
            OAUTH_PARAM_TOKEN: ["kkk9d7dh3k39sjv7"],
            OAUTH_PARAM_SIGNATURE_METHOD: ["HMAC-SHA1"],
            OAUTH_PARAM_TIMESTAMP: ["137131201"],
            OAUTH_PARAM_NONCE: ["7d8f3e4a"],
        }
        expected_result = urlencode_s(expected_params)

        self.assertEqual(urlencode_s(request_query_remove_non_oauth(params)),
                         expected_result)
        self.assertEqual(
            urlencode_s(request_query_remove_non_oauth(query_string)),
            expected_result)
Beispiel #10
0
 def test_valid_query_string(self):
     params = {
         "a2": "r b",
         "b5": "=%3D",
         "a3": ["a", "2 q"],
         "c@": [""],
         "c2": "",
         "oauth_consumer_key": "9djdj82h48djs9d2",
         "oauth_token": "kkk9d7dh3k39sjv7",
         "oauth_signature_method": "HMAC-SHA1",
         "oauth_timestamp": ["137131201"],
         "oauth_nonce": "7d8f3e4a",
     }
     valid_query_string = "a2=r%20b&a3=2%20q&a3=a&b5=%3D%253D&c%40=&c2=&oauth_consumer_key=9djdj82h48djs9d2&oauth_nonce=7d8f3e4a&oauth_signature_method=HMAC-SHA1&oauth_timestamp=137131201&oauth_token=kkk9d7dh3k39sjv7"
     assert_equal(urlencode_s(params), valid_query_string)
Beispiel #11
0
def generate_base_string_query(url_query, oauth_params):
    """
    Serializes URL query parameters and OAuth protocol parameters into a valid
    OAuth base string URI query string.

    :see: Parameter Normalization
          (http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2)
    :param url_query:
        A dictionary or string of URL query parameters. Any parameters starting
        with ``oauth_`` will be ignored.
    :param oauth_params:
        A dictionary or string of protocol-specific query parameters. Any
        parameter names that do not begin with ``oauth_`` will be excluded
        from the normalized query string. ``oauth_signature``,
        ``oauth_consumer_secret``, and ``oauth_token_secret`` are also
        specifically excluded.
    :returns:
        Normalized string of query parameters.
    """
    url_query = query_remove_oauth(url_query)
    oauth_params = request_query_remove_non_oauth(oauth_params)

    query_d = {}
    query_d.update(url_query)
    query_d.update(oauth_params)

    # Now encode the parameters, while ignoring 'oauth_signature' and obviously,
    # the secrets from the entire list of parameters.
    def allow_func(name, _):
        """Allows only protocol parameters that must be included into
        the signature.

        :param name:
            The name of the parameter.
        :returns:
            ``True`` if the parameter can be included; ``False`` otherwise.
        """
        return name not in (OAUTH_PARAM_SIGNATURE,
                            #OAUTH_PARAM_CONSUMER_SECRET, # Sanitized above.
                            #OAUTH_PARAM_TOKEN_SECRET,    # Sanitized above.
                            )
    query = urlencode_s(query_d, allow_func)
    return query
Beispiel #12
0
    def test_adds_query_params_properly(self):
        params1 = {
            "a2": "r b",
            "b5": "=%3D",
            "a3": ["a"],
            "c2": [""],
        }
        params2 = {
            "a3": ["2 q"],
            "c@": "",
        }
        params3 = """oauth_nonce=7d8f3e4a\
&oauth_timestamp=137131201\
&oauth_signature_method=HMAC-SHA1\
&oauth_consumer_key=9djdj82h48djs9d2\
&oauth_token=kkk9d7dh3k39sjv7\
"""
        resulting_query_string = "a2=r%20b&a3=2%20q&a3=a&b5=%3D%253D&c%40=&c2=&oauth_consumer_key=9djdj82h48djs9d2&oauth_nonce=7d8f3e4a&oauth_signature_method=HMAC-SHA1&oauth_timestamp=137131201&oauth_token=kkk9d7dh3k39sjv7"
        assert_equal(urlencode_s(query_add(params1, params2, params3)), resulting_query_string)
Beispiel #13
0
    def fetch_refreshed_access_token(self,
                                     refresh_token,
                                     method="POST",
                                     payload_params=None):
        """
        Fetches a refreshed access token from the OAuth 2.0 server.

        :param refresh_token:
            The previously-obtained refresh token.
        :param method:
            (Default POST) The HTTP method to use for the request.
        :param payload_params:
            (Default ``None``) Additional payload parameters to be URL-encoded
            and added into the request body.
        :returns:
            Refreshed access token.
        """
        # TODO: Add async_callback.
        params = {
            "client_id": self._client_credentials.identifier,
            "client_secret": self._client_credentials.shared_secret,
            "refresh_token": refresh_token,
            "grant_type": "refresh_token",
        }
        if payload_params:
            params.update(payload_params)
        body = urlencode_s(params)
        headers = {
            HEADER_CONTENT_TYPE: CONTENT_TYPE_FORM_URLENCODED,
        }
        response = self._http_client.fetch(RequestAdapter(method=method,
                                                          url=self._token_uri,
                                                          body=body,
                                                          headers=headers))
        if response.error:
            raise HttpError(
                "[refresh access token] OAuth 2.0 server response " \
                "error: %d - %s" % (response.status, response.reason))
        logging.info(response.content_type)
        token = json_decode(response.content)
        logging.info(token)
        return token
Beispiel #14
0
 def test_do_seq_removes_blank_lists(self):
     params = dict(a=[], c="something")
     self.assertEqual(urlencode_s(params), b("c=something"))
Beispiel #15
0
 def test_do_seq_dicts(self):
     # Behaves like doseq=1
     params = dict(a=dict(a='b'), c="something")
     self.assertEqual(urlencode_s(params), b('a=a&c=something'))