-
-
Save cloudaice/5565236 to your computer and use it in GitHub Desktop.
Revisions
-
James Casbon revised this gist
Jun 26, 2012 . 1 changed file with 62 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,62 @@ import tornado.ioloop import tornado.web import tornado.escape import tornado.options import tornado.httputil import jinja2 import pyjade.compiler import coffeescript import markdown import github class GithubLoginHandler(tornado.web.RequestHandler, github.GithubMixin): _OAUTH_REDIRECT_URL = 'http://localhost:8888/auth/github' @tornado.web.asynchronous def get(self): # we can append next to the redirect uri, so the user gets the # correct URL on login redirect_uri = tornado.httputil.url_concat( self._OAUTH_REDIRECT_URL, {'next': self.get_argument('next', '/')}) # if we have a code, we have been authorized so we can log in if self.get_argument("code", False): self.get_authenticated_user( redirect_uri=redirect_uri, client_id=self.settings["github_client_id"], client_secret=self.settings["github_secret"], code=self.get_argument("code"), callback=self.async_callback(self._on_login) ) return # otherwise we need to request an authorization code self.authorize_redirect( redirect_uri=redirect_uri, client_id=self.settings["github_client_id"], extra_params={"scope": self.settings['github_scope'], "foo":1}) def _on_login(self, user): """ This handles the user object from the login request """ if user: logging.info('logged in user from github: ' + str(user)) self.set_secure_cookie("user", tornado.escape.json_encode(user)) else: self.clear_cookie("user") self.redirect(self.get_argument("next","/")) class GistLister(BaseHandler, github.GithubMixin): @tornado.web.authenticated @tornado.web.asynchronous def get(self): self.github_request( '/gists', self._on_get_gists, access_token=self.current_user['access_token']) def _on_get_gists(self, gists): self.render('gists.jade', gists=gists) -
James Casbon revised this gist
Jun 26, 2012 . 1 changed file with 16 additions and 43 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,11 +4,12 @@ import tornado.auth import tornado.httpclient import tornado.escape import tornado.httputil import logging class GithubMixin(tornado.auth.OAuth2Mixin): """ Github OAuth Mixin, based on FacebookGraphMixin """ _OAUTH_AUTHORIZE_URL = 'https://github.com/login/oauth/authorize' @@ -19,6 +20,7 @@ def get_authenticated_user(self, redirect_uri, client_id, client_secret, code, callback, extra_fields=None): """ Handles the login for Github, queries /user and returns a user object """ logging.debug('gau ' + redirect_uri) http = tornado.httpclient.AsyncHTTPClient() args = { "redirect_uri": redirect_uri, @@ -29,13 +31,13 @@ def get_authenticated_user(self, redirect_uri, client_id, client_secret, 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, callback, fields, response): """ callback for authentication url, if successful get the user details """ if response.error: logging.warning('Github auth error: %s' % str(response)) callback(None) return @@ -59,23 +61,29 @@ def _on_access_token(self, redirect_uri, client_id, client_secret, def _on_get_user_info(self, callback, session, user): """ callback for github request /user to create a user """ logging.debug('user data from github ' + str(user)) if user is None: callback(None) return callback({ "login": user["login"], "name": user["name"], "email": user["email"], "access_token": session["access_token"], }) def github_request(self, path, callback, access_token=None, method='GET', body=None, **args): """ Makes a github API request, hands callback the parsed data """ args["access_token"] = access_token url = tornado.httputil.url_concat(self._API_URL + path, args) logging.debug('request to ' + url) http = tornado.httpclient.AsyncHTTPClient() if body is not None: body = tornado.escape.json_encode(body) logging.debug('body is' + body) http.fetch(url, callback=self.async_callback( self._parse_response, callback), method=method, body=body) def _parse_response(self, callback, response): """ Parse the JSON from the API """ @@ -97,39 +105,4 @@ def _parse_response(self, callback, response): callback(json) -
James Casbon created this gist
Jun 20, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,135 @@ import urllib import tornado.ioloop import tornado.web import tornado.auth import tornado.httpclient import tornado.escape import logging class GithubMixin(tornado.auth.OAuth2Mixin): """ Github OAuth Mixin """ _OAUTH_AUTHORIZE_URL = 'https://github.com/login/oauth/authorize' _OAUTH_ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token' _API_URL = 'https://api.github.com' def get_authenticated_user(self, redirect_uri, client_id, client_secret, code, callback, extra_fields=None): """ Handles the login for Github, queries /user and returns a user object """ http = tornado.httpclient.AsyncHTTPClient() args = { "redirect_uri": redirect_uri, "code": code, "client_id": client_id, "client_secret": client_secret, } http.fetch(self._oauth_request_token_url(**args), self.async_callback(self._on_access_token, redirect_uri, client_id, client_secret, callback, extra_fields)) def _on_access_token(self, redirect_uri, client_id, client_secret, callback, fields, response): """ callback for authentication url, if successful get the user details """ if response.error: logging.warning('Facebook auth error: %s' % str(response)) callback(None) return args = tornado.escape.parse_qs_bytes( tornado.escape.native_str(response.body)) if 'error' in args: logging.error('oauth error ' + args['error'][-1]) raise Exception(args['error'][-1]) session = { "access_token": args["access_token"][-1], } self.github_request( method="/user", callback=self.async_callback( self._on_get_user_info, callback, session), access_token=session["access_token"], ) def _on_get_user_info(self, callback, session, user): """ callback for github request /user to create a user """ if user is None: callback(None) return callback({ "login": user["login"], "name": user["name"], "access_token": session["access_token"], }) def github_request(self, method, callback, access_token=None, **args): """ Makes a github API request, hands callback the parsed data """ args["access_token"] = access_token url = self._API_URL + method + '?' + urllib.urlencode(args) logging.warning('request to ' + url) http = tornado.httpclient.AsyncHTTPClient() http.fetch(url, callback=self.async_callback( self._parse_response, callback)) def _parse_response(self, callback, response): """ Parse the JSON from the API """ if response.error: logging.warning("HTTP error from Github: %s", response.error) callback(None) return try: json = tornado.escape.json_decode(response.body) except Exception: logging.warning("Invalid JSON from Github: %r", response.body) callback(None) return if isinstance(json, dict) and json.get("error_code"): logging.warning("Facebook error: %d: %r", json["error_code"], json.get("error_msg")) callback(None) return callback(json) class GithubLoginHandler(tornado.web.RequestHandler, GithubMixin): """ Example that uses the mixin to do auth """ @tornado.web.asynchronous def get(self): if self.get_argument("code", False): logging.warning('got code, getting authenticated user') self.get_authenticated_user( redirect_uri='http://localhost:8888/auth/github', client_id=self.settings["github_client_id"], client_secret=self.settings["github_secret"], code=self.get_argument("code"), callback=self.async_callback( self._on_login)) return logging.warning('getting a code via authorize_redirect') self.authorize_redirect(redirect_uri='http://localhost:8888/auth/github', client_id=self.settings["github_client_id"], extra_params={"scope": "gist"}) def _on_login(self, user): """ This handlers the user object from the login request """ logging.error(user) self.finish() application = tornado.web.Application([ (r"/auth/github", GithubLoginHandler), ], debug=True, github_client_id = '........', github_secret = '......') if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()