122 lines
4.7 KiB
Python

from typing import List, Optional
from fastapi import HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.application.users_repository import UsersRepository
from app.core.constants import UserRoles
from app.domain.entities.users import UserRead, UserActivate, UserUpdate, PasswordChangeRequest
from app.domain.models import User
from app.infrastructure.register_service import RegisterService
class UsersService:
def __init__(self, db: AsyncSession):
self.users_repository = UsersRepository(db)
self.user_roles = UserRoles()
async def get_all(self) -> List[UserRead]:
users = await self.users_repository.get_all()
response = []
for user in users:
response.append(UserRead.model_validate(user))
return response
async def get_by_id(self, user_id: int) -> UserRead:
user = await self.users_repository.get_by_id(user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Пользователь не найден',
)
return UserRead.model_validate(user)
async def set_activate(self, activate_data: UserActivate, current_user: User) -> UserRead:
user = await self.users_repository.get_by_id(activate_data.user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Пользователь не найден',
)
if user.id == current_user.id:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Нельзя заблокировать самого себя'
)
if user.role.title == UserRoles.MODERATOR and user.is_admin:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Нельзя заблокировать даминистратора'
)
user.is_activated = activate_data.is_activated
user = await self.users_repository.update(user)
return UserRead.model_validate(user)
async def update(self, user_id: int, user: UserUpdate, current_user: User):
user_model = await self.users_repository.get_by_id(user_id)
if not user_model:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Пользователь не найден',
)
if current_user.id != user_model.id and not (
current_user.role.title == self.user_roles.MODERATOR and current_user.is_admin
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail='Доступ запрещен',
)
user_model.first_name = user.first_name
user_model.last_name = user.last_name
user_model.patronymic = user.patronymic
user_model.email = str(user.email)
user_model.birthdate = user.birthdate
user_model = await self.users_repository.update(user_model)
return UserRead.model_validate(user_model)
async def change_password(
self, user_id: int, password_data: PasswordChangeRequest, current_user: User
) -> Optional[UserRead]:
user_model = await self.users_repository.get_by_id(user_id)
if not user_model:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Пользователь не найден',
)
if current_user.id != user_model.id and not (
current_user.role.title == self.user_roles.MODERATOR and current_user.is_admin
):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail='Доступ запрещен',
)
if password_data.password != password_data.repeat_password:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Пароли не совпадают',
)
if not RegisterService.is_strong_password(password_data.repeat_password):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Пароль слишком слабый. Пароль должен содержать не менее 8 символов, включая хотя бы одну букву и одну цифру и один специальный символ.'
)
user_model.set_password(password_data.password)
user_model = await self.users_repository.update(user_model)
return UserRead.model_validate(user_model)