чето какието изменения #5

Merged
ns.potapov merged 1 commits from nspotapov/backend into main 2025-06-11 00:40:50 +04:00
8 changed files with 102 additions and 70 deletions

View File

@@ -10,30 +10,29 @@ from app.dependencies.auth_dep import (
from app.dependencies.dao_dep import get_session_with_commit, get_session_without_commit from app.dependencies.dao_dep import get_session_with_commit, get_session_without_commit
from app.exceptions import UserAlreadyExistsException, IncorrectEmailOrPasswordException from app.exceptions import UserAlreadyExistsException, IncorrectEmailOrPasswordException
from app.models import User from app.models import User
from app.schemas import SUserRegister, SUserAuth, EmailModel, SUserAddDB, SUserInfo from app.schemas import UserCreateSchema, UserAuthSchema, EmailSchema, UserAddDBSchema, UserSchema
router = APIRouter() router = APIRouter()
@router.post("/register") @router.post("/register")
async def register_user( async def register_user(
user_data: SUserRegister, session: AsyncSession = Depends(get_session_with_commit) user_data: UserCreateSchema, session: AsyncSession = Depends(get_session_with_commit)
) -> dict: ) -> dict:
# Проверка существования пользователя # Проверка существования пользователя
user_dao = UsersDAO(session) user_dao = UsersDAO(session)
existing_user = await user_dao.find_one_or_none( existing_user = await user_dao.find_one_or_none(
filters=EmailModel(email=user_data.email) filters=EmailSchema(email=user_data.email)
) )
if existing_user: if existing_user:
raise UserAlreadyExistsException raise UserAlreadyExistsException
# Подготовка данных для добавления # Подготовка данных для добавления
user_data_dict = user_data.model_dump() user_data_dict = user_data.model_dump()
user_data_dict.pop("confirm_password", None)
# Добавление пользователя # Добавление пользователя
await user_dao.add(values=SUserAddDB(**user_data_dict)) await user_dao.add(values=UserAddDBSchema(**user_data_dict))
return {"message": "Вы успешно зарегистрированы!"} return {"message": "Вы успешно зарегистрированы!"}
@@ -41,11 +40,11 @@ async def register_user(
@router.post("/login") @router.post("/login")
async def auth_user( async def auth_user(
response: Response, response: Response,
user_data: SUserAuth, user_data: UserAuthSchema,
session: AsyncSession = Depends(get_session_without_commit), session: AsyncSession = Depends(get_session_without_commit),
) -> dict: ) -> dict:
users_dao = UsersDAO(session) users_dao = UsersDAO(session)
user = await users_dao.find_one_or_none(filters=EmailModel(email=user_data.email)) user = await users_dao.find_one_or_none(filters=EmailSchema(email=user_data.email))
if not (user and await authenticate_user(user=user, password=user_data.password)): if not (user and await authenticate_user(user=user, password=user_data.password)):
raise IncorrectEmailOrPasswordException raise IncorrectEmailOrPasswordException
@@ -61,8 +60,8 @@ async def logout(response: Response):
@router.get("/me") @router.get("/me")
async def get_me(user_data: User = Depends(get_current_user)) -> SUserInfo: async def get_me(user_data: User = Depends(get_current_user)) -> UserSchema:
return SUserInfo.model_validate(user_data) return UserSchema.model_validate(user_data)
@router.post("/refresh") @router.post("/refresh")

View File

@@ -7,6 +7,7 @@ from fastapi.staticfiles import StaticFiles
from loguru import logger from loguru import logger
from app.auth import router as auth_router from app.auth import router as auth_router
from app.routers import all_routers
@asynccontextmanager @asynccontextmanager
@@ -58,6 +59,9 @@ def register_routers(app: FastAPI) -> None:
# Подключение роутеров # Подключение роутеров
app.include_router(auth_router, prefix="/auth", tags=["Auth"]) app.include_router(auth_router, prefix="/auth", tags=["Auth"])
for router in all_routers:
app.include_router(router)
# Создание экземпляра приложения # Создание экземпляра приложения
app = create_app() app = create_app()

View File

@@ -0,0 +1,5 @@
from .users import router as users_router
all_routers = [
users_router
]

View File

@@ -1,32 +0,0 @@
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from app.schemas import SUserInfo
from app.dependencies.dao_dep import get_session_with_commit, get_session_without_commit
router = APIRouter(prefix="/user")
@router.get("/{user_id}")
async def get_user_by_id(user_id: int, session: AsyncSession = Depends(get_session_without_commit)) -> SUserInfo:
pass
@router.get("/")
async def get_all_users(session: AsyncSession = Depends(get_session_without_commit)) -> list[SUserInfo]:
pass
@router.post("/")
async def create_user(user_data, session: AsyncSession = Depends(get_session_with_commit)) -> dict:
pass
@router.put("/{user_id}")
async def update_user(user_id: int, user_data, session: AsyncSession = Depends(get_session_with_commit)):
pass
@router.delete("/{user_id}")
async def delete_user(user_id: int, session: AsyncSession = Depends(get_session_with_commit)):
pass

View File

@@ -0,0 +1,58 @@
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from app.dao import UsersDAO
from app.dependencies.dao_dep import get_session_with_commit, get_session_without_commit
from app.exceptions import UserAlreadyExistsException
from app.schemas import UserSchema, EmailSchema, UserAddDBSchema
router = APIRouter(prefix="/users", tags=["Users"])
@router.get("/{user_id}")
async def get_user_by_id(user_id: int, session: AsyncSession = Depends(get_session_without_commit)) -> UserSchema:
user = await UsersDAO(session).find_one_or_none_by_id(data_id=user_id)
if not user:
raise HTTPException(status_code=404)
return UserSchema.model_validate(user)
@router.get("")
async def get_all_users(session: AsyncSession = Depends(get_session_without_commit)) -> list[UserSchema]:
users_dao = UsersDAO(session)
users = await users_dao.find_all()
return [UserSchema.model_validate(user) for user in users]
@router.post("")
async def create_user(user_data, session: AsyncSession = Depends(get_session_with_commit)) -> dict:
# Проверка существования пользователя
user_dao = UsersDAO(session)
existing_user = await user_dao.find_one_or_none(
filters=EmailSchema(email=user_data.email)
)
if existing_user:
raise UserAlreadyExistsException
# Подготовка данных для добавления
user_data_dict = user_data.model_dump()
user_data_dict.pop("confirm_password", None)
# Добавление пользователя
await user_dao.add(values=UserAddDBSchema(**user_data_dict))
return {"message": "Вы успешно зарегистрированы!"}
@router.put("/{user_id}")
async def update_user(user_id: int, user_data, session: AsyncSession = Depends(get_session_with_commit)):
pass
@router.delete("/{user_id}")
async def delete_user(user_id: int, session: AsyncSession = Depends(get_session_with_commit)):
pass

View File

@@ -1,2 +1,2 @@
from .general import EmailModel from .general import EmailSchema
from .user import UserBase, SUserInfo, SUserAddDB, SUserRegister, SUserAuth from .user import UserBaseSchema, UserSchema, UserAddDBSchema, UserCreateSchema, UserAuthSchema

View File

@@ -1,11 +1,27 @@
from typing import Self
from pydantic import ( from pydantic import (
BaseModel, BaseModel,
ConfigDict, ConfigDict,
EmailStr, EmailStr,
Field, Field, model_validator,
) )
from app.auth.utils import get_password_hash
class EmailModel(BaseModel):
class EmailSchema(BaseModel):
email: EmailStr = Field(description="Электронная почта") email: EmailStr = Field(description="Электронная почта")
model_config = ConfigDict(from_attributes=True) model_config = ConfigDict(from_attributes=True)
class PasswordSchema(BaseModel):
password: str = Field(
min_length=5, max_length=50, description="Пароль, от 5 до 50 знаков"
)
model_config = ConfigDict(from_attributes=True)
@model_validator(mode="after")
def check_password(self) -> Self:
self.password = get_password_hash(self.password)
return self

View File

@@ -1,16 +1,12 @@
from typing import Self
from pydantic import ( from pydantic import (
Field, Field,
model_validator,
) )
from app.auth.utils import get_password_hash
from app.models.user import UserRole from app.models.user import UserRole
from .general import EmailModel from .general import EmailSchema, PasswordSchema
class UserBase(EmailModel): class UserBaseSchema(EmailSchema):
name: str = Field( name: str = Field(
min_length=3, max_length=50, description="Имя, от 3 до 50 символов" min_length=3, max_length=50, description="Имя, от 3 до 50 символов"
) )
@@ -26,33 +22,19 @@ class UserBase(EmailModel):
role: UserRole = Field(description="Роль пользователя в системе", default=UserRole.GUEST) role: UserRole = Field(description="Роль пользователя в системе", default=UserRole.GUEST)
class SUserRegister(UserBase): class UserCreateSchema(PasswordSchema, UserBaseSchema):
password: str = Field( pass
min_length=5, max_length=50, description="Пароль, от 5 до 50 знаков"
)
confirm_password: str = Field(
min_length=5, max_length=50, description="Повторите пароль"
)
@model_validator(mode="after")
def check_password(self) -> Self:
if self.password != self.confirm_password:
raise ValueError("Пароли не совпадают")
self.password = get_password_hash(
self.password
) # хешируем пароль до сохранения в базе данных
return self
class SUserAddDB(UserBase): class UserAddDBSchema(UserBaseSchema):
password: str = Field(min_length=5, description="Пароль в формате HASH-строки") password: str = Field(min_length=5, description="Пароль в формате HASH-строки")
class SUserAuth(EmailModel): class UserAuthSchema(EmailSchema):
password: str = Field( password: str = Field(
min_length=5, max_length=50, description="Пароль, от 5 до 50 знаков" min_length=5, max_length=50, description="Пароль, от 5 до 50 знаков"
) )
class SUserInfo(UserBase): class UserSchema(UserBaseSchema):
id: int = Field(description="Идентификатор пользователя") id: int = Field(description="Идентификатор пользователя")