Отредактированна регистрация

This commit is contained in:
urec56 2024-02-10 17:23:45 +03:00
parent 70653e71e2
commit 28efd76c70
9 changed files with 57 additions and 24 deletions

View file

@ -2,7 +2,7 @@ from sqladmin.authentication import AuthenticationBackend
from starlette.requests import Request from starlette.requests import Request
from app.config import settings from app.config import settings
from app.users.auth import authenticate_user_by_username, create_access_token from app.users.auth import authenticate_user_by_username, create_access_token, validate_user_admin
from app.users.dependencies import get_current_user from app.users.dependencies import get_current_user
ADMIN_ROLE = 100 ADMIN_ROLE = 100
@ -32,11 +32,9 @@ class AdminAuth(AuthenticationBackend):
return False return False
user = await get_current_user(token) user = await get_current_user(token)
if not user or user.role != ADMIN_ROLE: if user:
return False return await validate_user_admin(user.id)
return False
# Check the token in depth
return True
authentication_backend = AdminAuth(secret_key=settings.SECRET_KEY) authentication_backend = AdminAuth(secret_key=settings.SECRET_KEY)

View file

@ -9,9 +9,10 @@ class BaseDAO:
@classmethod @classmethod
async def add(cls, **data): # Метод добавляет данные в БД async def add(cls, **data): # Метод добавляет данные в БД
async with async_session_maker() as session: async with async_session_maker() as session:
query = insert(cls.model).values(**data) query = insert(cls.model).values(**data).returning(cls.model.id)
await session.execute(query) result = await session.execute(query)
await session.commit() await session.commit()
return result.scalar()
@classmethod @classmethod
async def find_one_or_none(cls, **filter_by): # Метод проверяет наличие строки с заданными параметрами async def find_one_or_none(cls, **filter_by): # Метод проверяет наличие строки с заданными параметрами

View file

@ -64,6 +64,6 @@ class PasswordsМismatchException(BlackPhoenixException):
detail = "Пароли не совпадают" detail = "Пароли не совпадают"
class UsersIdIsTheSameException(BlackPhoenixException): class UserCanNotReadThisChatException(BlackPhoenixException):
status_code = status.HTTP_409_CONFLICT status_code = status.HTTP_409_CONFLICT
detail = "Айди юзеров совпадают" detail = "Юзер не может читать этот чат"

View file

@ -8,3 +8,5 @@ celery = Celery(
broker=f'redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}', broker=f'redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}',
include=['app.tasks.tasks'] include=['app.tasks.tasks']
) )
celery.conf.update(result_backend=f'redis://{settings.REDIS_HOST}:{settings.REDIS_PORT}')

View file

