def test_equality_and_realm(self): params = { 'realm': ['Examp%20le'], 'oauth_nonce': ['4572616e48616d6d65724c61686176'], 'oauth_timestamp': ['137131200'], 'oauth_consumer_key': ['0685bd9184jfhq22'], 'oauth_something': [' Some Example'], 'oauth_signature_method': ['HMAC-SHA1'], 'oauth_version': ['1.0'], 'oauth_token': ['ad180jjd733klru7'], 'oauth_empty': [''], 'oauth_signature': ['wOJIO9A2W5mFwDgiDvZbTSMK/PY='], } expected_value = 'OAuth oauth_consumer_key="0685bd9184jfhq22",oauth_empty="",oauth_nonce="4572616e48616d6d65724c61686176",oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",oauth_signature_method="HMAC-SHA1",oauth_something="%20Some%20Example",oauth_timestamp="137131200",oauth_token="ad180jjd733klru7",oauth_version="1.0"' assert_equal(generate_normalized_authorization_header_value(params), expected_value) expected_value = 'OAuth realm="http://example.com/",oauth_consumer_key="0685bd9184jfhq22",oauth_empty="",oauth_nonce="4572616e48616d6d65724c61686176",oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",oauth_signature_method="HMAC-SHA1",oauth_something="%20Some%20Example",oauth_timestamp="137131200",oauth_token="ad180jjd733klru7",oauth_version="1.0"' assert_equal(generate_normalized_authorization_header_value(params, realm="http://example.com/") , expected_value)
def _build_request(self, method, url, payload_params=None, headers=None, token_or_temporary_credentials=None, realm=None, oauth_signature_method=SIGNATURE_METHOD_HMAC_SHA1, **extra_oauth_params): """ Builds an OAuth request. :param method: HTTP request method. :param url: The OAuth request URI. :param payload_params: A dictionary of payload parameters. These will be serialized into the URL or the entity-body depending on the HTTP request method. These must not include any parameters starting with ``oauth_``. Any of these parameters with names starting with the ``oauth_`` prefix will be ignored. :param headers: A dictionary of headers that will be passed along with the request. Must not include the "Authorization" header. :param realm: The value to use for the realm parameter in the Authorization HTTP header. It will be excluded from the request signature. :param oauth_signature_method: One of: 1. :attr:`pyoauth.oauth1.SIGNATURE_METHOD_HMAC_SHA1` 2. :attr:`pyoauth.oauth1.SIGNATURE_METHOD_RSA_SHA1` 3. :attr:`pyoauth.oauth1.SIGNATURE_METHOD_PLAINTEXT` :param extra_oauth_params: Any additional oauth parameters you would like to include. The parameter names must begin with ``oauth_``. Any other parameters with names that do not begin with this prefix will be ignored. :returns: An instance of :class:`pyoauth.http.Request`. """ method = method.upper() headers = headers or {} realm = realm or "" if oauth_signature_method not in SIGNATURE_METHOD_MAP: raise InvalidSignatureMethodError("Invalid signature method specified: `%r`" % (oauth_signature_method,)) # Required OAuth protocol parameters. # See Making Requests (http://tools.ietf.org/html/rfc5849#section-3.1) oauth_params = dict( oauth_consumer_key=self._client_credentials.identifier, oauth_signature_method=oauth_signature_method, oauth_timestamp=generate_timestamp(), oauth_nonce=generate_nonce(), oauth_version=self.oauth_version, ) if token_or_temporary_credentials: oauth_params["oauth_token"] = token_or_temporary_credentials.identifier if "_test_force_exclude_oauth_version" in extra_oauth_params: del oauth_params["oauth_version"] # Filter and add additional OAuth parameters. _force_override_reserved_oauth_params_for_tests = "_test_force_override_reserved_oauth_params" in extra_oauth_params extra_oauth_params = request_protocol_params_sanitize(extra_oauth_params) reserved_oauth_params = ( "oauth_signature", # Calculated from given parameters. "oauth_nonce", # System-generated. "oauth_timestamp", # System-generated. "oauth_consumer_key", # Provided when creating the client instance. "oauth_version", # Optional but MUST be set to "1.0" according to spec. "oauth_token", # Determined from the token or temporary credentials. ) for k, v in extra_oauth_params.items(): if not _force_override_reserved_oauth_params_for_tests and k in reserved_oauth_params: # Don't override these required system-generated protocol parameters. raise IllegalArgumentError("Cannot override system-generated protocol parameter `%r`." % k) else: if k in oauth_params: # Warn when an existing protocol parameter is being # overridden. logging.warning("Overriding existing protocol parameter `%r`=`%r` with `%r`=`%r`", k, oauth_params[k], k, v[0]) oauth_params[k] = v[0] # Filter payload parameters for the request. payload_params = query_params_sanitize(payload_params) # I was not entirely certain about whether PUT payload # params should be included in the signature or not. # Here is why: # # http://groups.google.com/group/oauth/browse_thread/thread/fdc0b11f2c4a8dc3/ # # http://tools.ietf.org/html/rfc5849#appendix-A # However, Appendix A in the RFC specification clarifies this point. # form URL encoded entity bodies in a request using any HTTP verb # must be part of the base string used for the signature. # Therefore, do NOT exclude payload params from the signature URL # when the PUT HTTP method is used. # #if method == "PUT": # signature_url = url #else: signature_url = url_add_query(url, payload_params) # Determine the request's OAuth signature. oauth_params["oauth_signature"] = self._sign_request_data(oauth_signature_method, method, signature_url, oauth_params, token_or_temporary_credentials) # Build request data now. # OAuth parameters and any parameters starting with the ``oauth_`` # must be included only in ONE of these three locations: # # 1. Authorization header. # 2. Request URI query string. # 3. Request entity body. # # See Parameter Transmission (http://tools.ietf.org/html/rfc5849#section-3.6) if "Authorization" in headers: raise InvalidAuthorizationHeaderError("Authorization field is already present in headers: `%r`" % (headers, )) if self._use_authorization_header: auth_header_value = \ generate_normalized_authorization_header_value(oauth_params, realm=realm, param_delimiter=self._authorization_header_param_delimiter) headers["Authorization"] = auth_header_value # Empty the params if using authorization so that they are not # included multiple times in a request below. oauth_params = None if method == "GET": request_url = url_add_query(url, payload_params) request_url = url_append_query(request_url, oauth_params) payload = "" else: # The payload params are not appended to the OAuth request URL # in this case but added to the payload instead. request_url = url headers["Content-Type"] = CONTENT_TYPE_FORM_URLENCODED payload = query_append(payload_params, oauth_params) return RequestProxy(method, url=request_url, body=payload, headers=headers)