chat_back/app/chat/router.py

219 lines
7.5 KiB
Python

from cryptography.fernet import Fernet
from fastapi import APIRouter, Depends, status
from app.config import settings
from app.exceptions import UserDontHavePermissionException, MessageNotFoundException, UserCanNotReadThisChatException
from app.chat.dao import ChatDAO
from app.chat.shemas import SMessage, SLastMessages, SPinnedChat, SDeletedUser, SChat, SDeletedChat
from app.users.dao import UserDAO
from app.users.dependencies import check_verificated_user_with_exc
from app.users.auth import ADMIN_USER_ID, AuthService
from app.users.schemas import SCreateInvitationLink, SUserAddedToChat, SUser
router = APIRouter(prefix="/chat", tags=["Чат"])
@router.get(
"",
status_code=status.HTTP_200_OK,
response_model=list[SChat]
)
async def get_all_chats(user: SUser = Depends(check_verificated_user_with_exc)):
result = await UserDAO.get_user_allowed_chats(user.id)
return result
@router.post(
"",
status_code=status.HTTP_201_CREATED,
response_model=None,
)
async def add_message_to_chat(chat_id: int, message: str, user: SUser = Depends(check_verificated_user_with_exc)):
chats = await AuthService.get_user_allowed_chats_id(user.id)
if chat_id not in chats:
raise UserDontHavePermissionException
send_message_to_chat = await ChatDAO.send_message(
user_id=user.id,
chat_id=chat_id,
message=message,
)
return send_message_to_chat
@router.delete(
"/delete_message",
status_code=status.HTTP_200_OK,
response_model=None,
)
async def delete_message_from_chat(message_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
get_message_sender = await ChatDAO.get_message_by_id(message_id=message_id)
if get_message_sender is None:
raise MessageNotFoundException
if get_message_sender["user_id"] != user.id:
if not await AuthService.validate_user_admin(user_id=user.id):
raise UserDontHavePermissionException
deleted_message = await ChatDAO.delete_message(message_id=message_id)
return deleted_message
@router.post(
"/create_chat",
status_code=status.HTTP_201_CREATED,
response_model=None,
)
async def create_chat(user_to_exclude: int, chat_name: str, user: SUser = Depends(check_verificated_user_with_exc)):
if user.id == user_to_exclude:
raise UserCanNotReadThisChatException
chat_id = await ChatDAO.create(user_id=user_to_exclude, chat_name=chat_name, created_by=user.id)
user_added_to_chat = await ChatDAO.add_user_to_chat(user.id, chat_id)
await ChatDAO.add_user_to_chat(ADMIN_USER_ID, chat_id)
return user_added_to_chat
@router.get(
"/get_last_message/{chat_id}",
status_code=status.HTTP_200_OK,
response_model=list[SMessage]
)
async def get_last_message(chat_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
message = await ChatDAO.get_some_messages(chat_id=chat_id, message_number_from=0, messages_to_get=1)
if message is None:
raise MessageNotFoundException
for mes in message:
mes["created_at"] = mes["created_at"].isoformat()
return message
@router.get(
"/get_some_messages/{chat_id}",
status_code=status.HTTP_200_OK,
response_model=list[SMessage]
)
async def get_some_messages(
chat_id: int, last_messages: SLastMessages = Depends(), user: SUser = Depends(check_verificated_user_with_exc)
):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
messages = await ChatDAO.get_some_messages(
chat_id=chat_id, message_number_from=last_messages.messages_loaded,
messages_to_get=last_messages.messages_to_get
)
if not messages:
raise MessageNotFoundException
for mes in messages:
mes["created_at"] = mes["created_at"].isoformat()
return messages
@router.get(
"/message/{chat_id}",
status_code=status.HTTP_200_OK,
response_model=SMessage
)
async def get_message_by_id(chat_id: int, message_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
message = await ChatDAO.get_message_by_id(message_id=message_id)
if not message:
raise MessageNotFoundException
message = dict(message)
message["created_at"] = message["created_at"].isoformat()
return message
@router.get(
"/create_invitation_link",
status_code=status.HTTP_201_CREATED,
response_model=SCreateInvitationLink,
)
async def create_invitation_link(chat_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
cipher_suite = Fernet(settings.INVITATION_LINK_TOKEN_KEY)
invitation_token = cipher_suite.encrypt(str(chat_id).encode())
invitation_link = settings.INVITATION_LINK_HOST + "/api/chat/invite_to_chat/" + str(invitation_token).split("'")[1]
return {"invitation_link": invitation_link}
@router.get(
"/invite_to_chat/{invitation_token}",
status_code=status.HTTP_200_OK,
response_model=SUserAddedToChat,
)
async def invite_to_chat(invitation_token: str, user: SUser = Depends(check_verificated_user_with_exc)):
invitation_token = invitation_token.encode()
cipher_suite = Fernet(settings.INVITATION_LINK_TOKEN_KEY)
chat_id = int(cipher_suite.decrypt(invitation_token))
chat = await ChatDAO.find_one_or_none(id=chat_id)
if user.id == chat.chat_for:
raise UserCanNotReadThisChatException
return {"user_added_to_chat": await ChatDAO.add_user_to_chat(chat_id=chat_id, user_id=user.id)}
@router.delete(
"/delete_chat/{chat_id}",
status_code=status.HTTP_200_OK,
response_model=SDeletedChat,
)
async def delete_chat(chat_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
chat = await ChatDAO.find_one_or_none(id=chat_id)
if user.id == chat.created_by:
return {"deleted_chat": await ChatDAO.delete_chat(chat_id)}
raise UserDontHavePermissionException
@router.delete(
"/delete_user_from_chat/{chat_id}",
status_code=status.HTTP_200_OK,
response_model=SDeletedUser
)
async def delete_user_from_chat(chat_id: int, user_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
chat = await ChatDAO.find_one_or_none(id=chat_id)
if user.id == chat.created_by:
return {"deleted_user": await ChatDAO.delete_user(chat_id=chat_id, user_id=user_id)}
raise UserDontHavePermissionException
@router.post(
"/pin_chat",
status_code=status.HTTP_200_OK,
response_model=SPinnedChat
)
async def pinn_chat(chat_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.pin_chat(chat_id=chat_id, user_id=user.id)
return {"chat_id": chat_id, "user_id": user.id}
@router.delete(
"/unpin_chat",
status_code=status.HTTP_200_OK,
response_model=SPinnedChat
)
async def unpinn_chat(chat_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.unpin_chat(chat_id=chat_id, user_id=user.id)
return {"chat_id": chat_id, "user_id": user.id}
@router.get(
"/get_pinned_chats",
status_code=status.HTTP_200_OK,
response_model=list[SChat]
)
async def get_pinned_chats(user: SUser = Depends(check_verificated_user_with_exc)):
return await ChatDAO.get_pinned_chats(user_id=user.id)
@router.get(
"/pinned_messages/{chat_id}",
status_code=status.HTTP_200_OK,
response_model=list[SMessage] | None
)
async def pinned_messages(chat_id: int, user: SUser = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
messages = await ChatDAO.get_pinned_messages(chat_id=chat_id)
if messages:
for mes in messages:
mes["created_at"] = mes["created_at"].isoformat()
return messages