Compare commits

...

3 Commits

Author SHA1 Message Date
IluaAir
9099120ee2 username validation 2025-09-20 14:11:14 +03:00
IluaAir
c642b89581 full view User profile 2025-09-20 14:04:07 +03:00
IluaAir
e0cddbdd34 add is_superuser for jwt token 2025-09-20 13:55:36 +03:00
5 changed files with 27 additions and 10 deletions

View File

@@ -14,8 +14,9 @@ router = APIRouter(prefix=settings.api.v1.users, tags=["Users"])
@router.get("/me") @router.get("/me")
async def get_me(user: ActiveUser): async def get_me(session: sessionDep, user: ActiveUser):
return user cur_user = await UserService(session).get_user_by_filter_or_raise(id=user.id)
return cur_user
@router.get("/") @router.get("/")

View File

@@ -1,4 +1,4 @@
from pydantic import BaseModel from pydantic import BaseModel, ConfigDict, Field
class Token(BaseModel): class Token(BaseModel):
@@ -8,5 +8,8 @@ class Token(BaseModel):
class TokenData(BaseModel): class TokenData(BaseModel):
id: int id: int
sub: str sub: str = Field(alias='username')
is_superuser: bool
is_active: bool is_active: bool
model_config = ConfigDict(populate_by_name=True)

View File

@@ -3,7 +3,7 @@ from typing import Annotated
from pydantic import BaseModel, BeforeValidator, ConfigDict, EmailStr from pydantic import BaseModel, BeforeValidator, ConfigDict, EmailStr
from src.schemas.tasks import TaskWithId from src.schemas.tasks import TaskWithId
from src.schemas.validators import ensure_password from src.schemas.validators import ensure_password, ensure_username
class UserUpdate(BaseModel): class UserUpdate(BaseModel):
@@ -19,6 +19,8 @@ class User(BaseModel):
username: str username: str
is_active: bool is_active: bool
is_superuser: bool is_superuser: bool
telegram_id: int | None
avatar_path: str | None
model_config = ConfigDict(from_attributes=True, extra="ignore") model_config = ConfigDict(from_attributes=True, extra="ignore")
@@ -36,7 +38,7 @@ class UserRequest(BaseModel):
class UserRequestADD(BaseModel): class UserRequestADD(BaseModel):
username: str username: Annotated[str, BeforeValidator(ensure_username)]
email: EmailStr | None = None email: EmailStr | None = None
password: Annotated[str, BeforeValidator(ensure_password)] password: Annotated[str, BeforeValidator(ensure_password)]

View File

@@ -1,11 +1,21 @@
from typing import Any from typing import Any
def ensure_password(value: Any) -> Any: def ensure_password(value: Any) -> str:
if not isinstance(value, str): if not isinstance(value, str):
raise TypeError("Password must be a string") raise TypeError("Password must be a string")
value = value.strip()
if len(value) < 8: if len(value) < 8:
raise ValueError("Password must be at least 8 characters") raise ValueError("Password must be at least 8 characters")
if value.strip() == "": elif value.strip() == "":
raise ValueError("Password cannot be empty") raise ValueError("Password cannot be empty")
return value return value
def ensure_username(value: str) -> str:
value = value.strip()
if len(value) < 3:
raise ValueError("Username must be at least 3 characters")
elif value.lower() in ['admin', 'moderator', 'админ', 'модератор']:
raise ValueError("Login is already taken")
return value

View File

@@ -2,7 +2,7 @@ from fastapi import HTTPException
from src.core.auth_manager import AuthManager from src.core.auth_manager import AuthManager
from src.core.settings import settings from src.core.settings import settings
from src.schemas.auth import Token from src.schemas.auth import Token, TokenData
from src.schemas.users import User, UserAdd, UserRequestADD, UserWithHashedPass from src.schemas.users import User, UserAdd, UserRequestADD, UserWithHashedPass
from src.services.base import BaseService from src.services.base import BaseService
@@ -27,6 +27,7 @@ class AuthService(BaseService):
detail="Incorrect username or password", detail="Incorrect username or password",
) )
user = UserWithHashedPass.model_validate(result) user = UserWithHashedPass.model_validate(result)
user_token = TokenData.model_validate(user.model_dump())
verify = AuthManager.verify_password( verify = AuthManager.verify_password(
plain_password=password, hashed_password=user.hashed_password plain_password=password, hashed_password=user.hashed_password
) )
@@ -36,7 +37,7 @@ class AuthService(BaseService):
detail="Incorrect username or password", detail="Incorrect username or password",
) )
access_token = AuthManager.create_access_token( access_token = AuthManager.create_access_token(
data={"id": user.id, "sub": user.username, "is_active": user.is_active} user_token.model_dump()
) )
return Token( return Token(
access_token=access_token, token_type=settings.access_token.token_type access_token=access_token, token_type=settings.access_token.token_type