Spaces:
Running
Running
| """ | |
| System User model for authentication and authorization. | |
| Represents a system user with login credentials and permissions. | |
| """ | |
| from datetime import datetime | |
| from typing import Optional, Dict, Any, List | |
| from uuid import UUID | |
| from pydantic import BaseModel, Field, EmailStr | |
| from enum import Enum | |
| class UserStatus(str, Enum): | |
| """User account status options.""" | |
| ACTIVE = "active" | |
| INACTIVE = "inactive" | |
| SUSPENDED = "suspended" | |
| LOCKED = "locked" | |
| PENDING_ACTIVATION = "pending_activation" | |
| class UserRole(str, Enum): | |
| """System user roles.""" | |
| SUPER_ADMIN = "super_admin" | |
| ADMIN = "admin" | |
| MANAGER = "manager" | |
| USER = "user" | |
| READ_ONLY = "read_only" | |
| class LoginAttemptModel(BaseModel): | |
| """Login attempt tracking.""" | |
| timestamp: datetime = Field(default_factory=datetime.utcnow) | |
| ip_address: Optional[str] = Field(None, description="IP address of login attempt") | |
| user_agent: Optional[str] = Field(None, description="User agent string") | |
| success: bool = Field(..., description="Whether login was successful") | |
| failure_reason: Optional[str] = Field(None, description="Reason for failure if unsuccessful") | |
| class SecuritySettingsModel(BaseModel): | |
| """User security settings.""" | |
| require_password_change: bool = Field(default=False, description="Force password change on next login") | |
| password_expires_at: Optional[datetime] = Field(None, description="Password expiry date") | |
| failed_login_attempts: int = Field(default=0, description="Count of consecutive failed login attempts") | |
| last_failed_login: Optional[datetime] = Field(None, description="Timestamp of last failed login") | |
| account_locked_until: Optional[datetime] = Field(None, description="Account lock expiry time") | |
| last_password_change: Optional[datetime] = Field(None, description="Last password change timestamp") | |
| login_attempts: List[LoginAttemptModel] = Field(default_factory=list, description="Recent login attempts (last 10)") | |
| password_reset_token: Optional[str] = Field(None, description="Password reset token (stored securely)") | |
| password_reset_token_created_at: Optional[datetime] = Field(None, description="When reset token was created") | |
| class SystemUserModel(BaseModel): | |
| """ | |
| System User data model for authentication and authorization. | |
| Represents the complete user document in MongoDB. | |
| """ | |
| user_id: UUID = Field(..., description="Unique user identifier (UUID/ULID)") | |
| username: str = Field(..., description="Unique username (lowercase alphanumeric)") | |
| email: EmailStr = Field(..., description="User email address") | |
| merchant_id: str = Field(..., description="User Merchant Information") | |
| merchant_type: Optional[str] = Field(None, description="Merchant type (ncnf, cnf, distributor, retail)") | |
| # Authentication | |
| password_hash: str = Field(..., description="Bcrypt hashed password") | |
| # Personal information | |
| first_name: Optional[str] = Field(None, description="User first name") | |
| last_name: Optional[str] = Field(None, description="User last name") | |
| full_name: Optional[str] = Field(None, description="User full name") | |
| phone: Optional[str] = Field(None, description="User phone number (E.164 format)") | |
| # Authorization | |
| role: str = Field(default="user", alias="role_id", description="User role identifier") | |
| permissions: Dict[str, List[str]] = Field(default_factory=dict, description="Grouped permissions by module") | |
| # Status and security | |
| status: UserStatus = Field(default=UserStatus.PENDING_ACTIVATION, description="Account status") | |
| security_settings: SecuritySettingsModel = Field( | |
| default_factory=SecuritySettingsModel, | |
| description="Security and login settings" | |
| ) | |
| # Session management | |
| last_login_at: Optional[datetime] = Field(None, description="Last successful login timestamp") | |
| last_login_ip: Optional[str] = Field(None, description="IP address of last login") | |
| current_session_token: Optional[str] = Field(None, description="Current JWT token hash for session management") | |
| # Profile information | |
| profile_picture_url: Optional[str] = Field(None, description="URL to profile picture") | |
| timezone: str = Field(default="UTC", description="User timezone") | |
| language: str = Field(default="en", description="Preferred language code") | |
| # Audit fields | |
| created_by: str = Field(..., description="User ID who created this user account") | |
| created_at: datetime = Field(default_factory=datetime.utcnow, description="Account creation timestamp") | |
| updated_at: Optional[datetime] = Field(None, description="Last update timestamp") | |
| updated_by: Optional[str] = Field(None, description="User ID who last updated this record") | |
| class Config: | |
| populate_by_name = True | |
| json_schema_extra = { | |
| "example": { | |
| "user_id": "usr_01HZQX5K3N2P8R6T4V9W", | |
| "username": "john.doe", | |
| "email": "john.doe@company.com", | |
| "merchant_id": "mch_retail_001", | |
| "merchant_type": "retail", | |
| "password_hash": "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LeVMstdMT6jmDQrji", | |
| "first_name": "John", | |
| "last_name": "Doe", | |
| "phone": "+919876543210", | |
| "role_id": "admin", | |
| "permissions": { | |
| "customers": ["view", "create", "update"], | |
| "orders": ["view", "create", "update"], | |
| "settings": ["view", "update"] | |
| }, | |
| "status": "active", | |
| "security_settings": { | |
| "require_password_change": False, | |
| "failed_login_attempts": 0, | |
| "login_attempts": [] | |
| }, | |
| "last_login_at": "2024-11-30T10:30:00Z", | |
| "last_login_ip": "192.168.1.100", | |
| "timezone": "Asia/Kolkata", | |
| "language": "en", | |
| "created_by": "system", | |
| "created_at": "2024-01-15T08:00:00Z" | |
| } | |
| } | |