Добавил эндпоинт на проверку пароля
This commit is contained in:
parent
2d41c02592
commit
e381353cf4
10 changed files with 77 additions and 15 deletions
|
@ -12,7 +12,7 @@ from app.chat.shemas import (
|
||||||
SAllowedChats,
|
SAllowedChats,
|
||||||
SMessageList,
|
SMessageList,
|
||||||
SPinnedChats,
|
SPinnedChats,
|
||||||
SPinnedMessages,
|
SPinnedMessages, SChangeData,
|
||||||
)
|
)
|
||||||
from app.unit_of_work import UnitOfWork
|
from app.unit_of_work import UnitOfWork
|
||||||
from app.users.dependencies import check_verificated_user_with_exc
|
from app.users.dependencies import check_verificated_user_with_exc
|
||||||
|
@ -47,12 +47,32 @@ async def create_chat(
|
||||||
if user.id == user_to_exclude:
|
if user.id == user_to_exclude:
|
||||||
raise UserCanNotReadThisChatException
|
raise UserCanNotReadThisChatException
|
||||||
async with uow:
|
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(user.id, chat_id)
|
||||||
await uow.chat.add_user_to_chat(settings.ADMIN_USER_ID, chat_id)
|
await uow.chat.add_user_to_chat(settings.ADMIN_USER_ID, chat_id)
|
||||||
await uow.commit()
|
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(
|
@router.get(
|
||||||
"/get_last_message/{chat_id}",
|
"/get_last_message/{chat_id}",
|
||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
|
|
|
@ -35,9 +35,16 @@ class SChat(BaseModel):
|
||||||
chat_id: int
|
chat_id: int
|
||||||
chat_for: int
|
chat_for: int
|
||||||
chat_name: str
|
chat_name: str
|
||||||
|
created_by: int
|
||||||
avatar_image: str
|
avatar_image: str
|
||||||
|
|
||||||
|
|
||||||
|
class SChangeData(BaseModel):
|
||||||
|
chat_id: int
|
||||||
|
chat_name: str
|
||||||
|
avatar_image: HttpUrl
|
||||||
|
|
||||||
|
|
||||||
class SAllowedChats(BaseModel):
|
class SAllowedChats(BaseModel):
|
||||||
allowed_chats: list[SChat] | None
|
allowed_chats: list[SChat] | None
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from pydantic import HttpUrl
|
||||||
from sqlalchemy import insert, select, update, delete, func
|
from sqlalchemy import insert, select, update, delete, func
|
||||||
from sqlalchemy.exc import IntegrityError, NoResultFound
|
from sqlalchemy.exc import IntegrityError, NoResultFound
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
|
@ -35,11 +36,11 @@ class ChatDAO(BaseDAO):
|
||||||
Chat.id.label("chat_id"),
|
Chat.id.label("chat_id"),
|
||||||
Chat.chat_for,
|
Chat.chat_for,
|
||||||
Chat.chat_name,
|
Chat.chat_name,
|
||||||
Users.avatar_image
|
Chat.created_by,
|
||||||
|
Chat.avatar_image
|
||||||
)
|
)
|
||||||
.select_from(Chat)
|
.select_from(Chat)
|
||||||
.join(UserChat, Chat.id == UserChat.chat_id)
|
.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)
|
.where(UserChat.chat_id == chat_id, UserChat.user_id == user_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,8 +50,12 @@ class ChatDAO(BaseDAO):
|
||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
raise ChatNotFoundException
|
raise ChatNotFoundException
|
||||||
|
|
||||||
async def create_chat(self, user_id: int, chat_name: str, created_by: int) -> int:
|
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).returning(Chat.id)
|
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)
|
result = await self.session.execute(stmt)
|
||||||
chat_id = result.scalar()
|
chat_id = result.scalar()
|
||||||
|
@ -200,6 +205,14 @@ class ChatDAO(BaseDAO):
|
||||||
)
|
)
|
||||||
await self.session.execute(stmt)
|
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:
|
async def delete_chat(self, chat_id: int) -> None:
|
||||||
stmt = update(Chat).where(Chat.id == chat_id).values(visibility=False)
|
stmt = update(Chat).where(Chat.id == chat_id).values(visibility=False)
|
||||||
await self.session.execute(stmt)
|
await self.session.execute(stmt)
|
||||||
|
@ -229,13 +242,13 @@ class ChatDAO(BaseDAO):
|
||||||
"chat_id", Chat.id,
|
"chat_id", Chat.id,
|
||||||
"chat_for", Chat.chat_for,
|
"chat_for", Chat.chat_for,
|
||||||
"chat_name", Chat.chat_name,
|
"chat_name", Chat.chat_name,
|
||||||
"avatar_image", Users.avatar_image,
|
"created_by", Chat.created_by,
|
||||||
|
"avatar_image", Chat.avatar_image,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.select_from(PinnedChat)
|
.select_from(PinnedChat)
|
||||||
.join(Users, PinnedChat.user_id == Users.id)
|
|
||||||
.join(Chat, PinnedChat.chat_id == Chat.id)
|
.join(Chat, PinnedChat.chat_id == Chat.id)
|
||||||
.where(PinnedChat.user_id == user_id, Chat.visibility == True) # noqa: E712
|
.where(PinnedChat.user_id == user_id, Chat.visibility == True) # noqa: E712
|
||||||
)
|
)
|
||||||
|
|
|
@ -92,14 +92,14 @@ class UserDAO(BaseDAO):
|
||||||
"chat_id", Chat.id,
|
"chat_id", Chat.id,
|
||||||
"chat_for", Chat.chat_for,
|
"chat_for", Chat.chat_for,
|
||||||
"chat_name", Chat.chat_name,
|
"chat_name", Chat.chat_name,
|
||||||
"avatar_image", Users.avatar_image,
|
"created_by", Chat.created_by,
|
||||||
|
"avatar_image", Chat.avatar_image,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.select_from(UserChat)
|
.select_from(UserChat)
|
||||||
.join(Chat, Chat.id == UserChat.chat_id)
|
.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
|
.where(UserChat.user_id == user_id, Chat.visibility == True) # noqa: E712
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"""Database Creation
|
"""Database Creation
|
||||||
|
|
||||||
Revision ID: 4668313943c0
|
Revision ID: c69369209bab
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2024-06-08 18:36:31.974804
|
Create Date: 2024-06-13 18:40:03.297322
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from typing import Sequence, Union
|
from typing import Sequence, Union
|
||||||
|
@ -12,7 +12,7 @@ import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision: str = '4668313943c0'
|
revision: str = 'c69369209bab'
|
||||||
down_revision: Union[str, None] = None
|
down_revision: Union[str, None] = None
|
||||||
branch_labels: Union[str, Sequence[str], None] = None
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
depends_on: 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('created_by', sa.Integer(), nullable=False),
|
||||||
sa.Column('chat_for', sa.Integer(), nullable=True),
|
sa.Column('chat_for', sa.Integer(), nullable=True),
|
||||||
sa.Column('chat_name', sa.String(), nullable=False),
|
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.Column('visibility', sa.Boolean(), server_default='true', nullable=False),
|
||||||
sa.ForeignKeyConstraint(['chat_for'], ['users.id'], ),
|
sa.ForeignKeyConstraint(['chat_for'], ['users.id'], ),
|
||||||
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
|
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
|
|
@ -11,4 +11,5 @@ class Chat(Base):
|
||||||
created_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
created_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
||||||
chat_for = mapped_column(ForeignKey("users.id"))
|
chat_for = mapped_column(ForeignKey("users.id"))
|
||||||
chat_name: Mapped[str]
|
chat_name: Mapped[str]
|
||||||
|
avatar_image: Mapped[str]
|
||||||
visibility: Mapped[bool] = mapped_column(server_default="true")
|
visibility: Mapped[bool] = mapped_column(server_default="true")
|
||||||
|
|
|
@ -9,7 +9,7 @@ def get_redis_session() -> Redis:
|
||||||
|
|
||||||
class RedisService:
|
class RedisService:
|
||||||
@staticmethod
|
@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)
|
await redis.setex(f"user_verification_code: {user_id}", 1800, verification_code)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -18,7 +18,7 @@ class RedisService:
|
||||||
return verification_code.decode()
|
return verification_code.decode()
|
||||||
|
|
||||||
@staticmethod
|
@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}")
|
await redis.delete(f"user_verification_code: {user_id}")
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 478 KiB |
Binary file not shown.
Before Width: | Height: | Size: 34 KiB |
|
@ -112,6 +112,26 @@ async def register_user(user_data: SUserRegister, uow=Depends(UnitOfWork)):
|
||||||
return {"authorization": f"Bearer {access_token}"}
|
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(
|
@router.get(
|
||||||
"/email_verification/{user_code}",
|
"/email_verification/{user_code}",
|
||||||
status_code=status.HTTP_200_OK,
|
status_code=status.HTTP_200_OK,
|
||||||
|
|
Loading…
Add table
Reference in a new issue