diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index 6d25437..1bdbdb5 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordRequestForm from sqlalchemy.orm import Session @@ -12,21 +12,34 @@ router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/register", response_model=schemas.UserOut) def register(payload: schemas.UserCreate, db: Session = Depends(get_db)): - existing = db.query(models.User).filter(models.User.email == payload.email).first() - if existing: - raise HTTPException(status_code=400, detail="Пользователь с таким email уже существует") + """Регистрация закрыта для публичного доступа. - # первый зарегистрированный пользователь становится администратором - is_first_user = db.query(models.User).count() == 0 - user = models.User( - email=payload.email, - password_hash=hash_password(payload.password), - role=models.Role.admin if is_first_user else models.Role.client, + Единственное исключение — 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="Регистрация закрыта. Обратитесь к администратору для создания учётной записи.", ) - db.add(user) - db.commit() - db.refresh(user) - return user @router.post("/login", response_model=schemas.Token) @@ -34,6 +47,8 @@ def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depend 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"}