From 00b087a8a1ce4b94a9aa0196bb64ad7364246486 Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Wed, 11 Nov 2009 17:33:39 -0700 Subject: [PATCH 1/3] added missing argument to Client.set_signature_method (self is important ;-) ) --- oauth2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index 0f2791ab..72acb6ff 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -554,7 +554,7 @@ def __init__(self, consumer, token=None, cache=None, timeout=None, httplib2.Http.__init__(self, cache=cache, timeout=timeout, proxy_info=proxy_info) - def set_signature_method(method): + def set_signature_method(self, method): if not isinstance(method, SignatureMethod): raise ValueError("Invalid signature method.") From 53780ee6c0bd01a0e2763fa9520c7e65c1ab068d Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Wed, 13 Jan 2010 04:21:16 -0700 Subject: [PATCH 2/3] use doseq in urllib.urlencode to correctly encode sequence values. this is absolutely required for Client since querystring value that gets passed in via URI will pass through parse_qs and result in {"k": ["v1"]} for a single value. --- oauth2/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index b0f61fa5..1124d86e 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -309,7 +309,10 @@ def to_header(self, realm=''): def to_postdata(self): """Serialize as post data for a POST request.""" - return urllib.urlencode(self) + # tell urlencode to deal with sequence values and map them correctly + # to resulting querystring. for example self["k"] = ["v1", "v2"] will + # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D + return urllib.urlencode(self, True) def to_url(self): """Serialize as a URL for a GET request.""" @@ -325,7 +328,7 @@ def get_parameter(self, parameter): def get_normalized_parameters(self): """Return a string that contains the parameters that must be signed.""" items = [(k, v) for k, v in self.items() if k != 'oauth_signature'] - encoded_str = urllib.urlencode(sorted(items)) + encoded_str = urllib.urlencode(sorted(items), True) # Encode signature parameters per Oauth Core 1.0 protocol # spec draft 7, section 3.6 # (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6) From 82a05f96878f187f67c1af44befc1bec562e5c1f Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Thu, 14 Jan 2010 20:48:47 -0700 Subject: [PATCH 3/3] Added Client.request(..., force_auth_header=False) to force sending Authorization header This is required by LinkedIn API at this time. --- oauth2/__init__.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index 1124d86e..a965fc71 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -309,11 +309,14 @@ def to_header(self, realm=''): def to_postdata(self): """Serialize as post data for a POST request.""" + return self.encode_postdata(self) + + def encode_postdata(self, data): # tell urlencode to deal with sequence values and map them correctly # to resulting querystring. for example self["k"] = ["v1", "v2"] will # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D - return urllib.urlencode(self, True) - + return urllib.urlencode(data, True) + def to_url(self): """Serialize as a URL for a GET request.""" return '%s?%s' % (self.url, self.to_postdata()) @@ -574,7 +577,8 @@ def set_signature_method(self, method): self.method = method def request(self, uri, method="GET", body=None, headers=None, - redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None): + redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None, + force_auth_header=False): if not isinstance(headers, dict): headers = {} @@ -592,13 +596,23 @@ def request(self, uri, method="GET", body=None, headers=None, req.sign_request(self.method, self.consumer, self.token) + if force_auth_header: + # ensure we always send Authorization + headers.update(req.to_header()) + if method == "POST": - body = req.to_postdata() + if not force_auth_header: + body = req.to_postdata() + else: + body = req.encode_postdata(req.get_nonoauth_parameters()) headers['Content-Type'] = 'application/x-www-form-urlencoded' elif method == "GET": - uri = req.to_url() + if not force_auth_header: + uri = req.to_url() else: - headers.update(req.to_header()) + if not force_auth_header: + # don't call update twice. + headers.update(req.to_header()) return httplib2.Http.request(self, uri, method=method, body=body, headers=headers, redirections=redirections,