from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from ..database import get_db from ..schemas.auth import UserRegister, UserLogin, OAuthLogin, Token, UserOut from ..services import auth_service from .deps import get_current_user router = APIRouter(prefix="/auth", tags=["auth"]) def _make_token(user) -> Token: """user puede ser un User o un int (id).""" if isinstance(user, int): # Fallback antiguo token = auth_service.create_access_token({"sub": str(user)}) return Token(access_token=token, role="CIUDADANO") token = auth_service.create_access_token({"sub": str(user.id), "role": user.role}) return Token(access_token=token, role=user.role) @router.post("/register", response_model=Token, status_code=201) def register(data: UserRegister, db: Session = Depends(get_db)): if data.email and auth_service.get_user_by_email(db, data.email): raise HTTPException(status_code=400, detail="El correo ya está registrado") user = auth_service.create_user(db, data.full_name, data.email, data.phone, data.password) return _make_token(user) @router.post("/login", response_model=Token) def login(data: UserLogin, db: Session = Depends(get_db)): # Normalizar entrada: trim espacios, lowercase email email = (data.email or "").strip().lower() password = (data.password or "").strip() # Log de debug — muestra qué llega exactamente (sin la contraseña completa) print(f"[LOGIN] email_recibido={email!r} pw_len={len(password)}") if not email or not password: raise HTTPException(status_code=401, detail="Credenciales inválidas — campos vacíos") # Buscar usuario (case-insensitive con LOWER en SQL) from sqlalchemy import func from ..models.user import User as UserModel user = db.query(UserModel).filter(func.lower(UserModel.email) == email).first() if not user: print(f"[LOGIN] ✗ usuario no encontrado") raise HTTPException(status_code=401, detail="Credenciales inválidas") if not user.hashed_password: print(f"[LOGIN] ✗ usuario sin password (cuenta OAuth)") raise HTTPException(status_code=401, detail="Esta cuenta usa OAuth, no contraseña") if not auth_service.verify_password(password, user.hashed_password): print(f"[LOGIN] ✗ password incorrecta") raise HTTPException(status_code=401, detail="Credenciales inválidas") print(f"[LOGIN] ✓ login OK para id={user.id}") return _make_token(user) @router.post("/oauth", response_model=Token) def oauth_login(data: OAuthLogin, db: Session = Depends(get_db)): user = auth_service.get_or_create_oauth_user(db, data.provider, data.oauth_id, data.email, data.full_name) if data.push_token: user.push_token = data.push_token db.commit() return _make_token(user)