Skip to content

Instantly share code, notes, and snippets.

@luwes
Last active September 27, 2016 18:26
Show Gist options
  • Save luwes/6d54a479651fde2b68bf3e890d089689 to your computer and use it in GitHub Desktop.
Save luwes/6d54a479651fde2b68bf3e890d089689 to your computer and use it in GitHub Desktop.
Tornado Vimeo Mixin OAuth2
class BaseHandler(RequestHandler):
COOKIE_NAME = 'user'
def get_current_user(self):
user_json = self.get_secure_cookie(self.COOKIE_NAME)
if not user_json:
return None
return json_decode(user_json)
class LoginHandler(BaseHandler, VimeoMixin):
async def get(self):
my_url = (self.request.protocol + "://" + self.request.host + "/login")
api_state = self.get_secure_cookie('api_state')
is_valid = api_state and api_state.decode('ascii') == self.get_argument('state', None)
if self.get_argument('code', None) and is_valid:
self.clear_cookie('api_state')
user = await self.get_authenticated_user(
redirect_uri=my_url,
client_id=options.vimeo_client_identifier,
client_secret=options.vimeo_client_secrets,
code=self.get_argument("code"),
)
self.set_secure_cookie(self.COOKIE_NAME, json_encode(user))
self.redirect(self.get_argument('next', '/'))
else:
state = base64.b64encode(os.urandom(10)).decode('ascii')
self.set_secure_cookie('api_state', state)
self.authorize_redirect(
redirect_uri=my_url,
client_id=options.vimeo_client_identifier,
scope=['public', 'private'],
extra_params={
'state': state,
}
)
import urllib
import functools
import base64
import urllib.parse as urllib_parse
import tornado.ioloop
import tornado.web
import tornado.auth
import tornado.httpclient
import tornado.escape
import tornado.httputil
import logging
class VimeoMixin(tornado.auth.OAuth2Mixin):
""" Vimeo OAuth Mixin, based on FacebookGraphMixin
"""
_OAUTH_AUTHORIZE_URL = 'https://api.vimeo.com/oauth/authorize'
_OAUTH_ACCESS_TOKEN_URL = 'https://api.vimeo.com/oauth/access_token'
_OAUTH_NO_CALLBACKS = False
_API_URL = 'https://api.vimeo.com'
@tornado.auth._auth_return_future
def get_authenticated_user(self, redirect_uri, client_id, client_secret,
code, callback, extra_fields=None):
""" Handles the login for Vimeo, queries /user and returns a user object
"""
http = tornado.httpclient.AsyncHTTPClient()
body = urllib_parse.urlencode({
"redirect_uri": redirect_uri,
"code": code,
"client_id": client_id,
"client_secret": client_secret,
"grant_type": "authorization_code",
})
fields = set([ 'name', 'link', 'pictures'])
if extra_fields:
fields.update(extra_fields)
fn = functools.partial(self._on_access_token, redirect_uri, client_id,
client_secret, callback, fields)
http.fetch(self._OAUTH_ACCESS_TOKEN_URL, fn, method="POST", body=body)
def _on_access_token(self, redirect_uri, client_id, client_secret,
future, fields, response):
"""Callback function for the exchange to the access token."""
if response.error:
future.set_exception(tornado.auth.AuthError('Vimeo auth error: %s' % str(response)))
return
body = tornado.escape.json_decode(response.body)
#future.set_result(args)
self._on_get_user_info(future, body, fields, body['user'])
def _on_get_user_info(self, future, session, fields, user):
if user is None:
future.set_result(None)
return
fieldmap = {}
for field in fields:
fieldmap[field] = user.get(field)
fieldmap.update({"access_token": session["access_token"]})
future.set_result(fieldmap)
@tornado.auth._auth_return_future
def vimeo_request(self, path, callback, access_token=None,
post_args=None, **args):
url = self._API_URL + path
oauth_future = self.oauth2_request(url, access_token=access_token,
post_args=post_args, **args)
tornado.concurrent.chain_future(oauth_future, callback)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment