github-actions[bot]
Deploy to Hugging Face Space
abf702c
from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi_sso.sso.google import GoogleSSO
from app.core.config import settings
from app.core.auth import create_access_token
from app.db.session import get_db
from app.services.user_service import user_service
from sqlalchemy.ext.asyncio import AsyncSession
from starlette.responses import RedirectResponse
router = APIRouter()
google_sso = GoogleSSO(
client_id=settings.GOOGLE_CLIENT_ID,
client_secret=settings.GOOGLE_CLIENT_SECRET,
redirect_uri=settings.GOOGLE_REDIRECT_URI,
allow_insecure_http=True # Set to False in production
)
@router.get("/google/login")
async def google_login():
with google_sso:
return await google_sso.get_login_redirect()
@router.get("/google/callback")
async def google_callback(request: Request, db: AsyncSession = Depends(get_db)):
with google_sso:
try:
user_data = await google_sso.verify_and_process(request)
except Exception as e:
raise HTTPException(status_code=400, detail=f"Google Authentication failed: {str(e)}")
if not user_data:
raise HTTPException(status_code=400, detail="Failed to get user data from Google")
# Check if user exists
user = await user_service.get_user_by_email(db, user_data.email)
if not user:
user = await user_service.create_user(
db=db,
email=user_data.email,
full_name=user_data.display_name or user_data.email,
avatar_url=user_data.picture,
google_id=user_data.id
)
# Record Session
from app.models.database import UserSession
session_record = UserSession(
user_id=user.id,
ip_address=request.client.host if request.client else None,
user_agent=request.headers.get("user-agent")
)
db.add(session_record)
await db.commit()
# Create access token
access_token = create_access_token(data={"sub": user.email})
# Redirect back to frontend with token
# In a real app, you might use a more secure way to pass the token
import os
frontend_url = os.getenv("FRONTEND_URL", "http://localhost:5173")
return RedirectResponse(url=f"{frontend_url}/auth/callback?token={access_token}")
# Fixing imports and implementing logout properly
from app.core.auth import get_user_or_demo
from app.models.database import UserSession, User as DBUser
from sqlalchemy import select
import datetime
@router.post("/logout")
async def logout_endpoint(db: AsyncSession = Depends(get_db), user: DBUser = Depends(get_user_or_demo)):
# Find the latest open session for this user
result = await db.execute(
select(UserSession)
.where(UserSession.user_id == user.id)
.where(UserSession.logout_at == None)
.order_by(UserSession.login_at.desc())
.limit(1)
)
last_session = result.scalar_one_or_none()
if last_session:
last_session.logout_at = datetime.datetime.utcnow()
await db.commit()
return {"status": "success", "message": "Logged out successfully"}
return {"status": "success", "message": "No active session found"}