提交 ba3a0e9d 编写于 作者: B Ben Darnell

auth: Add deprecation warnings for anything using auth_return_future

上级 59a8f663
...@@ -73,6 +73,7 @@ import hashlib ...@@ -73,6 +73,7 @@ import hashlib
import hmac import hmac
import time import time
import uuid import uuid
import warnings
from tornado.concurrent import (Future, return_future, chain_future, from tornado.concurrent import (Future, return_future, chain_future,
future_set_exc_info, future_set_exc_info,
...@@ -113,6 +114,9 @@ def _auth_return_future(f): ...@@ -113,6 +114,9 @@ def _auth_return_future(f):
Note that when using this decorator the ``callback`` parameter Note that when using this decorator the ``callback`` parameter
inside the function will actually be a future. inside the function will actually be a future.
.. deprecated:: 5.1
Will be removed in 6.0.
""" """
replacer = ArgReplacer(f, 'callback') replacer = ArgReplacer(f, 'callback')
...@@ -121,6 +125,8 @@ def _auth_return_future(f): ...@@ -121,6 +125,8 @@ def _auth_return_future(f):
future = Future() future = Future()
callback, args, kwargs = replacer.replace(future, args, kwargs) callback, args, kwargs = replacer.replace(future, args, kwargs)
if callback is not None: if callback is not None:
warnings.warn("callback arguments are deprecated, use the returned Future instead",
DeprecationWarning)
future.add_done_callback( future.add_done_callback(
functools.partial(_auth_future_to_callback, callback)) functools.partial(_auth_future_to_callback, callback))
...@@ -179,6 +185,11 @@ class OpenIdMixin(object): ...@@ -179,6 +185,11 @@ class OpenIdMixin(object):
is present and `authenticate_redirect` if it is not). is present and `authenticate_redirect` if it is not).
The result of this method will generally be used to set a cookie. The result of this method will generally be used to set a cookie.
.. deprecated:: 5.1
The ``callback`` argument is deprecated and will be removed in 6.0.
Use the returned awaitable object instead.
""" """
# Verify the OpenID response via direct request to the OP # Verify the OpenID response via direct request to the OP
args = dict((k, v[-1]) for k, v in self.request.arguments.items()) args = dict((k, v[-1]) for k, v in self.request.arguments.items())
...@@ -381,6 +392,11 @@ class OAuthMixin(object): ...@@ -381,6 +392,11 @@ class OAuthMixin(object):
requests to this service on behalf of the user. The dictionary will requests to this service on behalf of the user. The dictionary will
also contain other fields such as ``name``, depending on the service also contain other fields such as ``name``, depending on the service
used. used.
.. deprecated:: 5.1
The ``callback`` argument is deprecated and will be removed in 6.0.
Use the returned awaitable object instead.
""" """
future = callback future = callback
request_key = escape.utf8(self.get_argument("oauth_token")) request_key = escape.utf8(self.get_argument("oauth_token"))
...@@ -648,6 +664,11 @@ class OAuth2Mixin(object): ...@@ -648,6 +664,11 @@ class OAuth2Mixin(object):
:hide: :hide:
.. versionadded:: 4.3 .. versionadded:: 4.3
.. deprecated:: 5.1
The ``callback`` argument is deprecated and will be removed in 6.0.
Use the returned awaitable object instead.
""" """
all_args = {} all_args = {}
if access_token: if access_token:
...@@ -781,6 +802,10 @@ class TwitterMixin(OAuthMixin): ...@@ -781,6 +802,10 @@ class TwitterMixin(OAuthMixin):
.. testoutput:: .. testoutput::
:hide: :hide:
.. deprecated:: 5.1
The ``callback`` argument is deprecated and will be removed in 6.0.
Use the returned awaitable object instead.
""" """
if path.startswith('http:') or path.startswith('https:'): if path.startswith('http:') or path.startswith('https:'):
# Raw urls are useful for e.g. search which doesn't follow the # Raw urls are useful for e.g. search which doesn't follow the
...@@ -896,6 +921,10 @@ class GoogleOAuth2Mixin(OAuth2Mixin): ...@@ -896,6 +921,10 @@ class GoogleOAuth2Mixin(OAuth2Mixin):
.. testoutput:: .. testoutput::
:hide: :hide:
.. deprecated:: 5.1
The ``callback`` argument is deprecated and will be removed in 6.0.
Use the returned awaitable object instead.
""" # noqa: E501 """ # noqa: E501
http = self.get_auth_http_client() http = self.get_auth_http_client()
body = urllib_parse.urlencode({ body = urllib_parse.urlencode({
...@@ -973,6 +1002,11 @@ class FacebookGraphMixin(OAuth2Mixin): ...@@ -973,6 +1002,11 @@ class FacebookGraphMixin(OAuth2Mixin):
.. versionchanged:: 4.5 .. versionchanged:: 4.5
The ``session_expires`` field was updated to support changes made to the The ``session_expires`` field was updated to support changes made to the
Facebook API in March 2017. Facebook API in March 2017.
.. deprecated:: 5.1
The ``callback`` argument is deprecated and will be removed in 6.0.
Use the returned awaitable object instead.
""" """
http = self.get_auth_http_client() http = self.get_auth_http_client()
args = { args = {
...@@ -991,6 +1025,7 @@ class FacebookGraphMixin(OAuth2Mixin): ...@@ -991,6 +1025,7 @@ class FacebookGraphMixin(OAuth2Mixin):
functools.partial(self._on_access_token, redirect_uri, client_id, functools.partial(self._on_access_token, redirect_uri, client_id,
client_secret, callback, fields)) client_secret, callback, fields))
@gen.coroutine
def _on_access_token(self, redirect_uri, client_id, client_secret, def _on_access_token(self, redirect_uri, client_id, client_secret,
future, fields, response): future, fields, response):
if response.error: if response.error:
...@@ -1003,10 +1038,8 @@ class FacebookGraphMixin(OAuth2Mixin): ...@@ -1003,10 +1038,8 @@ class FacebookGraphMixin(OAuth2Mixin):
"expires_in": args.get("expires_in") "expires_in": args.get("expires_in")
} }
self.facebook_request( user = yield self.facebook_request(
path="/me", path="/me",
callback=functools.partial(
self._on_get_user_info, future, session, fields),
access_token=session["access_token"], access_token=session["access_token"],
appsecret_proof=hmac.new(key=client_secret.encode('utf8'), appsecret_proof=hmac.new(key=client_secret.encode('utf8'),
msg=session["access_token"].encode('utf8'), msg=session["access_token"].encode('utf8'),
...@@ -1014,7 +1047,6 @@ class FacebookGraphMixin(OAuth2Mixin): ...@@ -1014,7 +1047,6 @@ class FacebookGraphMixin(OAuth2Mixin):
fields=",".join(fields) fields=",".join(fields)
) )
def _on_get_user_info(self, future, session, fields, user):
if user is None: if user is None:
future_set_result_unless_cancelled(future, None) future_set_result_unless_cancelled(future, None)
return return
...@@ -1080,6 +1112,11 @@ class FacebookGraphMixin(OAuth2Mixin): ...@@ -1080,6 +1112,11 @@ class FacebookGraphMixin(OAuth2Mixin):
.. versionchanged:: 3.1 .. versionchanged:: 3.1
Added the ability to override ``self._FACEBOOK_BASE_URL``. Added the ability to override ``self._FACEBOOK_BASE_URL``.
.. deprecated:: 5.1
The ``callback`` argument is deprecated and will be removed in 6.0.
Use the returned awaitable object instead.
""" """
url = self._FACEBOOK_BASE_URL + path url = self._FACEBOOK_BASE_URL + path
# Thanks to the _auth_return_future decorator, our "callback" # Thanks to the _auth_return_future decorator, our "callback"
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
import warnings
from tornado.auth import ( from tornado.auth import (
AuthError, OpenIdMixin, OAuthMixin, OAuth2Mixin, AuthError, OpenIdMixin, OAuthMixin, OAuth2Mixin,
GoogleOAuth2Mixin, FacebookGraphMixin, TwitterMixin, GoogleOAuth2Mixin, FacebookGraphMixin, TwitterMixin,
...@@ -19,16 +21,18 @@ from tornado.testing import AsyncHTTPTestCase, ExpectLog ...@@ -19,16 +21,18 @@ from tornado.testing import AsyncHTTPTestCase, ExpectLog
from tornado.web import RequestHandler, Application, asynchronous, HTTPError from tornado.web import RequestHandler, Application, asynchronous, HTTPError
class OpenIdClientLoginHandler(RequestHandler, OpenIdMixin): class OpenIdClientLoginHandlerLegacy(RequestHandler, OpenIdMixin):
def initialize(self, test): def initialize(self, test):
self._OPENID_ENDPOINT = test.get_url('/openid/server/authenticate') self._OPENID_ENDPOINT = test.get_url('/openid/server/authenticate')
@asynchronous @asynchronous
def get(self): def get(self):
if self.get_argument('openid.mode', None): if self.get_argument('openid.mode', None):
self.get_authenticated_user( with warnings.catch_warnings():
self.on_user, http_client=self.settings['http_client']) warnings.simplefilter('ignore', DeprecationWarning)
return self.get_authenticated_user(
self.on_user, http_client=self.settings['http_client'])
return
res = self.authenticate_redirect() res = self.authenticate_redirect()
assert isinstance(res, Future) assert isinstance(res, Future)
assert res.done() assert res.done()
...@@ -39,6 +43,23 @@ class OpenIdClientLoginHandler(RequestHandler, OpenIdMixin): ...@@ -39,6 +43,23 @@ class OpenIdClientLoginHandler(RequestHandler, OpenIdMixin):
self.finish(user) self.finish(user)
class OpenIdClientLoginHandler(RequestHandler, OpenIdMixin):
def initialize(self, test):
self._OPENID_ENDPOINT = test.get_url('/openid/server/authenticate')
@gen.coroutine
def get(self):
if self.get_argument('openid.mode', None):
user = yield self.get_authenticated_user(http_client=self.settings['http_client'])
if user is None:
raise Exception("user is None")
self.finish(user)
return
res = self.authenticate_redirect()
assert isinstance(res, Future)
assert res.done()
class OpenIdServerAuthenticateHandler(RequestHandler): class OpenIdServerAuthenticateHandler(RequestHandler):
def post(self): def post(self):
if self.get_argument('openid.mode') != 'check_authentication': if self.get_argument('openid.mode') != 'check_authentication':
...@@ -46,7 +67,7 @@ class OpenIdServerAuthenticateHandler(RequestHandler): ...@@ -46,7 +67,7 @@ class OpenIdServerAuthenticateHandler(RequestHandler):
self.write('is_valid:true') self.write('is_valid:true')
class OAuth1ClientLoginHandler(RequestHandler, OAuthMixin): class OAuth1ClientLoginHandlerLegacy(RequestHandler, OAuthMixin):
def initialize(self, test, version): def initialize(self, test, version):
self._OAUTH_VERSION = version self._OAUTH_VERSION = version
self._OAUTH_REQUEST_TOKEN_URL = test.get_url('/oauth1/server/request_token') self._OAUTH_REQUEST_TOKEN_URL = test.get_url('/oauth1/server/request_token')
...@@ -59,8 +80,10 @@ class OAuth1ClientLoginHandler(RequestHandler, OAuthMixin): ...@@ -59,8 +80,10 @@ class OAuth1ClientLoginHandler(RequestHandler, OAuthMixin):
@asynchronous @asynchronous
def get(self): def get(self):
if self.get_argument('oauth_token', None): if self.get_argument('oauth_token', None):
self.get_authenticated_user( with warnings.catch_warnings():
self.on_user, http_client=self.settings['http_client']) warnings.simplefilter('ignore', DeprecationWarning)
self.get_authenticated_user(
self.on_user, http_client=self.settings['http_client'])
return return
res = self.authorize_redirect(http_client=self.settings['http_client']) res = self.authorize_redirect(http_client=self.settings['http_client'])
assert isinstance(res, Future) assert isinstance(res, Future)
...@@ -78,6 +101,34 @@ class OAuth1ClientLoginHandler(RequestHandler, OAuthMixin): ...@@ -78,6 +101,34 @@ class OAuth1ClientLoginHandler(RequestHandler, OAuthMixin):
callback(dict(email='foo@example.com')) callback(dict(email='foo@example.com'))
class OAuth1ClientLoginHandler(RequestHandler, OAuthMixin):
def initialize(self, test, version):
self._OAUTH_VERSION = version
self._OAUTH_REQUEST_TOKEN_URL = test.get_url('/oauth1/server/request_token')
self._OAUTH_AUTHORIZE_URL = test.get_url('/oauth1/server/authorize')
self._OAUTH_ACCESS_TOKEN_URL = test.get_url('/oauth1/server/access_token')
def _oauth_consumer_token(self):
return dict(key='asdf', secret='qwer')
@gen.coroutine
def get(self):
if self.get_argument('oauth_token', None):
user = yield self.get_authenticated_user(http_client=self.settings['http_client'])
if user is None:
raise Exception("user is None")
self.finish(user)
return
yield self.authorize_redirect(http_client=self.settings['http_client'])
def _oauth_get_user(self, access_token, callback):
if self.get_argument('fail_in_get_user', None):
raise Exception("failing in get_user")
if access_token != dict(key='uiop', secret='5678'):
raise Exception("incorrect access token %r" % access_token)
callback(dict(email='foo@example.com'))
class OAuth1ClientLoginCoroutineHandler(OAuth1ClientLoginHandler): class OAuth1ClientLoginCoroutineHandler(OAuth1ClientLoginHandler):
"""Replaces OAuth1ClientLoginCoroutineHandler's get() with a coroutine.""" """Replaces OAuth1ClientLoginCoroutineHandler's get() with a coroutine."""
@gen.coroutine @gen.coroutine
...@@ -172,7 +223,7 @@ class TwitterClientHandler(RequestHandler, TwitterMixin): ...@@ -172,7 +223,7 @@ class TwitterClientHandler(RequestHandler, TwitterMixin):
return self.settings['http_client'] return self.settings['http_client']
class TwitterClientLoginHandler(TwitterClientHandler): class TwitterClientLoginHandlerLegacy(TwitterClientHandler):
@asynchronous @asynchronous
def get(self): def get(self):
if self.get_argument("oauth_token", None): if self.get_argument("oauth_token", None):
...@@ -186,6 +237,18 @@ class TwitterClientLoginHandler(TwitterClientHandler): ...@@ -186,6 +237,18 @@ class TwitterClientLoginHandler(TwitterClientHandler):
self.finish(user) self.finish(user)
class TwitterClientLoginHandler(TwitterClientHandler):
@gen.coroutine
def get(self):
if self.get_argument("oauth_token", None):
user = yield self.get_authenticated_user()
if user is None:
raise Exception("user is None")
self.finish(user)
return
yield self.authorize_redirect()
class TwitterClientLoginGenEngineHandler(TwitterClientHandler): class TwitterClientLoginGenEngineHandler(TwitterClientHandler):
@asynchronous @asynchronous
@gen.engine @gen.engine
...@@ -211,15 +274,17 @@ class TwitterClientLoginGenCoroutineHandler(TwitterClientHandler): ...@@ -211,15 +274,17 @@ class TwitterClientLoginGenCoroutineHandler(TwitterClientHandler):
yield self.authorize_redirect() yield self.authorize_redirect()
class TwitterClientShowUserHandler(TwitterClientHandler): class TwitterClientShowUserHandlerLegacy(TwitterClientHandler):
@asynchronous @asynchronous
@gen.engine @gen.engine
def get(self): def get(self):
# TODO: would be nice to go through the login flow instead of # TODO: would be nice to go through the login flow instead of
# cheating with a hard-coded access token. # cheating with a hard-coded access token.
response = yield gen.Task(self.twitter_request, with warnings.catch_warnings():
'/users/show/%s' % self.get_argument('name'), warnings.simplefilter('ignore', DeprecationWarning)
access_token=dict(key='hjkl', secret='vbnm')) response = yield gen.Task(self.twitter_request,
'/users/show/%s' % self.get_argument('name'),
access_token=dict(key='hjkl', secret='vbnm'))
if response is None: if response is None:
self.set_status(500) self.set_status(500)
self.finish('error from twitter request') self.finish('error from twitter request')
...@@ -227,6 +292,22 @@ class TwitterClientShowUserHandler(TwitterClientHandler): ...@@ -227,6 +292,22 @@ class TwitterClientShowUserHandler(TwitterClientHandler):
self.finish(response) self.finish(response)
class TwitterClientShowUserHandler(TwitterClientHandler):
@gen.coroutine
def get(self):
# TODO: would be nice to go through the login flow instead of
# cheating with a hard-coded access token.
try:
response = yield self.twitter_request(
'/users/show/%s' % self.get_argument('name'),
access_token=dict(key='hjkl', secret='vbnm'))
except AuthError:
self.set_status(500)
self.finish('error from twitter request')
else:
self.finish(response)
class TwitterClientShowUserFutureHandler(TwitterClientHandler): class TwitterClientShowUserFutureHandler(TwitterClientHandler):
@asynchronous @asynchronous
@gen.engine @gen.engine
...@@ -279,12 +360,17 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -279,12 +360,17 @@ class AuthTest(AsyncHTTPTestCase):
return Application( return Application(
[ [
# test endpoints # test endpoints
('/legacy/openid/client/login', OpenIdClientLoginHandlerLegacy, dict(test=self)),
('/openid/client/login', OpenIdClientLoginHandler, dict(test=self)), ('/openid/client/login', OpenIdClientLoginHandler, dict(test=self)),
('/legacy/oauth10/client/login', OAuth1ClientLoginHandlerLegacy,
dict(test=self, version='1.0')),
('/oauth10/client/login', OAuth1ClientLoginHandler, ('/oauth10/client/login', OAuth1ClientLoginHandler,
dict(test=self, version='1.0')), dict(test=self, version='1.0')),
('/oauth10/client/request_params', ('/oauth10/client/request_params',
OAuth1ClientRequestParametersHandler, OAuth1ClientRequestParametersHandler,
dict(version='1.0')), dict(version='1.0')),
('/legacy/oauth10a/client/login', OAuth1ClientLoginHandlerLegacy,
dict(test=self, version='1.0a')),
('/oauth10a/client/login', OAuth1ClientLoginHandler, ('/oauth10a/client/login', OAuth1ClientLoginHandler,
dict(test=self, version='1.0a')), dict(test=self, version='1.0a')),
('/oauth10a/client/login_coroutine', ('/oauth10a/client/login_coroutine',
...@@ -297,11 +383,14 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -297,11 +383,14 @@ class AuthTest(AsyncHTTPTestCase):
('/facebook/client/login', FacebookClientLoginHandler, dict(test=self)), ('/facebook/client/login', FacebookClientLoginHandler, dict(test=self)),
('/legacy/twitter/client/login', TwitterClientLoginHandlerLegacy, dict(test=self)),
('/twitter/client/login', TwitterClientLoginHandler, dict(test=self)), ('/twitter/client/login', TwitterClientLoginHandler, dict(test=self)),
('/twitter/client/login_gen_engine', ('/twitter/client/login_gen_engine',
TwitterClientLoginGenEngineHandler, dict(test=self)), TwitterClientLoginGenEngineHandler, dict(test=self)),
('/twitter/client/login_gen_coroutine', ('/twitter/client/login_gen_coroutine',
TwitterClientLoginGenCoroutineHandler, dict(test=self)), TwitterClientLoginGenCoroutineHandler, dict(test=self)),
('/legacy/twitter/client/show_user',
TwitterClientShowUserHandlerLegacy, dict(test=self)),
('/twitter/client/show_user', ('/twitter/client/show_user',
TwitterClientShowUserHandler, dict(test=self)), TwitterClientShowUserHandler, dict(test=self)),
('/twitter/client/show_user_future', ('/twitter/client/show_user_future',
...@@ -325,6 +414,21 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -325,6 +414,21 @@ class AuthTest(AsyncHTTPTestCase):
facebook_api_key='test_facebook_api_key', facebook_api_key='test_facebook_api_key',
facebook_secret='test_facebook_secret') facebook_secret='test_facebook_secret')
def test_openid_redirect_legacy(self):
response = self.fetch('/legacy/openid/client/login', follow_redirects=False)
self.assertEqual(response.code, 302)
self.assertTrue(
'/openid/server/authenticate?' in response.headers['Location'])
def test_openid_get_user_legacy(self):
response = self.fetch('/legacy/openid/client/login?openid.mode=blah'
'&openid.ns.ax=http://openid.net/srv/ax/1.0'
'&openid.ax.type.email=http://axschema.org/contact/email'
'&openid.ax.value.email=foo@example.com')
response.rethrow()
parsed = json_decode(response.body)
self.assertEqual(parsed["email"], "foo@example.com")
def test_openid_redirect(self): def test_openid_redirect(self):
response = self.fetch('/openid/client/login', follow_redirects=False) response = self.fetch('/openid/client/login', follow_redirects=False)
self.assertEqual(response.code, 302) self.assertEqual(response.code, 302)
...@@ -340,6 +444,16 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -340,6 +444,16 @@ class AuthTest(AsyncHTTPTestCase):
parsed = json_decode(response.body) parsed = json_decode(response.body)
self.assertEqual(parsed["email"], "foo@example.com") self.assertEqual(parsed["email"], "foo@example.com")
def test_oauth10_redirect_legacy(self):
response = self.fetch('/legacy/oauth10/client/login', follow_redirects=False)
self.assertEqual(response.code, 302)
self.assertTrue(response.headers['Location'].endswith(
'/oauth1/server/authorize?oauth_token=zxcv'))
# the cookie is base64('zxcv')|base64('1234')
self.assertTrue(
'_oauth_request_token="enhjdg==|MTIzNA=="' in response.headers['Set-Cookie'],
response.headers['Set-Cookie'])
def test_oauth10_redirect(self): def test_oauth10_redirect(self):
response = self.fetch('/oauth10/client/login', follow_redirects=False) response = self.fetch('/oauth10/client/login', follow_redirects=False)
self.assertEqual(response.code, 302) self.assertEqual(response.code, 302)
...@@ -350,6 +464,15 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -350,6 +464,15 @@ class AuthTest(AsyncHTTPTestCase):
'_oauth_request_token="enhjdg==|MTIzNA=="' in response.headers['Set-Cookie'], '_oauth_request_token="enhjdg==|MTIzNA=="' in response.headers['Set-Cookie'],
response.headers['Set-Cookie']) response.headers['Set-Cookie'])
def test_oauth10_get_user_legacy(self):
response = self.fetch(
'/legacy/oauth10/client/login?oauth_token=zxcv',
headers={'Cookie': '_oauth_request_token=enhjdg==|MTIzNA=='})
response.rethrow()
parsed = json_decode(response.body)
self.assertEqual(parsed['email'], 'foo@example.com')
self.assertEqual(parsed['access_token'], dict(key='uiop', secret='5678'))
def test_oauth10_get_user(self): def test_oauth10_get_user(self):
response = self.fetch( response = self.fetch(
'/oauth10/client/login?oauth_token=zxcv', '/oauth10/client/login?oauth_token=zxcv',
...@@ -368,6 +491,25 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -368,6 +491,25 @@ class AuthTest(AsyncHTTPTestCase):
self.assertTrue('oauth_nonce' in parsed) self.assertTrue('oauth_nonce' in parsed)
self.assertTrue('oauth_signature' in parsed) self.assertTrue('oauth_signature' in parsed)
def test_oauth10a_redirect_legacy(self):
response = self.fetch('/legacy/oauth10a/client/login', follow_redirects=False)
self.assertEqual(response.code, 302)
self.assertTrue(response.headers['Location'].endswith(
'/oauth1/server/authorize?oauth_token=zxcv'))
# the cookie is base64('zxcv')|base64('1234')
self.assertTrue(
'_oauth_request_token="enhjdg==|MTIzNA=="' in response.headers['Set-Cookie'],
response.headers['Set-Cookie'])
def test_oauth10a_get_user_legacy(self):
response = self.fetch(
'/legacy/oauth10a/client/login?oauth_token=zxcv',
headers={'Cookie': '_oauth_request_token=enhjdg==|MTIzNA=='})
response.rethrow()
parsed = json_decode(response.body)
self.assertEqual(parsed['email'], 'foo@example.com')
self.assertEqual(parsed['access_token'], dict(key='uiop', secret='5678'))
def test_oauth10a_redirect(self): def test_oauth10a_redirect(self):
response = self.fetch('/oauth10a/client/login', follow_redirects=False) response = self.fetch('/oauth10a/client/login', follow_redirects=False)
self.assertEqual(response.code, 302) self.assertEqual(response.code, 302)
...@@ -428,6 +570,9 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -428,6 +570,9 @@ class AuthTest(AsyncHTTPTestCase):
'_oauth_request_token="enhjdg==|MTIzNA=="' in response.headers['Set-Cookie'], '_oauth_request_token="enhjdg==|MTIzNA=="' in response.headers['Set-Cookie'],
response.headers['Set-Cookie']) response.headers['Set-Cookie'])
def test_twitter_redirect_legacy(self):
self.base_twitter_redirect('/legacy/twitter/client/login')
def test_twitter_redirect(self): def test_twitter_redirect(self):
self.base_twitter_redirect('/twitter/client/login') self.base_twitter_redirect('/twitter/client/login')
...@@ -451,6 +596,18 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -451,6 +596,18 @@ class AuthTest(AsyncHTTPTestCase):
u'screen_name': u'foo', u'screen_name': u'foo',
u'username': u'foo'}) u'username': u'foo'})
def test_twitter_show_user_legacy(self):
response = self.fetch('/legacy/twitter/client/show_user?name=somebody')
response.rethrow()
self.assertEqual(json_decode(response.body),
{'name': 'Somebody', 'screen_name': 'somebody'})
def test_twitter_show_user_error_legacy(self):
with ExpectLog(gen_log, 'Error response HTTP 500'):
response = self.fetch('/legacy/twitter/client/show_user?name=error')
self.assertEqual(response.code, 500)
self.assertEqual(response.body, b'error from twitter request')
def test_twitter_show_user(self): def test_twitter_show_user(self):
response = self.fetch('/twitter/client/show_user?name=somebody') response = self.fetch('/twitter/client/show_user?name=somebody')
response.rethrow() response.rethrow()
...@@ -458,8 +615,7 @@ class AuthTest(AsyncHTTPTestCase): ...@@ -458,8 +615,7 @@ class AuthTest(AsyncHTTPTestCase):
{'name': 'Somebody', 'screen_name': 'somebody'}) {'name': 'Somebody', 'screen_name': 'somebody'})
def test_twitter_show_user_error(self): def test_twitter_show_user_error(self):
with ExpectLog(gen_log, 'Error response HTTP 500'): response = self.fetch('/twitter/client/show_user?name=error')
response = self.fetch('/twitter/client/show_user?name=error')
self.assertEqual(response.code, 500) self.assertEqual(response.code, 500)
self.assertEqual(response.body, b'error from twitter request') self.assertEqual(response.body, b'error from twitter request')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册