Skip to content

Commit 81326a0

Browse files
committed
fix encoding of non-ascii data into postdata, really fixes joestump#48 this time (comes with test)
1 parent 1178db3 commit 81326a0

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

oauth2/__init__.py

+23-4
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,26 @@ def to_unicode_optional_iterator(x):
135135
assert 'is not iterable' in str(e)
136136
return x
137137
else:
138-
return [ to_unicode(e) for e in l ]
138+
return [ to_unicode(e) for e in l ]
139+
140+
def to_utf8_optional_iterator(x):
141+
"""
142+
Raise TypeError if x is a str or if x is an iterable which
143+
contains a str.
144+
"""
145+
if isinstance(x, basestring):
146+
return to_utf8(x)
147+
148+
try:
149+
l = list(x)
150+
except TypeError, e:
151+
assert 'is not iterable' in str(e)
152+
return x
153+
else:
154+
return [ to_utf8_if_string(e) for e in l ]
139155

140156
def escape(s):
141157
"""Escape a URL including any /."""
142-
s = to_unicode(s)
143158
return urllib.quote(s.encode('utf-8'), safe='~')
144159

145160
def generate_timestamp():
@@ -386,10 +401,14 @@ def to_header(self, realm=''):
386401

387402
def to_postdata(self):
388403
"""Serialize as post data for a POST request."""
404+
d = {}
405+
for k, v in self.iteritems():
406+
d[k.encode('utf-8')] = to_utf8_optional_iterator(v)
407+
389408
# tell urlencode to deal with sequence values and map them correctly
390409
# to resulting querystring. for example self["k"] = ["v1", "v2"] will
391410
# result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D
392-
return urllib.urlencode(self, True).replace('+', '%20')
411+
return urllib.urlencode(d, True).replace('+', '%20')
393412

394413
def to_url(self):
395414
"""Serialize as a URL for a GET request."""
@@ -797,7 +816,7 @@ def check(self, request, consumer, token, signature):
797816

798817
class SignatureMethod_HMAC_SHA1(SignatureMethod):
799818
name = 'HMAC-SHA1'
800-
819+
801820
def signing_base(self, request, consumer, token):
802821
if not hasattr(request, 'normalized_url') or request.normalized_url is None:
803822
raise ValueError("Base URL for request is not set.")

tests/test_oauth.py

+18
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,24 @@ def test_to_header(self):
408408
for key, val in res.items():
409409
self.assertEquals(val, params.get(key))
410410

411+
def test_to_postdata_nonascii(self):
412+
realm = "http://sp.example.com/"
413+
414+
params = {
415+
'nonasciithing': u'q\xbfu\xe9 ,aasp u?..a.s',
416+
'oauth_version': "1.0",
417+
'oauth_nonce': "4572616e48616d6d65724c61686176",
418+
'oauth_timestamp': "137131200",
419+
'oauth_consumer_key': "0685bd9184jfhq22",
420+
'oauth_signature_method': "HMAC-SHA1",
421+
'oauth_token': "ad180jjd733klru7",
422+
'oauth_signature': "wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",
423+
}
424+
425+
req = oauth.Request("GET", realm, params)
426+
427+
self.failUnlessReallyEqual(req.to_postdata(), 'nonasciithing=q%C2%BFu%C3%A9%20%2Caasp%20u%3F..a.s&oauth_nonce=4572616e48616d6d65724c61686176&oauth_timestamp=137131200&oauth_consumer_key=0685bd9184jfhq22&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_token=ad180jjd733klru7&oauth_signature=wOJIO9A2W5mFwDgiDvZbTSMK%252FPY%253D')
428+
411429
def test_to_postdata(self):
412430
realm = "http://sp.example.com/"
413431

0 commit comments

Comments
 (0)