diff --git a/app/chat/router.py b/app/chat/router.py index 1e8432f..96e3407 100644 --- a/app/chat/router.py +++ b/app/chat/router.py @@ -12,7 +12,7 @@ from app.chat.shemas import ( SAllowedChats, SMessageList, SPinnedChats, - SPinnedMessages, + SPinnedMessages, SChangeData, ) from app.unit_of_work import UnitOfWork from app.users.dependencies import check_verificated_user_with_exc @@ -47,12 +47,32 @@ async def create_chat( if user.id == user_to_exclude: raise UserCanNotReadThisChatException async with uow: - chat_id = await uow.chat.create_chat(user_id=user_to_exclude, chat_name=chat_name, created_by=user.id) + user_chat_for = await uow.user.find_one(id=user_to_exclude) + chat_id = await uow.chat.create_chat( + user_id=user_to_exclude, chat_name=chat_name, created_by=user.id, avatar_image=user_chat_for.avatar_image + ) await uow.chat.add_user_to_chat(user.id, chat_id) await uow.chat.add_user_to_chat(settings.ADMIN_USER_ID, chat_id) await uow.commit() +@router.post( + "/change_data", + status_code=status.HTTP_200_OK, + response_model=None, +) +async def change_chat_data( + user_data: SChangeData, user: SUser = Depends(check_verificated_user_with_exc), uow=Depends(UnitOfWork) +): + async with uow: + chat = await uow.chat.find_one(chat_id=user_data.chat_id, user_id=user.id) + if chat.created_by != user.id: + raise UserDontHavePermissionException + await uow.chat.change_data( + chat_id=user_data.chat_id, chat_name=user_data.chat_name, avatar_image=user_data.avatar_image + ) + + @router.get( "/get_last_message/{chat_id}", status_code=status.HTTP_200_OK, diff --git a/app/chat/shemas.py b/app/chat/shemas.py index 1f16c7c..6648925 100644 --- a/app/chat/shemas.py +++ b/app/chat/shemas.py @@ -35,9 +35,16 @@ class SChat(BaseModel): chat_id: int chat_for: int chat_name: str + created_by: int avatar_image: str +class SChangeData(BaseModel): + chat_id: int + chat_name: str + avatar_image: HttpUrl + + class SAllowedChats(BaseModel): allowed_chats: list[SChat] | None diff --git a/app/dao/chat.py b/app/dao/chat.py index 762182b..d62771a 100644 --- a/app/dao/chat.py +++ b/app/dao/chat.py @@ -1,3 +1,4 @@ +from pydantic import HttpUrl from sqlalchemy import insert, select, update, delete, func from sqlalchemy.exc import IntegrityError, NoResultFound from sqlalchemy.orm import aliased @@ -35,11 +36,11 @@ class ChatDAO(BaseDAO): Chat.id.label("chat_id"), Chat.chat_for, Chat.chat_name, - Users.avatar_image + Chat.created_by, + Chat.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) ) @@ -49,8 +50,12 @@ class ChatDAO(BaseDAO): 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) + async def create_chat(self, user_id: int, chat_name: str, created_by: int, avatar_image: HttpUrl) -> int: + stmt = ( + insert(Chat) + .values(chat_for=user_id, chat_name=chat_name, created_by=created_by, avatar_image=avatar_image) + .returning(Chat.id) + ) result = await self.session.execute(stmt) chat_id = result.scalar() @@ -200,6 +205,14 @@ class ChatDAO(BaseDAO): ) await self.session.execute(stmt) + async def change_data(self, chat_id: int, chat_name: str, avatar_image: HttpUrl) -> None: + stmt = ( + update(Chat) + .values(chat_name=chat_name, avatar_image=avatar_image) + .where(Chat.id == chat_id) + ) + await self.session.execute(stmt) + async def delete_chat(self, chat_id: int) -> None: stmt = update(Chat).where(Chat.id == chat_id).values(visibility=False) await self.session.execute(stmt) @@ -229,13 +242,13 @@ class ChatDAO(BaseDAO): "chat_id", Chat.id, "chat_for", Chat.chat_for, "chat_name", Chat.chat_name, - "avatar_image", Users.avatar_image, + "created_by", Chat.created_by, + "avatar_image", Chat.avatar_image, ) ) ) ) .select_from(PinnedChat) - .join(Users, PinnedChat.user_id == Users.id) .join(Chat, PinnedChat.chat_id == Chat.id) .where(PinnedChat.user_id == user_id, Chat.visibility == True) # noqa: E712 ) diff --git a/app/dao/user.py b/app/dao/user.py index 326d868..393f702 100644 --- a/app/dao/user.py +++ b/app/dao/user.py @@ -92,14 +92,14 @@ class UserDAO(BaseDAO): "chat_id", Chat.id, "chat_for", Chat.chat_for, "chat_name", Chat.chat_name, - "avatar_image", Users.avatar_image, + "created_by", Chat.created_by, + "avatar_image", Chat.avatar_image, ) ) ) ) .select_from(UserChat) .join(Chat, Chat.id == UserChat.chat_id) - .join(Users, Users.id == UserChat.user_id) .where(UserChat.user_id == user_id, Chat.visibility == True) # noqa: E712 ) diff --git a/app/migrations/versions/2024-06-08_database_creation.py b/app/migrations/versions/2024-06-13_database_creation.py similarity index 96% rename from app/migrations/versions/2024-06-08_database_creation.py rename to app/migrations/versions/2024-06-13_database_creation.py index d93391c..4b251a9 100644 --- a/app/migrations/versions/2024-06-08_database_creation.py +++ b/app/migrations/versions/2024-06-13_database_creation.py @@ -1,8 +1,8 @@ """Database Creation -Revision ID: 4668313943c0 +Revision ID: c69369209bab Revises: -Create Date: 2024-06-08 18:36:31.974804 +Create Date: 2024-06-13 18:40:03.297322 """ from typing import Sequence, Union @@ -12,7 +12,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision: str = '4668313943c0' +revision: str = 'c69369209bab' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -39,6 +39,7 @@ def upgrade() -> None: sa.Column('created_by', sa.Integer(), nullable=False), sa.Column('chat_for', sa.Integer(), nullable=True), sa.Column('chat_name', sa.String(), nullable=False), + sa.Column('avatar_image', sa.String(), nullable=False), sa.Column('visibility', sa.Boolean(), server_default='true', nullable=False), sa.ForeignKeyConstraint(['chat_for'], ['users.id'], ), sa.ForeignKeyConstraint(['created_by'], ['users.id'], ), diff --git a/app/models/chat.py b/app/models/chat.py index 1e4d5d4..649898c 100644 --- a/app/models/chat.py +++ b/app/models/chat.py @@ -11,4 +11,5 @@ class Chat(Base): created_by: Mapped[int] = mapped_column(ForeignKey("users.id")) chat_for = mapped_column(ForeignKey("users.id")) chat_name: Mapped[str] + avatar_image: Mapped[str] visibility: Mapped[bool] = mapped_column(server_default="true") diff --git a/app/services/redis_service.py b/app/services/redis_service.py index 60a7407..96c096d 100644 --- a/app/services/redis_service.py +++ b/app/services/redis_service.py @@ -9,7 +9,7 @@ def get_redis_session() -> Redis: class RedisService: @staticmethod - async def set_verification_code(redis: Redis, user_id: int, verification_code: str): + async def set_verification_code(redis: Redis, user_id: int, verification_code: str) -> None: await redis.setex(f"user_verification_code: {user_id}", 1800, verification_code) @staticmethod @@ -18,7 +18,7 @@ class RedisService: return verification_code.decode() @staticmethod - async def delete_verification_code(redis: Redis, user_id: int): + async def delete_verification_code(redis: Redis, user_id: int) -> None: await redis.delete(f"user_verification_code: {user_id}") diff --git a/app/static/images/2023-04-21_214155.png b/app/static/images/2023-04-21_214155.png deleted file mode 100644 index 9dedd56..0000000 Binary files a/app/static/images/2023-04-21_214155.png and /dev/null differ diff --git a/app/static/images/ты уже пешка BP.png b/app/static/images/ты уже пешка BP.png deleted file mode 100755 index 2211c80..0000000 Binary files a/app/static/images/ты уже пешка BP.png and /dev/null differ diff --git a/app/users/router.py b/app/users/router.py index 869753f..24650d7 100644 --- a/app/users/router.py +++ b/app/users/router.py @@ -112,6 +112,26 @@ async def register_user(user_data: SUserRegister, uow=Depends(UnitOfWork)): return {"authorization": f"Bearer {access_token}"} +@router.post( + "/resend_email_verification", + status_code=status.HTTP_200_OK, +) +async def resend_email_verification(user: SUser = Depends(get_current_user)): + user_code = generate_confirmation_code() + user_mail_data = SConfirmationData.model_validate( + { + "user_id": user.id, + "username": user.username, + "email_to": user.email, + "confirmation_code": user_code + } + ) + send_registration_confirmation_email.delay(user_mail_data.model_dump()) + redis_session = get_redis_session() + await RedisService.delete_verification_code(redis=redis_session, user_id=user.id) + await RedisService.set_verification_code(redis=redis_session, user_id=user.id, verification_code=user_code) + + @router.get( "/email_verification/{user_code}", status_code=status.HTTP_200_OK,