From 99714ac4764f046ed3a18d4bcd0c87082d9428f8 Mon Sep 17 00:00:00 2001 From: dev1lfreak Date: Wed, 10 Jun 2026 20:09:40 +0300 Subject: [PATCH] fix: password change bugs --- .../repositories/i_user_repository.py | 4 ---- src/application/commands/set_password.py | 8 +++---- .../database/repositories/user_repository.py | 24 +++++++++++++++---- src/presentation/routing/users.py | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/application/abstractions/repositories/i_user_repository.py b/src/application/abstractions/repositories/i_user_repository.py index f632811..76ab23b 100644 --- a/src/application/abstractions/repositories/i_user_repository.py +++ b/src/application/abstractions/repositories/i_user_repository.py @@ -34,10 +34,6 @@ class IUserRepository(ABC): @abstractmethod async def count_individuals(self, *, query: str) -> int: raise NotImplementedError - - @abstractmethod - async def get_password_hash(self, user_id: str) -> str: - raise NotImplementedError @abstractmethod async def set_password(self, user_id: str, password_hash: str) -> UserEntity: diff --git a/src/application/commands/set_password.py b/src/application/commands/set_password.py index 64c6627..8e7525c 100644 --- a/src/application/commands/set_password.py +++ b/src/application/commands/set_password.py @@ -18,14 +18,12 @@ class SetPasswordCommand: @transactional async def __call__(self, email: str, password: str) -> bool: try: - user = await self._unit_of_work.user_repository.get_user_by_email(email) - - password_hash = self._hash_service.hash_password(password) + password_hash = await self._hash_service.hash(password) await self._unit_of_work.user_repository.set_password( - user_id=user.id, + user_email=email, password_hash=password_hash, ) - self._logger.info(f'Set password for user {user.id}') + self._logger.info(f'Set password for user {email}') return True except ApplicationException: raise diff --git a/src/infrastructure/database/repositories/user_repository.py b/src/infrastructure/database/repositories/user_repository.py index 586b46a..176b3e2 100644 --- a/src/infrastructure/database/repositories/user_repository.py +++ b/src/infrastructure/database/repositories/user_repository.py @@ -74,10 +74,25 @@ class UserRepository(IUserRepository): except SQLAlchemyError as exc: self._logger.exception(str(exc)) raise ApplicationException(status_code=500, message='Database error') - + + async def _get_user(self, user_id: str) -> UserModel: + stmt = ( + select(UserModel) + .where( + UserModel.id == user_id, + UserModel.is_deleted.is_(False), + ) + ) + result = await self._session.execute(stmt) + user: UserModel | None = result.scalar_one_or_none() + if user is None: + self._logger.warning(f'User not found with user_id {user_id}') + raise ApplicationException(status_code=404, message='User not found') + return user + async def _update_field(self, user_id: str, **fields: object) -> UserEntity: try: - user = await self._get_active_user(user_id) + user = await self._get_user(user_id) for key, value in fields.items(): setattr(user, key, value) await self._session.flush() @@ -89,8 +104,9 @@ class UserRepository(IUserRepository): self._logger.exception(str(exception)) raise InternalServerException(message=f'Database error: {str(exception)}') - async def set_password(self, user_id: str, password_hash: str) -> UserEntity: - return await self._update_field(user_id, password_hash=password_hash) + async def set_password(self, user_email: str, password_hash: str) -> UserEntity: + user = await self.get_user_by_email(user_email) + return await self._update_field(user.id, password_hash=password_hash) async def get_user_by_email(self, email: str) -> UserEntity: try: diff --git a/src/presentation/routing/users.py b/src/presentation/routing/users.py index a291571..88010e0 100644 --- a/src/presentation/routing/users.py +++ b/src/presentation/routing/users.py @@ -3,7 +3,7 @@ from fastapi.responses import ORJSONResponse from starlette import status from src.presentation.dependencies.commands import get_set_password_command from src.application.commands.set_password import SetPasswordCommand -from presentation.schemas.password import SetPasswordRequest +from src.presentation.schemas.password import SetPasswordRequest users_router = APIRouter(prefix='/users', tags=['users'])