chat_back/app/users/router.py
2024-07-16 18:18:28 +04:00

318 lines
9.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from random import randrange
from fastapi import APIRouter, Depends, status
from app.services.user_service import UserService
from app.users.exceptions import UserAlreadyExistsException, PasswordAlreadyInUseException, UserNotFoundException
from app.utils.unit_of_work import UnitOfWork
from app.utils.auth import (
create_access_token,
AuthService,
get_confirmation_code
)
from app.users.dependencies import get_current_user
from app.users.schemas import (
SUserLogin,
SUserRegister,
SUserResponse,
SUserAvatars,
SUserFilter,
SUser,
SUserChangeData,
SUserSendConfirmationCode,
STokenLogin,
SUsers,
SUserPassword,
SGetUsersFilter,
SUserCode, Responses,
)
router = APIRouter(prefix="/users", tags=["Пользователи"])
@router.get(
"",
status_code=status.HTTP_200_OK,
response_model=SUsers,
responses={
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def get_all_users(filter_by=Depends(SGetUsersFilter), uow=Depends(UnitOfWork)):
users = await UserService.find_all(uow=uow, username=filter_by.username)
return users
@router.post(
"/check_existing_user",
status_code=status.HTTP_200_OK,
response_model=None,
responses={
status.HTTP_409_CONFLICT: {
"model": Responses.SUserAlreadyExistsException,
"description": "Пользователь с таким ником или почтой уже существует"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def check_existing_user(user_filter: SUserFilter, uow=Depends(UnitOfWork)):
try:
await UserService.find_user(uow=uow, **user_filter.model_dump(exclude_none=True))
raise UserAlreadyExistsException
except UserNotFoundException:
pass
@router.post(
"/check_existing_password",
status_code=status.HTTP_200_OK,
response_model=None,
responses={
status.HTTP_409_CONFLICT: {
"model": Responses.SPasswordAlreadyInUseException,
"description": "Пароль уже занят"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def check_existing_password(_: SUserPassword):
random_int = randrange(10)
if random_int > 5:
raise PasswordAlreadyInUseException
@router.post(
"/register",
status_code=status.HTTP_201_CREATED,
response_model=STokenLogin,
responses={
status.HTTP_409_CONFLICT: {
"model": Responses.SPasswordsMismatchException,
"description": "Пароли не совпадают"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def register_user(user_data: SUserRegister, uow=Depends(UnitOfWork)):
user = await UserService.add_user(uow=uow, user_data=user_data)
await UserService.send_confirmation_email(user=user, mail_type="registration")
access_token = create_access_token({"sub": str(user.id)})
return {"authorization": f"Bearer {access_token}"}
@router.post(
"/resend_email_verification",
status_code=status.HTTP_200_OK,
response_model=None,
responses={
status.HTTP_401_UNAUTHORIZED: {
"model": Responses.STokenMissingException,
"description": "Токен отсутствует"
},
status.HTTP_403_FORBIDDEN: {
"model": Responses.SNotAuthenticated,
"description": "Not authenticated"
},
status.HTTP_404_NOT_FOUND: {
"model": Responses.SUserNotFoundException,
"description": "Юзер не найден"
},
status.HTTP_409_CONFLICT: {
"model": Responses.SIncorrectDataException,
"description": "Ты передал какую-то хуйню"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def resend_email_verification(user: SUser = Depends(get_current_user)):
await UserService.send_confirmation_email(user=user, mail_type="registration")
@router.post(
"/email_verification",
status_code=status.HTTP_200_OK,
response_model=None,
responses={
status.HTTP_401_UNAUTHORIZED: {
"model": Responses.STokenMissingException,
"description": "Токен отсутствует"
},
status.HTTP_403_FORBIDDEN: {
"model": Responses.SNotAuthenticated,
"description": "Not authenticated"
},
status.HTTP_404_NOT_FOUND: {
"model": Responses.SUserNotFoundException,
"description": "Юзер не найден"
},
status.HTTP_409_CONFLICT: {
"model": Responses.SWrongCodeException,
"description": "Введён не верный код подтверждения"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def email_verification(user_code: SUserCode, user: SUser = Depends(get_current_user), uow=Depends(UnitOfWork)):
confirmation_code = get_confirmation_code(user_code.user_code)
await UserService.verificate_user(uow=uow, user=user, confirmation_code=confirmation_code)
@router.post(
"/login",
status_code=status.HTTP_200_OK,
response_model=STokenLogin,
responses={
status.HTTP_401_UNAUTHORIZED: {
"model": Responses.SIncorrectAuthDataException,
"description": "Введены не верные данные"
},
status.HTTP_409_CONFLICT: {
"model": Responses.SIncorrectDataException,
"description": "Ты передал какую-то хуйню"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def login_user(user_data: SUserLogin, uow=Depends(UnitOfWork)):
user = await AuthService.authenticate_user(
uow=uow, email_or_username=user_data.email_or_username, password=user_data.password
)
access_token = create_access_token({"sub": str(user.id)})
return {"authorization": f"Bearer {access_token}"}
@router.get(
"/me",
status_code=status.HTTP_200_OK,
response_model=SUserResponse,
responses={
status.HTTP_401_UNAUTHORIZED: {
"model": Responses.STokenMissingException,
"description": "Токен отсутствует"
},
status.HTTP_403_FORBIDDEN: {
"model": Responses.SNotAuthenticated,
"description": "Not authenticated"
},
status.HTTP_404_NOT_FOUND: {
"model": Responses.SUserNotFoundException,
"description": "Юзер не найден"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def get_user(user: SUser = Depends(get_current_user)):
return user
@router.get(
"/avatars",
status_code=status.HTTP_200_OK,
response_model=SUserAvatars,
responses={
status.HTTP_401_UNAUTHORIZED: {
"model": Responses.STokenMissingException,
"description": "Токен отсутствует"
},
status.HTTP_403_FORBIDDEN: {
"model": Responses.SNotAuthenticated,
"description": "Not authenticated"
},
status.HTTP_404_NOT_FOUND: {
"model": Responses.SUserNotFoundException,
"description": "Юзер не найден"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def get_user_avatars_history(user=Depends(get_current_user), uow=Depends(UnitOfWork)):
user_avatars = await UserService.get_user_avatars_history(uow=uow, user_id=user.id)
return user_avatars
@router.post(
"/send_confirmation_code",
status_code=status.HTTP_200_OK,
response_model=None,
responses={
status.HTTP_401_UNAUTHORIZED: {
"model": Responses.STokenMissingException,
"description": "Токен отсутствует"
},
status.HTTP_403_FORBIDDEN: {
"model": Responses.SNotAuthenticated,
"description": "Not authenticated"
},
status.HTTP_404_NOT_FOUND: {
"model": Responses.SUserNotFoundException,
"description": "Юзер не найден"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def send_confirmation_code(user_data: SUserSendConfirmationCode, user: SUser = Depends(get_current_user)):
await UserService.send_confirmation_email(user=user, mail_type="data_change_confirmation", email=user_data.email)
@router.post(
"/change_data",
status_code=status.HTTP_200_OK,
response_model=None,
responses={
status.HTTP_401_UNAUTHORIZED: {
"model": Responses.STokenMissingException,
"description": "Токен отсутствует"
},
status.HTTP_403_FORBIDDEN: {
"model": Responses.SNotAuthenticated,
"description": "Not authenticated"
},
status.HTTP_404_NOT_FOUND: {
"model": Responses.SUserNotFoundException,
"description": "Юзер не найден"
},
status.HTTP_409_CONFLICT: {
"model": Responses.SWrongCodeException,
"description": "Введён не верный код подтверждения"
},
status.HTTP_500_INTERNAL_SERVER_ERROR: {
"model": Responses.SBlackPhoenixException,
"description": "Внутренняя ошибка сервера"
},
},
)
async def change_user_data(
user_data: SUserChangeData, user: SUser = Depends(get_current_user), uow=Depends(UnitOfWork)
):
await UserService.change_data(uow=uow, user=user, user_data=user_data)