122 lines
4.7 KiB
Python
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)
|