Skip to content

Commit

Permalink
Merge pull request #3294 from bdarnell/auth-updates
Browse files Browse the repository at this point in the history
auth: Various updates
  • Loading branch information
bdarnell committed Jul 8, 2023
2 parents 6e3521d + c98f7cc commit 34673bf
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 160 deletions.
1 change: 0 additions & 1 deletion demos/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ Feature demos
~~~~~~~~~~~~~

- ``facebook``: Authentication with the Facebook Graph API.
- ``twitter``: Authentication with the Twitter API.
- ``file_upload``: Client and server support for streaming HTTP request
payloads.
- ``tcpecho``: Using the lower-level ``IOStream`` interfaces for non-HTTP
Expand Down
1 change: 1 addition & 0 deletions demos/google_auth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main.cfg
113 changes: 113 additions & 0 deletions demos/google_auth/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""Demo app for GoogleOAuth2Mixin
Recommended usage:
- Register an app with Google following the instructions at
https://www.tornadoweb.org/en/stable/auth.html#tornado.auth.GoogleOAuth2Mixin
- Use "http://localhost:8888/auth/google" as the redirect URI.
- Create a file in this directory called main.cfg, containing two lines (python syntax):
google_oauth_key="..."
google_oauth_secret="..."
- Run this file with `python main.py --config_file=main.cfg`
- Visit "http://localhost:8888" in your browser.
"""
import asyncio
import json
import tornado
import urllib.parse

from tornado.options import define, options
from tornado.web import url

define("port", default=8888, help="run on the given port", type=int)
define("google_oauth_key", help="Google OAuth Key")
define("google_oauth_secret", help="Google OAuth Secret")
define(
"config_file",
help="tornado config file",
callback=lambda path: tornado.options.parse_config_file(path, final=False),
)


class BaseHandler(tornado.web.RequestHandler):
def get_current_user(self):
user_cookie = self.get_signed_cookie("googledemo_user")
if user_cookie:
return json.loads(user_cookie)
return None


class IndexHandler(BaseHandler, tornado.auth.GoogleOAuth2Mixin):
@tornado.web.authenticated
async def get(self):
try:
# This is redundant: we got the userinfo in the login handler.
# But this demonstrates the usage of oauth2_request outside of
# the login flow, and getting anything more than userinfo
# leads to more approval prompts and complexity.
user_info = await self.oauth2_request(
"https://www.googleapis.com/oauth2/v1/userinfo",
access_token=self.current_user["access_token"],
)
except tornado.httpclient.HTTPClientError as e:
print(e.response.body)
raise
self.write(f"Hello {user_info['name']}")


class LoginHandler(BaseHandler, tornado.auth.GoogleOAuth2Mixin):
async def get(self):
redirect_uri = urllib.parse.urljoin(
self.application.settings["redirect_base_uri"],
self.reverse_url("google_oauth"),
)
if self.get_argument("code", False):
access = await self.get_authenticated_user(
redirect_uri=redirect_uri, code=self.get_argument("code")
)
user = await self.oauth2_request(
"https://www.googleapis.com/oauth2/v1/userinfo",
access_token=access["access_token"],
)
# Save the user and access token.
user_cookie = dict(id=user["id"], access_token=access["access_token"])
self.set_signed_cookie("googledemo_user", json.dumps(user_cookie))
self.redirect("/")
else:
self.authorize_redirect(
redirect_uri=redirect_uri,
client_id=self.get_google_oauth_settings()["key"],
scope=["profile", "email"],
response_type="code",
extra_params={"approval_prompt": "auto"},
)


class LogoutHandler(BaseHandler):
def get(self):
self.clear_cookie("user")
self.redirect("/")


async def main():
tornado.options.parse_command_line()
app = tornado.web.Application(
[
url(r"/", IndexHandler),
url(r"/auth/google", LoginHandler, name="google_oauth"),
url(r"/logout", LogoutHandler),
],
redirect_base_uri=f"http://localhost:{options.port}",
google_oauth=dict(
key=options.google_oauth_key, secret=options.google_oauth_secret
),
debug=True,
cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
login_url="/auth/google",
)
app.listen(options.port)
shutdown_event = asyncio.Event()
await shutdown_event.wait()


if __name__ == "__main__":
asyncio.run(main())
12 changes: 0 additions & 12 deletions demos/twitter/home.html

This file was deleted.

105 changes: 0 additions & 105 deletions demos/twitter/twitterdemo.py

This file was deleted.

0 comments on commit 34673bf

Please sign in to comment.