from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordRequestForm from sqlalchemy.orm import Session from .. import models, schemas from ..database import get_db from ..security import hash_password, verify_password, create_access_token from ..deps import get_current_user router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/register", response_model=schemas.UserOut) def register(payload: schemas.UserCreate, db: Session = Depends(get_db)): """Регистрация закрыта для публичного доступа. Единственное исключение — bootstrap первого администратора: когда в БД ещё нет ни одного пользователя, регистрация создаёт admin-аккаунт. Это нужно, чтобы панель можно было поднять с нуля. Все последующие пользователи создаются только через CLI (`python -m app.manage_users`) или админский эндпоинт /admin/users. """ email = payload.email.lower().strip() # Bootstrap: первый пользователь становится администратором. if db.query(models.User).count() == 0: user = models.User( email=email, password_hash=hash_password(payload.password), role=models.Role.admin, is_active=True, ) db.add(user) db.commit() db.refresh(user) return user # Публичная регистрация закрыта — отвечаем 403. raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Регистрация закрыта. Обратитесь к администратору для создания учётной записи.", ) @router.post("/login", response_model=schemas.Token) def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)): user = db.query(models.User).filter(models.User.email == form_data.username).first() if not user or not verify_password(form_data.password, user.password_hash): raise HTTPException(status_code=401, detail="Неверный email или пароль") if not user.is_active: raise HTTPException(status_code=403, detail="Аккаунт деактивирован. Обратитесь к администратору.") token = create_access_token({"sub": str(user.id)}) return {"access_token": token, "token_type": "bearer"} @router.get("/me", response_model=schemas.UserOut) def me(current_user: models.User = Depends(get_current_user)): return current_user