Изменил подтверждение почты

This commit is contained in:
urec56 2024-03-30 15:37:23 +05:00
parent 040f10a2ed
commit 6b3dad8566
5 changed files with 34 additions and 11 deletions

View file

@ -8,7 +8,7 @@ from app.config import settings
def create_registration_confirmation_template(
username: str,
email_to: EmailStr,
confirmation_code: str,
confirmation_link: str,
):
email = EmailMessage()
@ -19,7 +19,7 @@ def create_registration_confirmation_template(
email.set_content(
f"""
<h1>{username}, лови аптечку</h1>
<h2>{confirmation_code}</h2>
{confirmation_link}
""",
subtype="html"
)

View file

@ -1,7 +1,9 @@
import json
import smtplib
import random
import string
from cryptography.fernet import Fernet
from pydantic import EmailStr
@ -19,15 +21,25 @@ def generate_confirmation_code(length=6):
@celery.task
def send_registration_confirmation_email(
user_id: int,
username: str,
email_to: EmailStr,
MODE: str
):
confirmation_code = generate_confirmation_code()
if MODE == 'TEST':
return confirmation_code
load = {"user_id": user_id, "username": username, "email": email_to, "confirmation_code": confirmation_code}
str_load = json.dumps(load)
cipher_suite = Fernet(settings.INVITATION_LINK_TOKEN_KEY)
invitation_token = cipher_suite.encrypt(str_load.encode())
confirmation_link = settings.INVITATION_LINK_HOST + '/api/users/email_verification/' + invitation_token.decode()
msg_content = create_registration_confirmation_template(
username=username, email_to=email_to, confirmation_code=confirmation_code
username=username, email_to=email_to, confirmation_link=confirmation_link
)
with smtplib.SMTP_SSL(settings.SMTP_HOST, settings.SMTP_PORT) as server:

View file

@ -150,7 +150,7 @@ class UserCodesDAO(BaseDAO):
AND now() - usersverificationcodes.date_of_creation < INTERVAL '30 minutes'
"""
query = (select(UsersVerificationCodes.__table__.columns)
.where((func.now() - UsersVerificationCodes.date_of_creation) < text("INTERVAL '30 minutes'"))
.where((func.now() - UsersVerificationCodes.date_of_creation) < text("INTERVAL '10 minutes'"))
.filter_by(**filter_by))
async with async_session_maker() as session:

View file

@ -1,3 +1,6 @@
import json
from cryptography.fernet import Fernet
from fastapi import APIRouter, Response, Depends, status, Request
from fastapi.responses import RedirectResponse
@ -50,7 +53,10 @@ async def check_existing_email(email: SEmail):
@router.post("/register", response_model=SUserToken, status_code=status.HTTP_201_CREATED)
async def register_user(response: Response, user_data: SUserRegister):
if user_data.password != user_data.password2:
raise PasswordsMismatchException
await check_existing_user(user_data)
hashed_password = get_password_hash(user_data.password)
user_id = await UserDAO.add(
email=user_data.email,
@ -60,7 +66,7 @@ async def register_user(response: Response, user_data: SUserRegister):
)
result = send_registration_confirmation_email.delay(
username=user_data.username, email_to=user_data.email, MODE=settings.MODE
user_id=user_id, username=user_data.username, email_to=user_data.email, MODE=settings.MODE
)
result = result.get()
@ -73,12 +79,16 @@ async def register_user(response: Response, user_data: SUserRegister):
return {"access_token": access_token}
@router.post('/email_verification', status_code=status.HTTP_200_OK, response_model=SEmailVerification)
async def email_verification(user_code: SUserCode, user: Users = Depends(get_current_user)):
@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)
user_data = cipher_suite.decrypt(invitation_token).decode("utf-8")
user_data = json.loads(user_data)
user_codes = await UserCodesDAO.get_user_codes(
user_id=user.id, description="Код подтверждения почты", code=user_code.user_code
user_id=user_data["user_id"], description="Код подтверждения почты", code=user_data["confirmation_code"]
)
if not user_codes or not await UserDAO.change_data(user_id=user.id, role=VERIFICATED_USER):
if not user_codes or not await UserDAO.change_data(user_id=user_data["user_id"], role=VERIFICATED_USER):
raise WrongCodeException
return {'email_verification': True}
@ -127,12 +137,12 @@ async def change_avatar(user_data: SUserAvatar, current_user: Users = Depends(ge
@router.patch("/change_password", status_code=status.HTTP_200_OK)
async def change_password(new_password: SUserPassword, current_user: Users = Depends(get_current_user)):
if new_password.new_password != new_password.new_password2:
raise PasswordsMismatchException
await check_verificated_user_with_exc(user_id=current_user.id)
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
if new_password.new_password != new_password.new_password2:
raise PasswordsMismatchException
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)

View file

@ -15,6 +15,7 @@ class SUserRegister(BaseModel):
email: EmailStr
username: str = Query(None, min_length=2, max_length=30)
password: str = Query(None, min_length=8)
password2: str = Query(None, min_length=8)
date_of_birth: date
@field_validator("date_of_birth")