@ -32,3 +32,5 @@ def send_registration_confirmation_email(
server.login(settings.SMTP_USER, settings.SMTP_PASS) server.login(settings.SMTP_USER, settings.SMTP_PASS)
server.send_message(msg_content) server.send_message(msg_content)
return confirmation_code

View file

@ -11,6 +11,8 @@ from app.users.models import Users
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
ADMIN_ROLE = 100
def get_password_hash(password: str) -> str: def get_password_hash(password: str) -> str:
return pwd_context.hash(password) return pwd_context.hash(password)
@ -57,3 +59,10 @@ async def validate_user_access_to_chat(user_id: int, chat_id: int):
if not chat_id in user_allowed_chats: if not chat_id in user_allowed_chats:
raise UserDontHavePermissionException raise UserDontHavePermissionException
return True return True
async def validate_user_admin(user_id: int):
user_role = await UserDAO.get_user_role(user_id=user_id)
if user_role == ADMIN_ROLE:
return True
return False

View file

@ -1,12 +1,12 @@
from fastapi import APIRouter, Depends, status from fastapi import APIRouter, Depends, status
from app.exceptions import UserDontHavePermissionException, MessageNotFoundException, UsersIdIsTheSameException from app.exceptions import UserDontHavePermissionException, MessageNotFoundException, UserCanNotReadThisChatException
from app.users.chat.dao import ChatDAO from app.users.chat.dao import ChatDAO
from app.users.chat.shemas import SMessage, SLastMessages from app.users.chat.shemas import SMessage, SLastMessages
from app.users.dao import UserDAO from app.users.dao import UserDAO
from app.users.dependencies import get_current_user from app.users.dependencies import get_current_user
from app.users.auth import validate_user_access_to_chat from app.users.auth import validate_user_access_to_chat, validate_user_admin
from app.users.models import Users from app.users.models import Users
router = APIRouter( router = APIRouter(
@ -44,8 +44,7 @@ async def delete_message_from_chat(
if get_message_sender is None: if get_message_sender is None:
raise MessageNotFoundException raise MessageNotFoundException
if get_message_sender["user_id"] != user.id: if get_message_sender["user_id"] != user.id:
get_user_role = await UserDAO.get_user_role(user_id=user.id) if not await validate_user_admin(user_id=user.id):
if not get_user_role == 1:
raise UserDontHavePermissionException raise UserDontHavePermissionException
deleted_message = await ChatDAO.delete_message(message_id=message_id) deleted_message = await ChatDAO.delete_message(message_id=message_id)
return deleted_message return deleted_message
@ -58,7 +57,7 @@ async def create_chat(
user: Users = Depends(get_current_user) user: Users = Depends(get_current_user)
): ):
if user.id == user_to_exclude: if user.id == user_to_exclude:
raise UsersIdIsTheSameException raise UserCanNotReadThisChatException
created_chat = await ChatDAO.create(user_id=user_to_exclude) created_chat = await ChatDAO.create(user_id=user_to_exclude)
return created_chat return created_chat

View file

@ -1,10 +1,10 @@
from sqlalchemy import update, select from sqlalchemy import update, select, insert
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from app.dao.base import BaseDAO from app.dao.base import BaseDAO
from app.database import async_session_maker from app.database import async_session_maker
from app.users.chat.models import UsersXChats from app.users.chat.models import UsersXChats
from app.users.models import Users from app.users.models import Users, UsersVerificationCodes
class UserDAO(BaseDAO): class UserDAO(BaseDAO):
@ -41,3 +41,21 @@ class UserDAO(BaseDAO):
async with async_session_maker() as session: async with async_session_maker() as session:
result = await session.execute(query) result = await session.execute(query)
return result.scalar() return result.scalar()
class UserCodesDAO(BaseDAO):
model = UsersVerificationCodes
@classmethod
async def set_user_codes(cls, user_id: int, code: str):
query = (insert(UsersVerificationCodes)
.values(user_id=user_id, code=code, description="Код подтверждения почты")
.returning(cls.model.code))
async with async_session_maker() as session:
result = await session.execute(query)
await session.commit()
return result.scalar()
@classmethod
async def get_user_codes(cls, user_id: int):
pass

View file

@ -6,7 +6,7 @@ from app.exceptions import UserAlreadyExistsException, IncorrectAuthDataExceptio
IncorrectPasswordException, PasswordsМismatchException IncorrectPasswordException, PasswordsМismatchException
from app.users.auth import get_password_hash, authenticate_user_by_email, authenticate_user_by_username, \ from app.users.auth import get_password_hash, authenticate_user_by_email, authenticate_user_by_username, \
create_access_token, verify_password create_access_token, verify_password
from app.users.dao import UserDAO from app.users.dao import UserDAO, UserCodesDAO
from app.users.dependencies import get_current_user from app.users.dependencies import get_current_user
from app.users.models import Users from app.users.models import Users
from app.users.schemas import SUserLogin, SUserRegister, SUser, SUserName, SUserPassword from app.users.schemas import SUserLogin, SUserRegister, SUser, SUserName, SUserPassword
@ -38,7 +38,7 @@ async def register_user(response: Response, user_data: SUserRegister):
if existing_user: if existing_user:
raise UserAlreadyExistsException raise UserAlreadyExistsException
hashed_password = get_password_hash(user_data.password) hashed_password = get_password_hash(user_data.password)
await UserDAO.add( user_id = await UserDAO.add(
email=user_data.email, email=user_data.email,
hashed_password=hashed_password, hashed_password=hashed_password,
username=user_data.username, username=user_data.username,
@ -46,11 +46,15 @@ async def register_user(response: Response, user_data: SUserRegister):
role=0, role=0,
black_phoenix=False black_phoenix=False
) )
send_registration_confirmation_email.delay(username=user_data.username, email_to=user_data.email)
user = await authenticate_user_by_email(user_data.email, user_data.password) result = send_registration_confirmation_email.delay(username=user_data.username, email_to=user_data.email)
access_token = create_access_token({"sub": str(user.id)}) result = result.get()
response.set_cookie(key="black_phoenix_access_token", value=access_token, httponly=True)
return {"access_token": access_token} if await UserCodesDAO.set_user_codes(user_id=user_id, code=result) == result:
user = await authenticate_user_by_email(user_data.email, user_data.password)
access_token = create_access_token({"sub": str(user.id)})
response.set_cookie(key="black_phoenix_access_token", value=access_token, httponly=True)
return {"access_token": access_token}
@router.post("/login", response_model=dict[str, str]) @router.post("/login", response_model=dict[str, str])