Skip to content

Instantly share code, notes, and snippets.

@gleicon
Forked from andreadipersio/tornado-dropbox-oauth2.py
Last active August 29, 2015 14:06
Show Gist options
  • Save gleicon/291909ff5fb8e8294025 to your computer and use it in GitHub Desktop.
Save gleicon/291909ff5fb8e8294025 to your computer and use it in GitHub Desktop.
forked from tornado-dropbox-oauth2
import cyclone.web
import cyclone.auth
from cyclone import escape, httpclient
from cyclone.options import parse_command_line, define, options
from twisted.python import log
from twisted.internet import task, defer, reactor
import sys
try:
import urllib.parse as urllib_parse # py3
except ImportError:
import urllib as urllib_parse # py2
class DropboxMixin(cyclone.auth.OAuth2Mixin):
"""Dropbox authentication using OAuth2.
https://www.dropbox.com/developers/core/docs
"""
_OAUTH_AUTHORIZE_URL = "https://www.dropbox.com/1/oauth2/authorize"
_OAUTH_ACCESS_TOKEN_URL = "https://api.dropbox.com/1/oauth2/token"
_OAUTH_SETTINGS_KEY = 'dropbox_oauth'
@property
def oauth_settings(self):
return self.settings[self._OAUTH_SETTINGS_KEY]
@defer.inlineCallbacks
def get_authenticated_user(self, code):
"""Handles the login for the Dropbox user, returning a user object."""
body = urllib_parse.urlencode({
"redirect_uri": self.oauth_settings["redirect"],
"code": code,
"client_id": self.oauth_settings['key'],
"client_secret": self.oauth_settings['secret'],
"grant_type": "authorization_code",
})
print body
response = yield cyclone.httpclient.fetch(
self._OAUTH_ACCESS_TOKEN_URL,
method="POST",
headers={'Content-Type': ['application/x-www-form-urlencoded']},
postdata=body
)
if response.error:
msg = 'Dropbox auth error: {}'.format(str(response))
cyclone.auth.AuthError(msg)
defer.returnValue(None)
args = escape.json_decode(response.body)
defer.returnValue(args)
def authorize_redirect(self):
kwargs = {
"redirect_uri": self.oauth_settings["redirect"],
"client_id": self.oauth_settings["key"],
"extra_params": {"response_type": "code"}
}
return super(DropboxMixin, self).authorize_redirect(**kwargs)
class AuthHandler(cyclone.web.RequestHandler, DropboxMixin):
@cyclone.web.asynchronous
@defer.inlineCallbacks
def get(self):
code = self.get_argument("code", None)
if code:
user = yield self.get_authenticated_user(code=code)
self.set_secure_cookie("oauth_user", user.get("uid", ""))
self.set_secure_cookie("oauth_token", user.get("access_token", ""))
self.redirect("/")
else:
yield self.authorize_redirect()
class LogoutHandler(cyclone.web.RequestHandler, DropboxMixin):
def get(self):
self.clear_cookie("oauth_user")
self.clear_cookie("oauth_token")
return "Logged out"
class MainHandler(cyclone.web.RequestHandler):
def get_current_user(self):
return self.get_secure_cookie("oauth_user")
#@cyclone.web.authenticated
def get(self):
user = self.get_current_user()
if not user:
raise cyclone.web.HTTPError(401, "Access denied")
self.write("Welcome back, {}".format(user))
class Application(cyclone.web.Application):
def __init__(self):
handlers = [
(r"/auth", AuthHandler),
(r"/logout", LogoutHandler),
(r"/", MainHandler),
]
opts = {
"cookie_secret": "II*^WvQiOkv)QihQwQZ<JH!YY/q)v%TY",
"debug": True,
"login_url": "http://localhost:8888/auth",
#https://www.dropbox.com/developers
"dropbox_oauth": {
"redirect": "http://localhost:8888/auth",
"key": "",
"secret": ""
}
}
cyclone.web.Application.__init__(self, handlers, **opts)
def main():
log.startLogging(sys.stdout)
reactor.listenTCP(8888, Application(), interface="127.0.0.1")
reactor.run()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment