You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.8 KiB
Python

1 day ago
from fastapi import APIRouter, Depends, HTTPException, Request
from sqlmodel import Session, select
from datetime import datetime
from app.core.db import get_session
from app.models import GoogleAccount
from app.google.auth import build_flow, token_json_from_creds
from app.google.client import get_service
router = APIRouter()
@router.get("/start")
def start_oauth():
"""Devuelve el auth_url para que el usuario lo abra y autorice."""
flow = build_flow()
auth_url, state = flow.authorization_url(
access_type="offline",
include_granted_scopes="true",
prompt="consent",
)
return {"auth_url": auth_url, "state": state}
@router.get("/callback")
def oauth_callback(request: Request, session: Session = Depends(get_session)):
"""Recibe code/state y guarda token en SQLite."""
code = request.query_params.get("code")
state = request.query_params.get("state")
if not code:
raise HTTPException(status_code=400, detail="Falta 'code' en el callback")
flow = build_flow(state=state)
try:
flow.fetch_token(code=code)
except Exception as e:
raise HTTPException(status_code=400, detail=f"No se pudo obtener token: {e}")
creds = flow.credentials
token_json = token_json_from_creds(creds)
# Obtenemos el email con OAuth2 userinfo
try:
oauth2 = get_service("oauth2", "v2", token_json)
info = oauth2.userinfo().get().execute()
email = info.get("email")
if not email:
raise ValueError("No se pudo leer email")
except Exception as e:
raise HTTPException(status_code=400, detail=f"Token ok pero no pude obtener email: {e}")
existing = session.exec(select(GoogleAccount).where(GoogleAccount.email == email)).first()
now = datetime.utcnow()
if existing:
existing.token_json = token_json
existing.updated_at = now
session.add(existing)
session.commit()
return {"status": "updated", "email": email}
else:
acc = GoogleAccount(email=email, token_json=token_json, created_at=now, updated_at=now)
session.add(acc)
session.commit()
return {"status": "created", "email": email}
@router.get("/accounts")
def list_accounts(session: Session = Depends(get_session)):
rows = session.exec(select(GoogleAccount)).all()
return [{"email": r.email, "created_at": r.created_at, "updated_at": r.updated_at} for r in rows]
@router.delete("/accounts/{email}")
def delete_account(email: str, session: Session = Depends(get_session)):
acc = session.exec(select(GoogleAccount).where(GoogleAccount.email == email)).first()
if not acc:
raise HTTPException(status_code=404, detail="Cuenta no encontrada")
session.delete(acc)
session.commit()
return {"status": "deleted", "email": email}