|
from pydantic import BaseModel, Field, constr |
|
from typing import Optional |
|
from datetime import datetime |
|
from passlib.context import CryptContext |
|
|
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") |
|
|
|
|
|
PHONE_PATTERN = r"^(?:\+255|0)\d{9}$" |
|
MAC_PATTERN = r"^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$" |
|
|
|
|
|
|
|
class RegisterUserRequest(BaseModel): |
|
name: str = Field(..., max_length=100) |
|
password: str = Field(..., max_length=100) |
|
phoneNumber: str = Field( |
|
..., |
|
pattern=PHONE_PATTERN, |
|
description="Tanzanian phone number starting with +255 or 0 followed by 9 digits", |
|
) |
|
mac_address: str = Field( |
|
..., pattern=MAC_PATTERN, description="MAC address in standard format" |
|
) |
|
|
|
def hash_password(self): |
|
self.password = pwd_context.hash(self.password) |
|
|
|
class Config: |
|
schema_extra = { |
|
"example": { |
|
"name": "John Doe", |
|
"password": "StrongPassword1!", |
|
"phoneNumber": "+255123456789", |
|
"mac_address": "00:1A:2B:3C:4D:5E", |
|
} |
|
} |
|
|
|
|
|
|
|
class LoginUserRequest(BaseModel): |
|
phoneNumber: str = Field(..., pattern=PHONE_PATTERN) |
|
password: str |
|
mac_address: str = Field(..., pattern=MAC_PATTERN) |
|
|
|
|
|
|
|
class AccessTokenResponse(BaseModel): |
|
access_token: str |
|
token_type: str = "bearer" |
|
|
|
|
|
|
|
class BaseResponse(BaseModel): |
|
code: int |
|
message: str |
|
payload: Optional[dict] = None |
|
|
|
|
|
|
|
class ForgotPasswordRequest(BaseModel): |
|
phoneNumber: str = Field(..., pattern=PHONE_PATTERN) |
|
|
|
|
|
|
|
class VerifyResetTokenRequest(BaseModel): |
|
phoneNumber: str = Field(..., pattern=PHONE_PATTERN) |
|
reset_token: str = Field(..., max_length=6) |
|
|
|
|
|
|
|
class ResetPasswordRequest(BaseModel): |
|
phoneNumber: str = Field(..., pattern=PHONE_PATTERN) |
|
new_password: str = Field(..., max_length=100) |
|
|