From 47fd81a5910eab3483f79d03eedf9307bc81252f Mon Sep 17 00:00:00 2001 From: l3wdfut4pwr Date: Tue, 17 Mar 2026 14:11:45 +0200 Subject: simple registration prototype --- app/routes/register.py | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ app/routes/routes.py | 6 +++ 2 files changed, 121 insertions(+) create mode 100644 app/routes/register.py (limited to 'app/routes') diff --git a/app/routes/register.py b/app/routes/register.py new file mode 100644 index 0000000..0134c56 --- /dev/null +++ b/app/routes/register.py @@ -0,0 +1,115 @@ +import re +from typing import Optional + +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.future import select + +from app.models.user import User +from app.schemas.user import UserCreate, UserRead +from app.utils.db import get_async_session +from app.utils.hash_cfg import hash_password +from app.utils.logger_cfg import logger + +router = APIRouter(prefix="/auth", tags=["auth"]) + + +@router.post("/register", response_model=UserRead) +async def register_user( + user: UserCreate, session: AsyncSession = Depends(get_async_session) +): + logger.debug("Register request received") + + email: Optional[str] = user.email.strip() if user.email else None + + logger.debug("Normalized email value: {}", email) + + logger.info( + "Registration attempt | username={} email={}", + user.username, + email, + ) + + logger.debug("Validating password complexity") + + if not ( + re.search(r"[A-Za-z]", user.password) + and re.search(r"\d", user.password) + and re.search(r"[^\w\s]", user.password) + ): + logger.warning( + "Registration failed | password complexity requirement not met | username={}", + user.username, + ) + + logger.debug("Checking if username already exists") + result = await session.execute(select(User).where(User.username == user.username)) + existing_username = result.scalars().first() + if existing_username: + logger.warning( + "Registration failed | username already exists | username={}", + user.username, + ) + raise HTTPException( + status_code=400, + detail={"field": "username", "message": "Никнейм уже занят."}, + ) + + if email: + logger.debug("Checking if email already exists") + result = await session.execute(select(User).where(User.email == email)) + existing_email = result.scalars().first() + if existing_email: + logger.warning( + "Registration failed | email already exists | email={}", + email, + ) + raise HTTPException( + status_code=400, + detail={"field": "email", "message": "Адрес уже занят."}, + ) + + logger.debug("Starting password hashing") + + hashed_password = hash_password(user.password) + + logger.debug("Password hashing completed") + + logger.debug("Creating new user") + + new_user = User( + username=user.username, + email=email, + password=hashed_password, + ) + + logger.debug("User model created | username={}", user.username) + + logger.debug("Adding user to session") + + session.add(new_user) + + logger.debug("Preparing to commit database transaction") + + await session.commit() + + logger.debug("Transaction committed successfully") + + logger.debug("Refreshing user instance from database") + + await session.refresh(new_user) + + logger.debug( + "User instance refreshed | id={} username={}", + new_user.id, + new_user.username, + ) + + logger.success( + "User successfully registered | id={} username={} email={}", + new_user.id, + new_user.username, + new_user.email, + ) + + return new_user diff --git a/app/routes/routes.py b/app/routes/routes.py index e69de29..7db7ec4 100644 --- a/app/routes/routes.py +++ b/app/routes/routes.py @@ -0,0 +1,6 @@ +from fastapi import APIRouter + +from .register import router as register_router + +router = APIRouter() +router.include_router(register_router) -- cgit v1.3-3-g829e