Skip to content

Instantly share code, notes, and snippets.

@roiavidan
Last active August 29, 2015 14:02
Show Gist options
  • Save roiavidan/6d1f12105f6d72e75123 to your computer and use it in GitHub Desktop.
Save roiavidan/6d1f12105f6d72e75123 to your computer and use it in GitHub Desktop.
import tornado.auth
import tornado.escape
import tornado.httpclient
###
### Windows Live OAuth2 authentication Mixin.
### Based on the FacebookGraphMixin code which ships with Tornado.
### For usage, see the Facebook example: http://tornado.readthedocs.org/en/stable/auth.html#facebook
###
class WindowsLiveOAuth2Mixin(tornado.auth.OAuth2Mixin):
_OAUTH_ACCESS_TOKEN_URL = "https://login.live.com/oauth20_token.srf?"
_OAUTH_AUTHORIZE_URL = "https://login.live.com/oauth20_authorize.srf?"
_WLIVE_BASE_URL = "https://apis.live.net/v5.0/me?"
def get_auth_http_client(self):
"""
Returns the `.AsyncHTTPClient` instance to be used for auth requests.
"""
return tornado.httpclient.AsyncHTTPClient()
@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 the Windows Live user, returning a user object.
"""
http = self.get_auth_http_client()
args = {
"redirect_uri": redirect_uri,
"code": code,
"client_id": client_id,
"client_secret": client_secret,
"extra_params": {"grant_type": "authorization_code"}
}
fields = set(['id', 'name', 'first_name', 'last_name', 'locale', 'gender'])
if extra_fields:
fields.update(extra_fields)
http.fetch(self._oauth_request_token_url(**args), self.async_callback(self._on_access_token, redirect_uri, client_id, client_secret, callback, fields))
def _on_access_token(self, redirect_uri, client_id, client_secret, future, fields, response):
"""
Got access token. Fetch user profile.
"""
if response.error:
future.set_exception(tornado.auth.AuthError('Windows Live auth error: %s' % str(response)))
return
args = tornado.escape.json_decode(response.body)
access_token = args["access_token"]
url = WindowsLiveLoginHandler._WLIVE_BASE_URL + "access_token=" + access_token
http = self.get_auth_http_client()
http.fetch(url, callback=self.async_callback(self._on_get_user_info, future, args, fields))
def _on_get_user_info(self, future, session, fields, response):
"""
Extract profile fields from response.
"""
if response.code != 200 or response.body is None:
future.set_result(None)
return
user = tornado.escape.json_decode(response.body)
fieldmap = {}
for field in fields:
fieldmap[field] = user.get(field)
fieldmap.update({"access_token": session["access_token"], "session_expires": session.get("expires_in")})
future.set_result(fieldmap)
@obeleh
Copy link

obeleh commented Jul 22, 2015

I think that line 52:

url = WindowsLiveLoginHandler._WLIVE_BASE_URL + "access_token=" + access_token

Should become:

url = self._WLIVE_BASE_URL + "access_token=" + access_token

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment