Skip to content

Commit 7f1da20

Browse files
authored
Merge pull request mediawiki-utilities#34 from mediawiki-utilities/fix_oauth_initiate_error
Fixes initiate decode error and adds tests.
2 parents 464030a + c38fa29 commit 7f1da20

File tree

3 files changed

+62
-26
lines changed

3 files changed

+62
-26
lines changed

mwoauth/functions.py

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@
4747
from .tokens import AccessToken, RequestToken
4848

4949

50-
def force_unicode(val):
50+
def force_unicode(val, encoding="unicode-escape"):
5151
if type(val) == text_type:
5252
return val
5353
else:
5454
if PY3:
55-
return str(val, "unicode-escape")
55+
return val.decode(encoding, errors="replace")
5656
else:
57-
return unicode(val, "unicode-escape")
57+
return unicode(val, encoding, errors="replace")
5858

5959

6060
def initiate(mw_uri, consumer_token, callback='oob',
@@ -89,37 +89,38 @@ def initiate(mw_uri, consumer_token, callback='oob',
8989
auth=auth,
9090
headers={'User-Agent': user_agent})
9191

92-
credentials = parse_qs(r.content)
92+
request_token = process_request_token(r.content)
93+
94+
params = {'title': "Special:OAuth/authenticate",
95+
'oauth_token': request_token.key,
96+
'oauth_consumer_key': consumer_token.key}
97+
98+
return (mw_uri + "?" + urlencode(params), request_token)
99+
100+
101+
def process_request_token(content):
102+
text_content = force_unicode(content, "utf8")
103+
if text_content.startswith(force_unicode("Error: ")):
104+
raise OAuthException(text_content[len("Error: "):])
105+
106+
credentials = parse_qs(text_content)
93107

94108
if credentials is None or credentials == {}:
95109
raise OAuthException(
96110
"Expected x-www-form-urlencoded response from " +
97111
"MediaWiki, but got something else: " +
98-
"{0}".format(repr(r.content)))
99-
100-
elif b('oauth_token') not in credentials or \
101-
b('oauth_token_secret') not in credentials:
102-
112+
"{0}".format(repr(text_content)))
113+
elif 'oauth_token' not in credentials or \
114+
'oauth_token_secret' not in credentials:
103115
raise OAuthException(
104116
"MediaWiki response lacks token information: "
105117
"{0}".format(repr(credentials)))
106-
107118
else:
108-
109-
request_token = RequestToken(
110-
credentials.get(b('oauth_token'))[0],
111-
credentials.get(b('oauth_token_secret'))[0]
119+
return RequestToken(
120+
credentials.get('oauth_token')[0],
121+
credentials.get('oauth_token_secret')[0]
112122
)
113123

114-
params = {'title': "Special:OAuth/authenticate",
115-
'oauth_token': request_token.key,
116-
'oauth_consumer_key': consumer_token.key}
117-
118-
return (
119-
mw_uri + "?" + urlencode(params),
120-
request_token
121-
)
122-
123124

124125
def complete(mw_uri, consumer_token, request_token, response_qs,
125126
user_agent=defaults.USER_AGENT):
@@ -249,13 +250,13 @@ def identify(mw_uri, consumer_token, access_token, leeway=10.0,
249250
resp = r.json()
250251
if 'error' in resp:
251252
raise OAuthException(
252-
"A MediaWiki API error occurred: {0}".format(resp['message']))
253-
except ValueError:
253+
"A MediaWiki API error occurred: {0}"
254+
.format(resp['message']))
255+
except ValueError as e:
254256
raise OAuthException(
255257
"An error occurred while trying to read json " +
256258
"content: {0}".format(e))
257259

258-
259260
# Decode json & stuff
260261
try:
261262
identity = jwt.decode(r.content, consumer_token.secret,

mwoauth/tests/__init__.py

Whitespace-only changes.

mwoauth/tests/test_functions.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- coding: UTF-8 -*-
2+
import pytest
3+
from six import PY3, b
4+
5+
from ..errors import OAuthException
6+
from ..functions import process_request_token
7+
8+
9+
def test_process_request_token():
10+
request_token = process_request_token(
11+
b("oauth_token=iamatoken&oauth_token_secret=iamasecret"))
12+
assert request_token.key == "iamatoken"
13+
assert request_token.secret == "iamasecret"
14+
15+
16+
def test_process_request_token_errors():
17+
if PY3:
18+
text = "Error: Произошла ошибка в протоколе OAuth: " + \
19+
"Invalid consumer key"
20+
content = bytes(text, "utf-8")
21+
else:
22+
content = "Error: Произошла ошибка в протоколе OAuth: " + \
23+
"Invalid consumer key"
24+
text = unicode(content, "utf-8")
25+
with pytest.raises(OAuthException, match=text[len("Error: "):]):
26+
process_request_token(content)
27+
28+
with pytest.raises(OAuthException, match="I am an error"):
29+
process_request_token("Error: I am an error")
30+
31+
with pytest.raises(OAuthException, match=r"Expected x-www-form-.*"):
32+
process_request_token("TOTAL NONSENSE")
33+
34+
with pytest.raises(OAuthException, match=r"MediaWiki response lacks.*"):
35+
process_request_token("foo=bar&baz=bum")

0 commit comments

Comments
 (0)