ssf-2025-ana/Backend/schemas/user.py
2025-09-13 16:18:28 +09:00

93 lines
2.3 KiB
Python

from pydantic import BaseModel, EmailStr
from datetime import datetime
from typing import Optional
import hashlib
import secrets
from fastapi import Form
class UserCreate(BaseModel):
username: str
email: EmailStr
password: str
@classmethod
def as_form(
cls,
username: str = Form(...),
email: EmailStr = Form(...),
password: str = Form(...),
) -> "UserCreate":
return cls(username=username, email=email, password=password)
class UserUpdate(BaseModel):
email: Optional[EmailStr] = None
password: Optional[str] = None
@classmethod
def as_form(
cls,
email: Optional[EmailStr] = Form(default=None),
password: Optional[str] = Form(default=None),
) -> "UserUpdate":
return cls(email=email, password=password)
class UserLogin(BaseModel):
username: str
password: str
class UserResponse(BaseModel):
id: int
username: str
email: str
created_at: datetime
profile_image_path: str
is_active: bool
class User:
def __init__(
self,
id: int,
username: str,
email: str,
password_hash: str,
salt: str,
created_at: datetime,
profile_image_path: str,
is_active: bool = True,
):
self.id = id
self.username = username
self.email = email
self.password_hash = password_hash
self.salt = salt
self.created_at = created_at
self.profile_image_path = profile_image_path
self.is_active = is_active
@staticmethod
def hash_password(password: str, salt: Optional[str] = None) -> tuple[str, str]:
if salt is None:
salt = secrets.token_hex(32)
password_hash = hashlib.pbkdf2_hmac(
"sha256", password.encode("utf-8"), salt.encode("utf-8"), 100000
)
return password_hash.hex(), salt
def verify_password(self, password: str) -> bool:
password_hash, _ = self.hash_password(password, self.salt)
return password_hash == self.password_hash
def to_response(self) -> UserResponse:
return UserResponse(
id=self.id,
username=self.username,
email=self.email,
created_at=self.created_at,
profile_image_path=self.profile_image_path,
is_active=self.is_active,
)