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

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}