Spaces:
Running
Running
| # ============================================================ | |
| # app/schemas/auth.py - Authentication DTOs | |
| # ============================================================ | |
| from pydantic import BaseModel, EmailStr, Field, field_validator | |
| from typing import Optional | |
| import re | |
| class SignupDto(BaseModel): | |
| """Signup request DTO""" | |
| first_name: str = Field(..., min_length=1, max_length=50) | |
| last_name: str = Field(..., min_length=1, max_length=50) | |
| email: Optional[EmailStr] = None | |
| phone: Optional[str] = None | |
| password: str = Field(..., min_length=8, max_length=100) | |
| role: str = Field(..., pattern="^(renter|landlord)$") | |
| def validate_password(cls, v): | |
| """Validate password strength""" | |
| if not re.search(r"[A-Z]", v): | |
| raise ValueError("Must contain uppercase letter") | |
| if not re.search(r"[a-z]", v): | |
| raise ValueError("Must contain lowercase letter") | |
| if not re.search(r"[0-9]", v): | |
| raise ValueError("Must contain digit") | |
| if not re.search(r"[!@#$%^&*(),.?\":{}|<>]", v): | |
| raise ValueError("Must contain special character") | |
| return v | |
| def validate_contact(cls, v, info): | |
| """At least email or phone required""" | |
| if info.data.get("email") or info.data.get("phone"): | |
| return v | |
| raise ValueError("Email or phone is required") | |
| class VerifySignupOtpDto(BaseModel): | |
| """Verify signup OTP DTO""" | |
| identifier: str = Field(..., min_length=1) | |
| code: str = Field(..., min_length=4, max_length=4) | |
| class LoginDto(BaseModel): | |
| """Login request DTO""" | |
| identifier: str = Field(..., min_length=1) | |
| password: str = Field(..., min_length=1) | |
| class SendPasswordResetOtpDto(BaseModel): | |
| """Send password reset OTP DTO""" | |
| identifier: str = Field(..., min_length=1) | |
| class VerifyPasswordResetOtpDto(BaseModel): | |
| """Verify password reset OTP DTO""" | |
| identifier: str = Field(..., min_length=1) | |
| code: str = Field(..., min_length=4, max_length=4) | |
| class ResetPasswordDto(BaseModel): | |
| """Reset password DTO""" | |
| identifier: str = Field(..., min_length=1) | |
| new_password: str = Field(..., min_length=8, max_length=100) | |
| def validate_password(cls, v): | |
| """Validate password strength""" | |
| if not re.search(r"[A-Z]", v): | |
| raise ValueError("Must contain uppercase letter") | |
| if not re.search(r"[a-z]", v): | |
| raise ValueError("Must contain lowercase letter") | |
| if not re.search(r"[0-9]", v): | |
| raise ValueError("Must contain digit") | |
| if not re.search(r"[!@#$%^&*(),.?\":{}|<>]", v): | |
| raise ValueError("Must contain special character") | |
| return v | |
| class ResendOtpDto(BaseModel): | |
| """Resend OTP DTO""" | |
| identifier: str = Field(..., min_length=1) | |
| purpose: str = Field(..., pattern="^(signup|password_reset)$") | |