97 lines
2.4 KiB
Python
97 lines
2.4 KiB
Python
"""
|
|
User schemas for API request and response validation
|
|
"""
|
|
import re
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, EmailStr, Field, validator
|
|
|
|
|
|
class UserBase(BaseModel):
|
|
"""
|
|
Base user schema with common attributes
|
|
"""
|
|
email: EmailStr
|
|
username: str = Field(..., min_length=3, max_length=50)
|
|
is_active: Optional[bool] = True
|
|
|
|
class UserCreate(UserBase):
|
|
"""
|
|
Schema for user creation with password
|
|
"""
|
|
password: str = Field(..., min_length=8)
|
|
|
|
@validator('password')
|
|
def password_strength(cls, v):
|
|
"""
|
|
Validate password strength
|
|
"""
|
|
if not re.search(r'[A-Z]', v):
|
|
raise ValueError('Password must contain at least one uppercase letter')
|
|
if not re.search(r'[a-z]', v):
|
|
raise ValueError('Password must contain at least one lowercase letter')
|
|
if not re.search(r'[0-9]', v):
|
|
raise ValueError('Password must contain at least one digit')
|
|
return v
|
|
|
|
class UserUpdate(BaseModel):
|
|
"""
|
|
Schema for user update
|
|
"""
|
|
email: Optional[EmailStr] = None
|
|
username: Optional[str] = Field(None, min_length=3, max_length=50)
|
|
password: Optional[str] = Field(None, min_length=8)
|
|
is_active: Optional[bool] = None
|
|
|
|
@validator('password')
|
|
def password_strength(cls, v):
|
|
"""
|
|
Validate password strength if provided
|
|
"""
|
|
if v is None:
|
|
return v
|
|
if not re.search(r'[A-Z]', v):
|
|
raise ValueError('Password must contain at least one uppercase letter')
|
|
if not re.search(r'[a-z]', v):
|
|
raise ValueError('Password must contain at least one lowercase letter')
|
|
if not re.search(r'[0-9]', v):
|
|
raise ValueError('Password must contain at least one digit')
|
|
return v
|
|
|
|
class UserInDBBase(UserBase):
|
|
"""
|
|
Base schema for user in database
|
|
"""
|
|
id: int
|
|
is_superuser: Optional[bool] = False
|
|
|
|
class Config:
|
|
"""
|
|
Pydantic config
|
|
"""
|
|
orm_mode = True
|
|
|
|
class User(UserInDBBase):
|
|
"""
|
|
Schema for user response
|
|
"""
|
|
pass
|
|
|
|
class UserInDB(UserInDBBase):
|
|
"""
|
|
Schema for user in database with password
|
|
"""
|
|
hashed_password: str
|
|
|
|
class Token(BaseModel):
|
|
"""
|
|
Schema for access token
|
|
"""
|
|
access_token: str
|
|
token_type: str
|
|
|
|
class TokenPayload(BaseModel):
|
|
"""
|
|
Schema for token payload
|
|
"""
|
|
sub: Optional[int] = None |