diff --git a/classquiz/oauth/__init__.py b/classquiz/oauth/__init__.py index 49d3d8d..b1c9956 100644 --- a/classquiz/oauth/__init__.py +++ b/classquiz/oauth/__init__.py @@ -1,6 +1,7 @@ from fastapi import APIRouter from classquiz.oauth import google, github + router = APIRouter() router.include_router(google.router, prefix="/google") router.include_router(github.router, prefix="/github") diff --git a/classquiz/oauth/github.py b/classquiz/oauth/github.py index 4c8c7a9..81f8ab1 100644 --- a/classquiz/oauth/github.py +++ b/classquiz/oauth/github.py @@ -7,22 +7,11 @@ from pydantic import BaseModel, ValidationError from classquiz.auth import check_token, credentials_exception from classquiz.oauth.authenticate_user import log_user_in, rememberme_check from datetime import datetime +from classquiz.oauth.init_oauth import init_oauth settings = settings() router = APIRouter() -oauth = OAuth() -oauth.register( - name="github", - client_kwargs={"scope": "read:user user:email"}, - access_token_url="https://github.com/login/oauth/access_token", - access_token_params=None, - authorize_url="https://github.com/login/oauth/authorize", - authorize_params=None, - api_base_url="https://api.github.com/", - client_id=settings.github_client_id, - client_secret=settings.github_client_secret, -) class Plan(BaseModel): @@ -78,6 +67,7 @@ class GitHubOauthResponse(BaseModel): async def github_login(req: Request): if settings.github_client_id is None or settings.github_client_secret is None: raise HTTPException(status_code=501, detail="GitHub-Login isn't available on this server") + oauth = init_oauth() return await oauth.github.authorize_redirect(req, f"{settings.root_address}/api/v1/users/oauth/github/auth") @@ -87,7 +77,6 @@ async def auth(request: Request, response: Response): raise HTTPException(status_code=501, detail="GitHub-Login isn't available on this server") access_token = request.cookies.get("access_token") rememberme_token = request.cookies.get("rememberme_token") - print(access_token, rememberme_token) if access_token is not None: try: data = await check_token(access_token) @@ -97,6 +86,7 @@ async def auth(request: Request, response: Response): pass if rememberme_token is not None: return await rememberme_check(rememberme_token=rememberme_token, response=response) + oauth = init_oauth() try: token = await oauth.github.authorize_access_token(request) except: @@ -120,4 +110,7 @@ async def auth(request: Request, response: Response): email=user_data.email, username=user_data.login, auth_type=UserAuthTypes.GITHUB, verified=True ) - return await log_user_in(user=user, request=request, response=response) + await log_user_in(user=user, request=request, response=response) + response.headers.append("Location", "/account/login") + response.status_code = 302 + return response diff --git a/classquiz/oauth/google.py b/classquiz/oauth/google.py index 7b341d5..902ab98 100644 --- a/classquiz/oauth/google.py +++ b/classquiz/oauth/google.py @@ -1,23 +1,15 @@ from fastapi import APIRouter, Request, HTTPException, Response from classquiz.config import settings -from authlib.integrations.starlette_client import OAuth from classquiz.db.models import User, UserAuthTypes from pydantic import BaseModel, ValidationError from classquiz.auth import check_token, credentials_exception from classquiz.oauth.authenticate_user import log_user_in, rememberme_check +from classquiz.oauth.init_oauth import init_oauth settings = settings() router = APIRouter() -oauth = OAuth() -oauth.register( - name="github", - server_metadata_url="https://accounts.google.com/.well-known/openid-configuration", - client_kwargs={"scope": "openid email profile"}, - client_id=settings.google_client_id, - client_secret=settings.google_client_secret, -) class Userinfo(BaseModel): @@ -51,6 +43,8 @@ class OauthGoogleResponse(BaseModel): async def google_login(req: Request): if settings.google_client_secret is None or settings.google_client_id is None: raise HTTPException(status_code=501, detail="Google-Login isn't available on this server") + oauth = init_oauth() + return await oauth.google.authorize_redirect(req, f"{settings.root_address}/api/v1/users/oauth/google/auth") @@ -60,7 +54,6 @@ async def auth(request: Request, response: Response): raise HTTPException(status_code=501, detail="Google-Login isn't available on this server") access_token = request.cookies.get("access_token") rememberme_token = request.cookies.get("rememberme_token") - print(rememberme_token, access_token) if access_token is not None: try: data = await check_token(access_token) @@ -70,6 +63,7 @@ async def auth(request: Request, response: Response): pass if rememberme_token is not None: return await rememberme_check(rememberme_token=rememberme_token, response=response) + oauth = init_oauth() try: user_data = await oauth.google.authorize_access_token(request) @@ -97,4 +91,7 @@ async def auth(request: Request, response: Response): email=user_data.email, google_uid=user_data.sub, auth_type=UserAuthTypes.GOOGLE, verified=True ) - return await log_user_in(user=user, request=request, response=response) + await log_user_in(user=user, request=request, response=response) + response.headers.append("Location", "/account/login") + response.status_code = 302 + return response diff --git a/classquiz/oauth/init_oauth.py b/classquiz/oauth/init_oauth.py new file mode 100644 index 0000000..62944fa --- /dev/null +++ b/classquiz/oauth/init_oauth.py @@ -0,0 +1,30 @@ +from authlib.integrations.starlette_client import OAuth +from classquiz.config import settings +from functools import lru_cache + +settings = settings() + + +@lru_cache() +def init_oauth() -> OAuth: + oauth = OAuth() + oauth.register( + name="google", + server_metadata_url="https://accounts.google.com/.well-known/openid-configuration", + client_kwargs={"scope": "openid email profile"}, + client_id=settings.google_client_id, + client_secret=settings.google_client_secret, + ) + + oauth.register( + name="github", + client_kwargs={"scope": "read:user user:email"}, + access_token_url="https://github.com/login/oauth/access_token", + access_token_params=None, + authorize_url="https://github.com/login/oauth/authorize", + authorize_params=None, + api_base_url="https://api.github.com/", + client_id=settings.github_client_id, + client_secret=settings.github_client_secret, + ) + return oauth diff --git a/frontend/src/lib/config.ts b/frontend/src/lib/config.ts new file mode 100644 index 0000000..5402b29 --- /dev/null +++ b/frontend/src/lib/config.ts @@ -0,0 +1,2 @@ +export const google_auth_enabled = import.meta.env.VITE_GOOGLE_AUTH_ENABLED === 'true'; +export const github_auth_enabled = import.meta.env.VITE_GITHUB_AUTH_ENABLED === 'true'; diff --git a/frontend/src/routes/account/login.svelte b/frontend/src/routes/account/login.svelte index 6086e07..276794e 100644 --- a/frontend/src/routes/account/login.svelte +++ b/frontend/src/routes/account/login.svelte @@ -27,6 +27,7 @@ import Cookies from 'js-cookie'; import { getLocalization } from '$lib/i18n'; import Footer from '$lib/footer.svelte'; + import { google_auth_enabled, github_auth_enabled } from '$lib/config'; const { t } = getLocalization(); @@ -226,6 +227,45 @@ {/if} + {#if google_auth_enabled} +
+ Google Login + + Google + + + +
+ {/if} + {#if github_auth_enabled} +
+ GitHub Login + GitHub + + + +
+ {/if}