Skip to content

Instantly share code, notes, and snippets.

@cloudaice
Forked from jamescasbon/example.py
Created May 12, 2013 22:46
Show Gist options
  • Save cloudaice/5565236 to your computer and use it in GitHub Desktop.
Save cloudaice/5565236 to your computer and use it in GitHub Desktop.

Revisions

  1. James Casbon revised this gist Jun 26, 2012. 1 changed file with 62 additions and 0 deletions.
    62 changes: 62 additions & 0 deletions example.py
    Original 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)
  2. James Casbon revised this gist Jun 26, 2012. 1 changed file with 16 additions and 43 deletions.
    59 changes: 16 additions & 43 deletions github.py
    Original 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
    """ 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, extra_fields))
    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('Facebook auth error: %s' % str(response))
    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, method, callback, access_token=None, **args):
    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 = self._API_URL + method + '?' + urllib.urlencode(args)
    logging.warning('request to ' + url)
    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))
    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)


    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()

  3. James Casbon created this gist Jun 20, 2012.
    135 changes: 135 additions & 0 deletions github.py
    Original 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()