import os import httpx from fastapi import APIRouter, Depends, HTTPException, status # Import the new dependency from fastapi.security import OAuth2PasswordRequestForm from firebase_admin import auth from ..firebase_config import get_db # The LoginPasswordRequest model is no longer needed for this endpoint from ..models import UserCreate, UserRecord, LoginResponse router = APIRouter() FIREBASE_WEB_API_KEY = os.environ.get("FIREBASE_WEB_API_KEY") FIREBASE_SIGN_IN_URL = f"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={FIREBASE_WEB_API_KEY}" @router.post("/register", response_model=UserRecord, status_code=status.HTTP_201_CREATED) async def register_user(user: UserCreate): """ Registers a user in Firebase Auth and creates a corresponding user document in Firestore. """ # ... (this function remains the same) try: user_record = auth.create_user( email=user.email, password=user.password, display_name=user.full_name ) db = get_db() user_data = { "uid": user_record.uid, "email": user.email, "full_name": user.full_name, "role": "member" } db.collection('users').document(user_record.uid).set(user_data) return user_data except auth.EmailAlreadyExistsError: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Email already registered", ) # The signature of this function is updated @router.post("/login", response_model=LoginResponse) async def login_with_password(form_data: OAuth2PasswordRequestForm = Depends()): """ Authenticates a user with email/password via Firebase REST API, checks their role in Firestore, and returns their UID and ID token. """ payload = { # Use form_data.username as the email "email": form_data.username, "password": form_data.password, "returnSecureToken": True } async with httpx.AsyncClient() as client: try: response = await client.post(FIREBASE_SIGN_IN_URL, json=payload) response.raise_for_status() auth_data = response.json() uid = auth_data['localId'] # Check user role in Firestore to ensure account is active db = get_db() user_doc = db.collection('users').document(uid).get() if not user_doc.exists: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="User authenticated but not found in database.", ) user = user_doc.to_dict() if user.get("role") == "member": raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Account is not activated. Please contact an administrator." ) return LoginResponse(uid=uid, id_token=auth_data['idToken']) except httpx.HTTPStatusError as e: error_detail = e.response.json().get("error", {}).get("message", "Authentication failed.") raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=error_detail )