1- from typing import Annotated , Any
2-
3- from fastapi import APIRouter , Depends , HTTPException , Request
4- from sqlmodel import Session
5- from starlette .responses import RedirectResponse
6-
7- from src .core .db import get_db
8- from src .dependencies .auth0 import (
9- get_auth0_service ,
10- get_current_user ,
11- get_current_user_claims ,
1+ from fastapi import APIRouter , Request
2+ from fastapi .responses import RedirectResponse
3+ from authlib .integrations .starlette_client import OAuth
4+ from src .core .config import settings
5+
6+ router = APIRouter (tags = ["auth" ])
7+
8+ oauth = OAuth ()
9+ oauth .register (
10+ name = "auth0" ,
11+ client_id = settings .AUTH0_CLIENT_ID ,
12+ client_secret = settings .AUTH0_CLIENT_SECRET ,
13+ server_metadata_url = f"https://{ settings .AUTH0_DOMAIN } /.well-known/openid-configuration" ,
14+ client_kwargs = {"scope" : "openid profile email" },
1215)
13- from src .services .auth0 import Auth0Service
14- from src .users .auth0 import get_or_create_user_from_auth0
15- from src .users .models import User
16- from src .users .schemas import UserPublic
17-
18- router = APIRouter (prefix = "/auth0" , tags = ["auth0" ])
1916
2017
2118@router .get ("/login" )
22- async def login (
23- request : Request , auth_service : Annotated [Auth0Service , Depends (get_auth0_service )]
24- ) -> RedirectResponse :
25- return await auth_service .login (request )
19+ async def login (request : Request ):
20+ redirect_uri = request .url_for ("auth0_callback" )
21+ return await oauth .auth0 .authorize_redirect (
22+ request ,
23+ redirect_uri ,
24+ prompt = "select_account" ,
25+ connection = "google-oauth2"
26+ )
2627
2728
28- @router .get ("/callback" )
29- async def callback (
30- request : Request ,
31- session : Annotated [Session , Depends (get_db )],
32- auth_service : Annotated [Auth0Service , Depends (get_auth0_service )],
33- ) -> RedirectResponse :
34- try :
35- # Exchange auth code for tokens
36- token_response = await auth_service .callback (request )
37- access_token = token_response .get ("access_token" )
29+ @router .get ("/callback" , name = "auth0_callback" )
30+ async def auth0_callback (request : Request ):
31+ token = await oauth .auth0 .authorize_access_token (request )
3832
39- # Store access token in session for later use
40- request .session ["access_token" ] = access_token
33+ user = token .get ("userinfo" ) or await oauth .auth0 .userinfo (token = token )
4134
42- # Get user info from Auth0
43- user_info = await auth_service .get_user_info (access_token )
35+ request .session ["user" ] = {
36+ "email" : user ["email" ],
37+ "name" : user .get ("name" ),
38+ "picture" : user .get ("picture" ),
39+ "sub" : user .get ("sub" ),
40+ }
4441
45- # Get or create user in our database
46- db_user = await get_or_create_user_from_auth0 (session , user_info )
47-
48- # Store user ID in session
49- request .session ["user_id" ] = str (db_user .id )
50-
51- # Redirect to the frontend after successful authentication
52- return RedirectResponse (url = "/" )
53- except Exception as e :
54- # Log the error and redirect to error page
55- return RedirectResponse (url = f"/auth0/error?message={ str (e )} " )
42+ return RedirectResponse (url = "http://localhost:5173/collections" )
5643
5744
5845@router .get ("/logout" )
59- async def logout (
60- auth_service : Annotated [Auth0Service , Depends (get_auth0_service )],
61- ) -> RedirectResponse :
62- return auth_service .logout ()
63-
64-
65- @router .get ("/me" , response_model = UserPublic )
66- async def read_users_me (
67- current_user : Annotated [User , Depends (get_current_user )],
68- ) -> User :
69- return current_user
70-
71-
72- @router .get ("/validate" )
73- async def validate_token (
74- claims : Annotated [dict [str , Any ], Depends (get_current_user_claims )],
75- ) -> dict [str , Any ]:
76- return claims
77-
78-
79- @router .get ("/error" )
80- async def auth_error (message : str = "Authentication error" ):
81- raise HTTPException (status_code = 401 , detail = message )
46+ async def logout (request : Request ):
47+ request .session .clear ()
48+ return RedirectResponse (
49+ url = f"https://{ settings .AUTH0_DOMAIN } /v2/logout"
50+ f"?client_id={ settings .AUTH0_CLIENT_ID } "
51+ f"&returnTo=http://localhost:5173"
52+ )
53+
54+
55+ @router .get ("/me" )
56+ async def me (request : Request ):
57+ user = request .session .get ("user" )
58+ return {"authenticated" : bool (user ), "user" : user }
0 commit comments