forked from tornadoweb/tornado
-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
134 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
### Dropbox auth demo | ||
|
||
Implements an oauth2 mixin for dropbox inspired on https://gist.github.com/andreadipersio/7547259. | ||
|
||
Create an application on dropbox, add token and secret to main.py and run it with python main.py | ||
|
This file contains 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 characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import cyclone.web | ||
import cyclone.auth | ||
from cyclone import escape, httpclient | ||
from twisted.internet import task, defer | ||
|
||
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) | ||
|
This file contains 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 characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import cyclone.web | ||
import cyclone.auth | ||
from twisted.python import log | ||
from twisted.internet import task, defer, reactor | ||
import sys | ||
from dropbox import DropboxMixin | ||
|
||
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) | ||
print user | ||
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 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() | ||
print 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"/", 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() |