Добавлена верификация почта
This commit is contained in:
parent
1f0f228341
commit
ea23ea64b3
5 changed files with 56 additions and 12 deletions
|
@ -2,11 +2,9 @@ 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, validate_user_admin
|
from app.users.auth import authenticate_user_by_username, create_access_token, validate_user_admin, ADMIN_USER
|
||||||
from app.users.dependencies import get_current_user
|
from app.users.dependencies import get_current_user
|
||||||
|
|
||||||
ADMIN_ROLE = 100
|
|
||||||
|
|
||||||
|
|
||||||
class AdminAuth(AuthenticationBackend):
|
class AdminAuth(AuthenticationBackend):
|
||||||
async def login(self, request: Request) -> bool:
|
async def login(self, request: Request) -> bool:
|
||||||
|
@ -14,7 +12,7 @@ class AdminAuth(AuthenticationBackend):
|
||||||
username, password = form["username"], form["password"]
|
username, password = form["username"], form["password"]
|
||||||
|
|
||||||
user = await authenticate_user_by_username(username, password)
|
user = await authenticate_user_by_username(username, password)
|
||||||
if user and user.role == ADMIN_ROLE:
|
if user and user.role == ADMIN_USER:
|
||||||
access_token = create_access_token({"sub": str(user.id)})
|
access_token = create_access_token({"sub": str(user.id)})
|
||||||
request.session.update({"token": access_token})
|
request.session.update({"token": access_token})
|
||||||
|
|
||||||
|
|
|
@ -67,3 +67,8 @@ class PasswordsМismatchException(BlackPhoenixException):
|
||||||
class UserCanNotReadThisChatException(BlackPhoenixException):
|
class UserCanNotReadThisChatException(BlackPhoenixException):
|
||||||
status_code = status.HTTP_409_CONFLICT
|
status_code = status.HTTP_409_CONFLICT
|
||||||
detail = "Юзер не может читать этот чат"
|
detail = "Юзер не может читать этот чат"
|
||||||
|
|
||||||
|
|
||||||
|
class WrongCodeException(BlackPhoenixException):
|
||||||
|
status_code = status.HTTP_409_CONFLICT
|
||||||
|
detail = 'Введён не верный код подтверждения'
|
||||||
|
|
|
@ -11,7 +11,9 @@ from app.users.models import Users
|
||||||
|
|
||||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||||
|
|
||||||
ADMIN_ROLE = 100
|
ADMIN_USER = 100
|
||||||
|
REGISTRATED_USER = 0
|
||||||
|
VERIFICATED_USER = 1
|
||||||
|
|
||||||
|
|
||||||
def get_password_hash(password: str) -> str:
|
def get_password_hash(password: str) -> str:
|
||||||
|
@ -64,6 +66,11 @@ async def validate_user_access_to_chat(user_id: int, chat_id: int):
|
||||||
|
|
||||||
async def validate_user_admin(user_id: int):
|
async def validate_user_admin(user_id: int):
|
||||||
user_role = await UserDAO.get_user_role(user_id=user_id)
|
user_role = await UserDAO.get_user_role(user_id=user_id)
|
||||||
if user_role == ADMIN_ROLE:
|
if user_role == ADMIN_USER:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_codes_list(user_codes: list[dict], sort_description: str) -> list[str]:
|
||||||
|
user_codes_list = [user_code['code'] for user_code in user_codes if user_code['description'] == sort_description]
|
||||||
|
return user_codes_list
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
from sqlalchemy import update, select, insert
|
from datetime import datetime
|
||||||
|
|
||||||
|
from sqlalchemy import update, select, insert, and_, func, literal, text
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
from sqlalchemy.dialects.postgresql import INTERVAL
|
||||||
|
|
||||||
from app.dao.base import BaseDAO
|
from app.dao.base import BaseDAO
|
||||||
from app.database import async_session_maker, engine
|
from app.database import async_session_maker, engine
|
||||||
|
@ -96,5 +99,26 @@ class UserCodesDAO(BaseDAO):
|
||||||
return result.scalar()
|
return result.scalar()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_user_codes(cls, user_id: int):
|
async def get_user_codes(cls, user_id: int) -> list[dict[str, str | int | datetime]]:
|
||||||
pass
|
"""
|
||||||
|
SELECT
|
||||||
|
usersverificationcodes.id,
|
||||||
|
usersverificationcodes.user_id,
|
||||||
|
usersverificationcodes.code,
|
||||||
|
usersverificationcodes.description,
|
||||||
|
usersverificationcodes.date_of_creation
|
||||||
|
FROM usersverificationcodes
|
||||||
|
WHERE
|
||||||
|
usersverificationcodes.user_id = 20
|
||||||
|
AND now() - usersverificationcodes.date_of_creation < INTERVAL '30 minutes'
|
||||||
|
"""
|
||||||
|
query = select(UsersVerificationCodes.__table__.columns).where(
|
||||||
|
and_(
|
||||||
|
UsersVerificationCodes.user_id == user_id,
|
||||||
|
(func.now() - UsersVerificationCodes.date_of_creation) < text("INTERVAL '30 minutes'")
|
||||||
|
))
|
||||||
|
async with async_session_maker() as session:
|
||||||
|
# print(query.compile(engine, compile_kwargs={"literal_binds": True})) # Проверка SQL запроса
|
||||||
|
result = await session.execute(query)
|
||||||
|
result = result.mappings().all()
|
||||||
|
return result
|
||||||
|
|
|
@ -3,9 +3,9 @@ from fastapi.responses import RedirectResponse
|
||||||
from starlette import status
|
from starlette import status
|
||||||
|
|
||||||
from app.exceptions import UserAlreadyExistsException, IncorrectAuthDataException, UsernameAlreadyInUseException, \
|
from app.exceptions import UserAlreadyExistsException, IncorrectAuthDataException, UsernameAlreadyInUseException, \
|
||||||
IncorrectPasswordException, PasswordsМismatchException
|
IncorrectPasswordException, PasswordsМismatchException, WrongCodeException
|
||||||
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, REGISTRATED_USER, get_user_codes_list, VERIFICATED_USER
|
||||||
from app.users.dao import UserDAO, UserCodesDAO
|
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
|
||||||
|
@ -43,7 +43,7 @@ async def register_user(response: Response, user_data: SUserRegister):
|
||||||
hashed_password=hashed_password,
|
hashed_password=hashed_password,
|
||||||
username=user_data.username,
|
username=user_data.username,
|
||||||
date_of_birth=user_data.date_of_birth,
|
date_of_birth=user_data.date_of_birth,
|
||||||
role=0,
|
role=REGISTRATED_USER,
|
||||||
black_phoenix=False
|
black_phoenix=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,6 +57,16 @@ async def register_user(response: Response, user_data: SUserRegister):
|
||||||
return {"access_token": access_token}
|
return {"access_token": access_token}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post('/email_verification')
|
||||||
|
async def email_verification(user_code: str, user: Users = Depends(get_current_user)):
|
||||||
|
user_codes = await UserCodesDAO.get_user_codes(user_id=user.id)
|
||||||
|
user_codes = get_user_codes_list(user_codes=user_codes, sort_description="Код подтверждения почты")
|
||||||
|
if user_code in user_codes:
|
||||||
|
if await UserDAO.change_data(user_id=user.id, role=VERIFICATED_USER):
|
||||||
|
return True
|
||||||
|
raise WrongCodeException
|
||||||
|
|
||||||
|
|
||||||
@router.post("/login", response_model=dict[str, str])
|
@router.post("/login", response_model=dict[str, str])
|
||||||
async def login_user(response: Response, user_data: SUserLogin):
|
async def login_user(response: Response, user_data: SUserLogin):
|
||||||
user = await authenticate_user_by_email(user_data.email_or_username, user_data.password)
|
user = await authenticate_user_by_email(user_data.email_or_username, user_data.password)
|
||||||
|
|
Loading…
Add table
Reference in a new issue