Убрал лишнее

This commit is contained in:
urec56 2024-06-01 19:59:52 +05:00
parent e87109dde5
commit d1e8e80be6
10 changed files with 269 additions and 128 deletions

View file

@ -16,13 +16,21 @@ from app.users.schemas import SCreateInvitationLink, SUserAddedToChat
router = APIRouter(prefix="/chat", tags=["Чат"])
@router.get("", response_model=list[SChat])
@router.get(
"",
status_code=status.HTTP_200_OK,
response_model=list[SChat]
)
async def get_all_chats(user: Users = 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)
@router.post(
"",
status_code=status.HTTP_201_CREATED,
response_model=None,
)
async def add_message_to_chat(chat_id: int, message: str, user: Users = Depends(check_verificated_user_with_exc)):
chats = await AuthService.get_user_allowed_chats_id(user.id)
if chat_id not in chats:
@ -35,7 +43,11 @@ async def add_message_to_chat(chat_id: int, message: str, user: Users = Depends(
return send_message_to_chat
@router.delete("/delete_message", status_code=status.HTTP_204_NO_CONTENT)
@router.delete(
"/delete_message",
status_code=status.HTTP_200_OK,
response_model=None,
)
async def delete_message_from_chat(message_id: int, user: Users = 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:
@ -47,7 +59,11 @@ async def delete_message_from_chat(message_id: int, user: Users = Depends(check_
return deleted_message
@router.post("/create_chat", status_code=status.HTTP_201_CREATED)
@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: Users = Depends(check_verificated_user_with_exc)):
if user.id == user_to_exclude:
raise UserCanNotReadThisChatException
@ -57,7 +73,11 @@ async def create_chat(user_to_exclude: int, chat_name: str, user: Users = Depend
return user_added_to_chat
@router.get("/get_last_message/{chat_id}", response_model=list[SMessage])
@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: Users = 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)
@ -68,13 +88,18 @@ async def get_last_message(chat_id: int, user: Users = Depends(check_verificated
return message
@router.get("/get_some_messages/{chat_id}", response_model=list[SMessage])
@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: Users = Depends(check_verificated_user_with_exc)
chat_id: int, last_messages: SLastMessages = Depends(), user: Users = 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
chat_id=chat_id, message_number_from=last_messages.messages_loaded,
messages_to_get=last_messages.messages_to_get
)
if not messages:
raise MessageNotFoundException
@ -83,7 +108,11 @@ async def get_some_messages(
return messages
@router.get("/message/{chat_id}", response_model=SMessage)
@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: Users = 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)
@ -94,7 +123,11 @@ async def get_message_by_id(chat_id: int, message_id: int, user: Users = Depends
return message
@router.get("/create_invitation_link", response_model=SCreateInvitationLink, status_code=status.HTTP_201_CREATED)
@router.get(
"/create_invitation_link",
status_code=status.HTTP_201_CREATED,
response_model=SCreateInvitationLink,
)
async def create_invitation_link(chat_id: int, user: Users = 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)
@ -103,7 +136,11 @@ async def create_invitation_link(chat_id: int, user: Users = Depends(check_verif
return {"invitation_link": invitation_link}
@router.get("/invite_to_chat/{invitation_token}", response_model=SUserAddedToChat, status_code=status.HTTP_200_OK)
@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: Users = Depends(check_verificated_user_with_exc)):
invitation_token = invitation_token.encode()
cipher_suite = Fernet(settings.INVITATION_LINK_TOKEN_KEY)
@ -114,7 +151,11 @@ async def invite_to_chat(invitation_token: str, user: Users = Depends(check_veri
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}", response_model=SDeletedChat, status_code=status.HTTP_200_OK)
@router.delete(
"/delete_chat/{chat_id}",
status_code=status.HTTP_200_OK,
response_model=SDeletedChat,
)
async def delete_chat(chat_id: int, user: Users = Depends(check_verificated_user_with_exc)):
chat = await ChatDAO.find_one_or_none(id=chat_id)
if user.id == chat.created_by:
@ -122,7 +163,11 @@ async def delete_chat(chat_id: int, user: Users = Depends(check_verificated_user
raise UserDontHavePermissionException
@router.delete("/delete_user_from_chat/{chat_id}", response_model=SDeletedUser)
@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: Users = Depends(check_verificated_user_with_exc)):
chat = await ChatDAO.find_one_or_none(id=chat_id)
if user.id == chat.created_by:
@ -130,33 +175,53 @@ async def delete_user_from_chat(chat_id: int, user_id: int, user: Users = Depend
raise UserDontHavePermissionException
@router.post("/pinn_chat", response_model=SPinnedChat)
@router.post(
"/pin_chat",
status_code=status.HTTP_200_OK,
response_model=SPinnedChat
)
async def pinn_chat(chat_id: int, user: Users = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.pinn_chat(chat_id=chat_id, user_id=user.id)
return {"chat_id": chat_id, "user_id": user.id}
@router.delete("/unpinn_chat", response_model=SPinnedChat)
@router.delete(
"/unpin_chat",
status_code=status.HTTP_200_OK,
response_model=SPinnedChat
)
async def unpinn_chat(chat_id: int, user: Users = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.unpinn_chat(chat_id=chat_id, user_id=user.id)
return {"chat_id": chat_id, "user_id": user.id}
@router.get("/get_pinned_chats", response_model=list[SChat])
@router.get(
"/get_pinned_chats",
status_code=status.HTTP_200_OK,
response_model=list[SChat]
)
async def get_pinned_chats(user: Users = Depends(check_verificated_user_with_exc)):
return await ChatDAO.get_pinned_chats(user_id=user.id)
@router.post("/pinn_message", response_model=SPinnedMessage)
@router.post(
"/pin_message",
status_code=status.HTTP_200_OK,
response_model=SPinnedMessage
)
async def pinn_message(chat_id: int, message_id: int, user: Users = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
await ChatDAO.pinn_message(chat_id=chat_id, message_id=message_id, user_id=user.id)
return {"message_id": message_id, "user_id": user.id, "chat_id": chat_id}
@router.delete("/unpinn_message", response_model=SPinnedMessage)
@router.delete(
"/unpin_message",
status_code=status.HTTP_200_OK,
response_model=SPinnedMessage
)
async def unpinn_message(chat_id: int, message_id: int, user: Users = Depends(check_verificated_user_with_exc)):
await AuthService.validate_user_access_to_chat(chat_id=chat_id, user_id=user.id)
message_pinner = await ChatDAO.get_message_pinner(chat_id=chat_id, message_id=message_id)
@ -166,7 +231,11 @@ async def unpinn_message(chat_id: int, message_id: int, user: Users = Depends(ch
raise UserDontHavePermissionException
@router.get("/pinned_messages/{chat_id}", response_model=list[SMessage] | None)
@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: Users = 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)

View file

@ -19,14 +19,9 @@ class SMessage(BaseModel):
answer_id: int | None
class SLastMessages:
def __init__(
self,
messages_loaded: int,
messages_to_get: int,
):
self.messages_loaded = messages_loaded
self.messages_to_get = messages_to_get
class SLastMessages(BaseModel):
messages_loaded: int
messages_to_get: int
class SPinnedMessage(BaseModel):
@ -75,3 +70,14 @@ class SEditMessage(BaseModel):
id: int
new_message: str
new_image_url: str
class SPinMessage(BaseModel):
flag: str
id: int
user_id: int
class SUnpinMessage(BaseModel):
flag: str
id: int

View file

@ -1,13 +1,15 @@
from fastapi import WebSocket, WebSocketDisconnect
from fastapi import WebSocket, WebSocketDisconnect, Depends
from app.exceptions import IncorrectDataException, UserDontHavePermissionException
from app.services.message_service import MessageService
from app.users.auth import AuthService
from app.chat.router import router
from app.chat.shemas import SSendMessage, SMessage, SDeleteMessage, SEditMessage
from app.chat.shemas import SSendMessage, SMessage, SDeleteMessage, SEditMessage, SPinMessage, SUnpinMessage
from app.users.dependencies import get_current_user_ws
from app.users.schemas import SUser
class ConnectionManager(WebSocket):
class ConnectionManager:
def __init__(self):
self.active_connections: dict[int, list[WebSocket]] = {}
@ -49,12 +51,25 @@ class ConnectionManager(WebSocket):
edited_message = await self.edit_message(message.id, message.new_message, message.new_image_url)
new_message = {
"edited_message": edited_message,
"flag": "edit",
"id": message.id,
"edited_message": edited_message,
"new_message": message.new_message,
"new_image_url": message.new_image_url,
}
elif message["flag"] == "pin":
message = SPinMessage.model_validate(message)
pinned_message = await self.pin_message(chat_id=chat_id, user_id=message.user_id, message_id=message.id)
new_message = pinned_message.model_dump()
new_message["created_at"] = new_message["created_at"].isoformat()
new_message["flag"] = "pin"
elif message["flag"] == "unpin":
message = SUnpinMessage.model_validate(message)
unpinned_message = await self.unpin_message(chat_id=chat_id, message_id=message.id)
new_message = {"flag": "pin", "id": unpinned_message}
else:
raise IncorrectDataException
@ -82,19 +97,31 @@ class ConnectionManager(WebSocket):
)
return new_message
@staticmethod
async def pin_message(chat_id: int, user_id: int, message_id: int) -> SMessage:
pinned_message = await MessageService.pin_message(chat_id=chat_id, user_id=user_id, message_id=message_id)
return pinned_message
@staticmethod
async def unpin_message(chat_id: int, message_id: int) -> int:
unpinned_message_id = await MessageService.unpin_message(chat_id=chat_id, message_id=message_id)
return unpinned_message_id
manager = ConnectionManager()
@router.websocket("/ws/{chat_id}")
async def websocket_endpoint(chat_id: int, user_id: int, websocket: WebSocket):
await AuthService.check_verificated_user_with_exc(user_id=user_id)
await AuthService.validate_user_access_to_chat(user_id=user_id, chat_id=chat_id)
@router.websocket(
"/ws/{chat_id}",
)
async def websocket_endpoint(chat_id: int, websocket: WebSocket, user: SUser = Depends(get_current_user_ws)):
await AuthService.check_verificated_user_with_exc(user_id=user.id)
await AuthService.validate_user_access_to_chat(user_id=user.id, chat_id=chat_id)
await manager.connect(chat_id, websocket)
try:
while True:
data = await websocket.receive_json()
await manager.broadcast(user_id=user_id, chat_id=chat_id, message=data)
await manager.broadcast(user_id=user.id, chat_id=chat_id, message=data)
except WebSocketDisconnect:
manager.disconnect(chat_id, websocket)

View file

@ -1,4 +1,4 @@
from fastapi import APIRouter, UploadFile, HTTPException
from fastapi import APIRouter, UploadFile, HTTPException, status
import httpx
from app.config import settings
@ -36,19 +36,31 @@ async def upload_avatar_returning_dict(file: UploadFile, sub_str: str) -> dict:
return {"image_url": image_url, "hex_color": hex_color}
@router.post("/upload_avatar", response_model=SAvatarUrl)
@router.post(
"/upload_avatar",
status_code=status.HTTP_200_OK,
response_model=SAvatarUrl
)
async def upload_avatar(file: UploadFile):
image_data = await upload_avatar_returning_dict(file, "upload_avatar")
return image_data
@router.post("/upload_image", response_model=SImageUrl)
@router.post(
"/upload_image",
status_code=status.HTTP_200_OK,
response_model=SImageUrl
)
async def upload_image(file: UploadFile):
image_url = await upload_file_returning_str(file, "upload_image")
return {"image_url": image_url}
@router.post("/upload_background", response_model=list[SImageUrl])
@router.post(
"/upload_background",
status_code=status.HTTP_200_OK,
response_model=list[SImageUrl]
)
async def upload_background(file: UploadFile):
remote_server_url = settings.IMAGE_UPLOAD_SERVER + "upload_background"
response = await upload_file(file, remote_server_url)

View file

@ -22,3 +22,11 @@ class MessageService:
async def edit_message(message_id: int, new_message: str, new_image_url: str) -> bool:
new_message = await ChatDAO.edit_message(message_id=message_id, new_message=new_message, new_image_url=new_image_url)
return new_message
@staticmethod
async def pin_message(chat_id: int, user_id: int, message_id: int):
pass
@staticmethod
async def unpin_message(chat_id: int, message_id: int):
pass

View file

@ -1,4 +1,4 @@
from datetime import datetime, timedelta
from datetime import datetime, timedelta, UTC
from jose import jwt
from passlib.context import CryptContext
@ -32,10 +32,9 @@ def verify_password(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
# Функция создания JWT токена
def create_access_token(data: dict) -> str:
to_encode = data.copy()
expire = datetime.utcnow() + timedelta(minutes=180)
expire = datetime.now(UTC) + timedelta(days=30)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, settings.ALGORITHM)
return encoded_jwt

View file

@ -13,7 +13,7 @@ class UserDAO(BaseDAO):
model = Users
@staticmethod
async def find_one_or_none(**filter_by) -> SUser | None: # Метод проверяет наличие строки с заданными параметрами
async def find_one_or_none(**filter_by) -> SUser | None:
async with async_session_maker() as session:
query = select(Users).filter_by(**filter_by)
result = await session.execute(query)
@ -117,8 +117,8 @@ class UserDAO(BaseDAO):
return True
@staticmethod
async def get_user_avatars(user_id: int) -> list[Mapping[str, str | int]]:
query = select(UsersAvatars.avatar_image, UsersAvatars.id).where(UsersAvatars.user_id == user_id)
async def get_user_avatars(user_id: int) -> list[Mapping[str, str]]:
query = select(UsersAvatars.avatar_image).where(UsersAvatars.user_id == user_id)
async with async_session_maker() as session:
result = await session.execute(query)
result = result.mappings().all()

View file

@ -1,7 +1,7 @@
from datetime import datetime
from datetime import datetime, UTC
from fastapi import Depends, Request, Response
from jose import JWTError, jwt
from fastapi import Depends, Request, Response, WebSocket
from jose import JWTError, jwt, ExpiredSignatureError
from app.config import settings
from app.exceptions import (
@ -26,13 +26,11 @@ def get_token(request: Request) -> str:
async def get_current_user(response: Response, token: str = Depends(get_token)) -> SUser:
try:
payload = jwt.decode(token, settings.SECRET_KEY, settings.ALGORITHM)
except ExpiredSignatureError:
raise TokenExpiredException
except JWTError:
raise IncorrectTokenFormatException
expire: str = payload.get("exp")
if not expire or int(expire) < datetime.utcnow().timestamp():
raise TokenExpiredException
user_id: str = payload.get("sub")
if not user_id:
raise UserIsNotPresentException
@ -50,3 +48,29 @@ async def check_verificated_user_with_exc(user: SUser = Depends(get_current_user
if not user.role >= VERIFICATED_USER:
raise UserMustConfirmEmailException
return user
def get_token_ws(websocket: WebSocket) -> str:
token = websocket.cookies.get("black_phoenix_access_token")
if not token:
raise TokenAbsentException
return token
async def get_current_user_ws(token: str = Depends(get_token_ws)):
try:
payload = jwt.decode(token, settings.SECRET_KEY, settings.ALGORITHM)
except ExpiredSignatureError:
raise TokenExpiredException
except JWTError:
raise IncorrectTokenFormatException
user_id: str = payload.get("sub")
if not user_id:
raise UserIsNotPresentException
user = await UserService.find_one_or_none(user_id=int(user_id))
if not user:
raise UserIsNotPresentException
return user

View file

@ -2,74 +2,78 @@ import json
from cryptography.fernet import Fernet
from fastapi import APIRouter, Response, Depends, status
from fastapi.responses import RedirectResponse
from app.config import settings
from app.exceptions import (
UsernameAlreadyInUseException,
IncorrectPasswordException,
PasswordsMismatchException,
WrongCodeException,
UserNotFoundException,
SomethingWentWrongException,
UserAlreadyExistsException,
)
from app.users.auth import get_password_hash, create_access_token, verify_password, VERIFICATED_USER, AuthService
from app.users.auth import get_password_hash, create_access_token, VERIFICATED_USER, AuthService
from app.users.dao import UserDAO, UserCodesDAO
from app.users.dependencies import get_current_user, check_verificated_user_with_exc
from app.users.dependencies import get_current_user
from app.users.models import Users
from app.users.schemas import (
SUserLogin,
SUserRegister,
SUserResponse,
SUserPassword,
SUserRename,
SUserAvatar,
SUserPasswordRecover,
SUserCode,
SUserPasswordChange,
SRecoverEmailSent,
SUserToken,
SEmailVerification,
SUserName,
SNewAvatar,
SConfirmPasswordRecovery,
SPasswordRecovered,
SUserAvatars,
SUsername,
SEmail,
)
from app.tasks.tasks import send_registration_confirmation_email, send_password_change_email, send_password_recover_email
from app.tasks.tasks import send_registration_confirmation_email, send_password_change_email, \
send_password_recover_email
router = APIRouter(prefix="/users", tags=["Пользователи"])
@router.get("/teleport", response_class=RedirectResponse, status_code=status.HTTP_307_TEMPORARY_REDIRECT)
async def get_teleport():
return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
@router.get("", response_model=list[SUserResponse])
@router.get(
"",
status_code=status.HTTP_200_OK,
response_model=list[SUserResponse]
)
async def get_all_users():
users = await UserDAO.find_all()
return users
@router.post("/check_existing_username", status_code=status.HTTP_200_OK)
@router.post(
"/check_existing_username",
status_code=status.HTTP_200_OK,
response_model=None
)
async def check_existing_username(username: SUsername):
user = await UserDAO.find_one_or_none(username=username.username)
if user:
raise UserAlreadyExistsException
@router.post("/check_existing_email", status_code=status.HTTP_200_OK)
@router.post(
"/check_existing_email",
status_code=status.HTTP_200_OK,
response_model=None
)
async def check_existing_email(email: SEmail):
user = await UserDAO.find_one_or_none(email=email.email)
if user:
raise UserAlreadyExistsException
@router.post("/register", response_model=SUserToken, status_code=status.HTTP_201_CREATED)
@router.post(
"/register",
status_code=status.HTTP_201_CREATED,
response_model=SUserToken,
)
async def register_user(response: Response, user_data: SUserRegister):
if user_data.password != user_data.password2:
raise PasswordsMismatchException
@ -95,7 +99,11 @@ async def register_user(response: Response, user_data: SUserRegister):
return {"access_token": access_token}
@router.get("/email_verification/{user_code}", status_code=status.HTTP_200_OK, response_model=SEmailVerification)
@router.get(
"/email_verification/{user_code}",
status_code=status.HTTP_200_OK,
response_model=SEmailVerification
)
async def email_verification(user_code: str):
invitation_token = user_code.encode()
cipher_suite = Fernet(settings.INVITATION_LINK_TOKEN_KEY)
@ -109,7 +117,11 @@ async def email_verification(user_code: str):
return {"email_verification": True}
@router.post("/login", response_model=SUserToken)
@router.post(
"/login",
status_code=status.HTTP_200_OK,
response_model=SUserToken
)
async def login_user(response: Response, user_data: SUserLogin):
user = await AuthService.authenticate_user(user_data.email_or_username, user_data.password)
access_token = create_access_token({"sub": str(user.id)})
@ -117,51 +129,29 @@ async def login_user(response: Response, user_data: SUserLogin):
return {"access_token": access_token}
@router.post("/logout", status_code=status.HTTP_200_OK)
@router.post(
"/logout",
status_code=status.HTTP_200_OK,
response_model=None
)
async def logout_user(response: Response):
response.delete_cookie("black_phoenix_access_token")
@router.get("/me", response_model=SUserResponse)
async def read_users_me(current_user: Users = Depends(get_current_user)):
@router.get(
"/me",
status_code=status.HTTP_200_OK,
response_model=SUserResponse
)
async def get_user(current_user: Users = Depends(get_current_user)):
return current_user
@router.patch("/rename", response_model=SUserName)
async def rename_user(new_username: SUserRename, current_user: Users = Depends(check_verificated_user_with_exc)):
if not verify_password(new_username.password, current_user.hashed_password):
raise IncorrectPasswordException
existing_user = await UserDAO.find_one_or_none(username=new_username.username)
if existing_user:
raise UsernameAlreadyInUseException
new_username = await UserDAO.change_data(current_user.id, username=new_username.username)
return {"username": new_username}
@router.patch("/change_avatar", response_model=SNewAvatar)
async def change_avatar(user_data: SUserAvatar, current_user: Users = Depends(check_verificated_user_with_exc)):
if not verify_password(user_data.password, current_user.hashed_password):
raise IncorrectPasswordException
if await UserDAO.change_data(
current_user.id, avatar_image=user_data.new_avatar_image, avatar_hex=user_data.avatar_hex
) and await UserDAO.add_user_avatar(user_id=current_user.id, avatar=user_data.new_avatar_image):
return {"new_avatar_image": user_data.new_avatar_image, "avatar_hex": user_data.avatar_hex}
raise SomethingWentWrongException
@router.patch("/change_password", status_code=status.HTTP_200_OK)
async def change_password(new_password: SUserPassword, current_user: Users = Depends(check_verificated_user_with_exc)):
if new_password.new_password != new_password.new_password2:
raise PasswordsMismatchException
existing_user = await UserDAO.find_one_or_none(id=current_user.id)
if not verify_password(new_password.current_password, existing_user.hashed_password):
raise IncorrectPasswordException
hashed_password = get_password_hash(new_password.new_password)
await UserDAO.change_data(current_user.id, hashed_password=hashed_password)
send_password_change_email.delay(current_user.username, current_user.email, MODE=settings.MODE)
@router.patch("/send_recovery_email", status_code=status.HTTP_200_OK, response_model=SRecoverEmailSent)
@router.patch(
"/send_recovery_email",
status_code=status.HTTP_200_OK,
response_model=SRecoverEmailSent
)
async def send_recovery_email(email: SUserPasswordRecover):
existing_user = await UserDAO.find_one_or_none(email=email.email)
if not existing_user:
@ -170,16 +160,20 @@ async def send_recovery_email(email: SUserPasswordRecover):
result = result.get()
if (
await UserCodesDAO.set_user_codes(
user_id=existing_user.user_id, code=result, description="Код восстановления пароля"
)
== result
await UserCodesDAO.set_user_codes(
user_id=existing_user.user_id, code=result, description="Код восстановления пароля"
)
== result
):
return {"recover_email_sent": True}
raise SomethingWentWrongException
@router.post("/confirm_password_recovery", status_code=status.HTTP_200_OK, response_model=SConfirmPasswordRecovery)
@router.post(
"/confirm_password_recovery",
status_code=status.HTTP_200_OK,
response_model=SConfirmPasswordRecovery
)
async def confirm_password_recovery(user_code: SUserCode):
user_codes = await UserCodesDAO.get_user_codes(description="Код восстановления пароля", code=user_code.user_code)
if not user_codes:
@ -187,7 +181,11 @@ async def confirm_password_recovery(user_code: SUserCode):
return {"user_id": user_codes[0]["user_id"]}
@router.post("/password_recovery", status_code=status.HTTP_200_OK, response_model=SPasswordRecovered)
@router.post(
"/password_recovery",
status_code=status.HTTP_200_OK,
response_model=SPasswordRecovered
)
async def password_recovery(passwords: SUserPasswordChange):
if passwords.password1 != passwords.password2:
raise PasswordsMismatchException
@ -200,11 +198,10 @@ async def password_recovery(passwords: SUserPasswordChange):
return {"username": username}
@router.get("/avatars", response_model=list[SUserAvatars])
@router.get(
"/avatars",
status_code=status.HTTP_200_OK,
response_model=list[SUserAvatars]
)
async def get_user_avatars_history(user: Users = Depends(get_current_user)):
return await UserDAO.get_user_avatars(user_id=user.id)
@router.delete("/avatars", response_model=bool)
async def delete_form_user_avatars_history(avatar_id: int, user: Users = Depends(get_current_user)):
return await UserDAO.delete_user_avatar(avatar_id=avatar_id, user_id=user.id)

View file

@ -1,7 +1,7 @@
from datetime import date, timedelta, datetime, time
from pydantic_core import PydanticCustomError
from pydantic import BaseModel, EmailStr, ConfigDict, field_validator
from pydantic import BaseModel, EmailStr, ConfigDict, field_validator, HttpUrl
from fastapi import Query
@ -128,8 +128,7 @@ class SUserAddedToChat(BaseModel):
class SUserAvatars(BaseModel):
id: int
avatar_image: str
avatar_image: HttpUrl
class SUsername(BaseModel):