diff --git a/YYeTsFE b/YYeTsFE index 451b6ac..62ae11a 160000 --- a/YYeTsFE +++ b/YYeTsFE @@ -1 +1 @@ -Subproject commit 451b6ac37fa28b4600aed54e23f4c803a6f54725 +Subproject commit 62ae11a09add47652097e675394de618ef954c5e diff --git a/yyetsweb/handler.py b/yyetsweb/handler.py index b5c456a..2800245 100644 --- a/yyetsweb/handler.py +++ b/yyetsweb/handler.py @@ -27,7 +27,7 @@ import filetype import requests import zhconv from tornado import escape, gen, web -from tornado.auth import OAuth2Mixin +from tornado.auth import GoogleOAuth2Mixin, OAuth2Mixin from tornado.concurrent import run_on_executor from database import CaptchaResource, Redis @@ -1011,10 +1011,6 @@ class GitHubOAuth2LoginHandler(BaseHandler, OAuth2Mixin): _OAUTH_API_REQUEST_URL = "https://api.github.com/user" class_name = f"OAuthRegisterResource" - github_client_id = os.getenv("GITHUB_CLIENT_ID") - github_client_secret = os.getenv("GITHUB_CLIENT_SECRET") - redirect_uri = os.getenv("GITHUB_REDIRECT_URI") - def add_oauth_user(self, username): ip = self.get_real_ip() browser = self.request.headers['user-agent'] @@ -1022,14 +1018,20 @@ class GitHubOAuth2LoginHandler(BaseHandler, OAuth2Mixin): return response def get(self): + settings = self.settings.get("github_oauth") + github_client_id = settings.get("key") + github_client_secret = settings.get("secret") + redirect_uri = os.getenv("DOMAIN") + self.request.path + code = self.get_argument('code', None) if code: - access = self.get_authenticated_user(code) - resp = requests.get( - self._OAUTH_API_REQUEST_URL, - headers={"Authorization": "Bearer {}".format(access["access_token"])} - ).json() - + body = {"client_id": github_client_id, "client_secret": github_client_secret, "code": code} + access = requests.post(self._OAUTH_ACCESS_TOKEN_URL, data=body, + headers={"Accept": "application/json"}).json() + resp = requests.get(self._OAUTH_API_REQUEST_URL, + headers={"Authorization": "Bearer {}".format(access["access_token"])} + ).json() + username = resp["login"] logging.info("User %s login with GitHub now...", username) result = self.add_oauth_user(username) @@ -1039,15 +1041,41 @@ class GitHubOAuth2LoginHandler(BaseHandler, OAuth2Mixin): else: self.authorize_redirect( - redirect_uri=self.redirect_uri, - client_id=self.github_client_id, + redirect_uri=redirect_uri, + client_id=github_client_id, scope=[], response_type='code') - def get_authenticated_user(self, code): - body = { - "client_id": self.github_client_id, - "client_secret": self.github_client_secret, - "code": code, - } - return requests.post(self._OAUTH_ACCESS_TOKEN_URL, data=body, headers={"Accept": "application/json"}).json() + +class GoogleOAuth2LoginHandler(BaseHandler, GoogleOAuth2Mixin): + class_name = f"OAuthRegisterResource" + + def add_oauth_user(self, email): + ip = self.get_real_ip() + browser = self.request.headers['user-agent'] + response = self.instance.add_user(email, ip, browser) + return response + + async def get(self): + redirect_uri = os.getenv("DOMAIN") + self.request.path + code = self.get_argument('code', None) + if code: + access = await self.get_authenticated_user( + redirect_uri=redirect_uri, + code=code) + user = await self.oauth2_request( + "https://www.googleapis.com/oauth2/v1/userinfo", + access_token=access["access_token"]) + email = user["email"] + logging.info("User %s login with GitHub now...", email) + result = self.add_oauth_user(email) + if result["status"] == "success": + self.set_secure_cookie("username", email, 365) + self.redirect("/login?" + urlencode(result)) + else: + self.authorize_redirect( + redirect_uri=redirect_uri, + client_id=self.settings['google_oauth']['key'], + scope=['email'], + response_type='code', + extra_params={'approval_prompt': 'auto'}) diff --git a/yyetsweb/server.py b/yyetsweb/server.py index a9a1c00..d151b22 100644 --- a/yyetsweb/server.py +++ b/yyetsweb/server.py @@ -26,9 +26,10 @@ from handler import (AnnouncementHandler, BlacklistHandler, CaptchaHandler, CategoryHandler, CommentChildHandler, CommentHandler, CommentNewestHandler, CommentReactionHandler, DBDumpHandler, DoubanHandler, DoubanReportHandler, - GitHubOAuth2LoginHandler, GrafanaIndexHandler, - GrafanaQueryHandler, GrafanaSearchHandler, IndexHandler, - LikeHandler, MetricsHandler, NameHandler, NotFoundHandler, + GitHubOAuth2LoginHandler, GoogleOAuth2LoginHandler, + GrafanaIndexHandler, GrafanaQueryHandler, + GrafanaSearchHandler, IndexHandler, LikeHandler, + MetricsHandler, NameHandler, NotFoundHandler, NotificationHandler, ResourceHandler, ResourceLatestHandler, SpamProcessHandler, TopHandler, UserEmailHandler, UserHandler) @@ -70,6 +71,7 @@ class RunServer: (r'/api/category', CategoryHandler), (r'/api/admin/spam', SpamProcessHandler), (r'/auth/github', GitHubOAuth2LoginHandler), + (r'/auth/google', GoogleOAuth2LoginHandler), (r'/(.*\.html|.*\.js|.*\.css|.*\.png|.*\.jpg|.*\.ico|.*\.gif|.*\.woff2|.*\.gz|.*\.zip|' r'.*\.svg|.*\.json|.*\.txt)', @@ -80,6 +82,8 @@ class RunServer: "cookie_secret": os.getenv("cookie_secret", "eo2kcgpKwXj8Q3PKYj6nIL1J4j3b58DX"), "default_handler_class": NotFoundHandler, "login_url": "/login", + "google_oauth": {"key": os.getenv("GOOGLE_CLIENT_ID"), "secret": os.getenv("GOOGLE_CLIENT_SECRET")}, + "github_oauth": {"key": os.getenv("GITHUB_CLIENT_ID"), "secret": os.getenv("GITHUB_CLIENT_SECRET")} } application = web.Application(handlers, **settings)