diff --git a/app/chat/exceptions.py b/app/chat/exceptions.py index e4f615f..c71d84a 100644 --- a/app/chat/exceptions.py +++ b/app/chat/exceptions.py @@ -36,3 +36,8 @@ class UserAlreadyPinnedChatException(BlackPhoenixException): class MessageAlreadyPinnedException(BlackPhoenixException): status_code = status.HTTP_409_CONFLICT detail = "Сообщение уже закрепили" + + +class ChatNotFoundException(BlackPhoenixException): + status_code = status.HTTP_409_CONFLICT + detail = "Чат не найден" diff --git a/app/chat/router.py b/app/chat/router.py index fcff0eb..1e8432f 100644 --- a/app/chat/router.py +++ b/app/chat/router.py @@ -133,7 +133,7 @@ async def invite_to_chat( ): invitation_data = decode_invitation_token(invitation_token) async with uow: - chat = await uow.chat.find_one_or_none(id=invitation_data.chat_id) + chat = await uow.chat.find_one(chat_id=invitation_data.chat_id, user_id=user.id) if user.id == chat.chat_for: raise UserCanNotReadThisChatException await uow.chat.add_user_to_chat(chat_id=invitation_data.chat_id, user_id=user.id) @@ -147,7 +147,7 @@ async def invite_to_chat( ) async def delete_chat(chat_id: int, user: SUser = Depends(check_verificated_user_with_exc), uow=Depends(UnitOfWork)): async with uow: - chat = await uow.chat.find_one_or_none(id=chat_id) + chat = await uow.chat.find_one(chat_id=chat_id, user_id=user.id) if not user.id == chat.created_by: raise UserDontHavePermissionException await uow.chat.delete_chat(chat_id) @@ -166,7 +166,7 @@ async def delete_user_from_chat( uow=Depends(UnitOfWork) ): async with uow: - chat = await uow.chat.find_one_or_none(id=chat_id) + chat = await uow.chat.find_one(chat_id=chat_id, user_id=user.id) if not user.id == chat.created_by: raise UserDontHavePermissionException await uow.chat.delete_user_from_chat(chat_id=chat_id, user_id=user_id) diff --git a/app/dao/chat.py b/app/dao/chat.py index 040fa30..29a677e 100644 --- a/app/dao/chat.py +++ b/app/dao/chat.py @@ -9,8 +9,9 @@ from app.chat.exceptions import ( UserAlreadyPinnedChatException, MessageNotFoundException, MessageAlreadyPinnedException, + ChatNotFoundException, ) -from app.chat.shemas import SMessage, SMessageList, SPinnedMessages, SPinnedChats +from app.chat.shemas import SMessage, SMessageList, SPinnedMessages, SPinnedChats, SChat from app.models.users import Users from app.models.message_answer import MessageAnswer from app.models.chat import Chat @@ -27,11 +28,26 @@ class ChatDAO(BaseDAO): def check_query_compile(query): print(query.compile(engine, compile_kwargs={"literal_binds": True})) # Проверка SQL запроса - async def find_one_or_none(self, **filter_by): - query = select(Chat.__table__.columns).filter_by(**filter_by) - result = await self.session.execute(query) - result = result.mappings().one_or_none() - return result + async def find_one(self, chat_id: int, user_id: int) -> SChat: + try: + query = ( + select( + Chat.id.label("chat_id"), + Chat.chat_for, + Chat.chat_name, + Users.avatar_image + ) + .select_from(Chat) + .join(UserChat, Chat.id == UserChat.chat_id) + .join(Users, UserChat.user_id == Users.id) + .where(UserChat.chat_id == chat_id, UserChat.user_id == user_id) + ) + + result = await self.session.execute(query) + result = result.mappings().one() + return SChat.model_validate(result) + except NoResultFound: + raise ChatNotFoundException async def create_chat(self, user_id: int, chat_name: str, created_by: int) -> int: stmt = insert(Chat).values(chat_for=user_id, chat_name=chat_name, created_by=created_by).returning(Chat.id) diff --git a/app/utils/auth.py b/app/utils/auth.py index d049d3b..4218274 100644 --- a/app/utils/auth.py +++ b/app/utils/auth.py @@ -11,7 +11,7 @@ from app.exceptions import ( UserMustConfirmEmailException, ) from app.users.exceptions import IncorrectAuthDataException -from app.chat.exceptions import UserDontHavePermissionException +from app.chat.exceptions import UserDontHavePermissionException, ChatNotFoundException from app.unit_of_work import UnitOfWork from app.users.schemas import SUser, SConfirmationData, SInvitationData @@ -101,17 +101,11 @@ class AuthService: if not await cls.check_verificated_user(uow=uow, user_id=user_id): raise UserMustConfirmEmailException - @staticmethod - async def get_user_allowed_chats_id(uow: UnitOfWork, user_id: int) -> set[int]: - async with uow: - user_allowed_chats = await uow.user.get_user_allowed_chats(user_id) - user_allowed_chats_id = {chat.chat_id for chat in user_allowed_chats.allowed_chats} - return user_allowed_chats_id - @classmethod - async def validate_user_access_to_chat(cls, uow: UnitOfWork, user_id: int, chat_id: int) -> bool: - user_allowed_chats = await cls.get_user_allowed_chats_id(uow=uow, user_id=user_id) - if chat_id not in user_allowed_chats: + async def validate_user_access_to_chat(cls, uow: UnitOfWork, user_id: int, chat_id: int) -> None: + try: + async with uow: + await uow.chat.find_one(chat_id=chat_id, user_id=user_id) + except ChatNotFoundException: raise UserDontHavePermissionException - return True diff --git a/docker/Dockerfile_back b/docker/Dockerfile_back index 0b45151..2877ff2 100644 --- a/docker/Dockerfile_back +++ b/docker/Dockerfile_back @@ -26,5 +26,5 @@ RUN chown -R app:app $APP_HOME USER app -CMD ["gunicorn", "app.main:app", "--workers", "1", "--worker-class", "uvicorn.workers.UvicornWorker", "--bind=0.0.0.0:8000"] +CMD ["hypercorn", "app.main:app"]