domain.entities.user¶
src.domain.entities.user
¶
User domain entity for authentication.
Pure business logic, no framework dependencies.
Session Management
- session_tier: Role-based tier determining default session limit
- max_sessions: Optional admin override for session limit
- get_max_sessions(): Returns effective session limit
Token Breach Rotation
- min_token_version: Per-user minimum acceptable token version
- Increment to invalidate all user's tokens (password change, security event)
Classes¶
User
dataclass
¶
User domain entity with authentication business rules.
Pure business logic with no infrastructure dependencies. Represents a user account with email verification, password, and lockout.
Business Rules
- Email verification required before login
- Account locks after 5 failed login attempts
- Lockout duration is 15 minutes
- Failed login counter resets on successful login
Attributes:
| Name | Type | Description |
|---|---|---|
id |
UUID
|
Unique user identifier |
email |
str
|
User email address (validated by Email value object) |
password_hash |
str
|
Bcrypt hashed password (never plaintext) |
is_verified |
bool
|
Email verification status (blocks login if False) |
is_active |
bool
|
Account active status (deactivated users cannot login) |
failed_login_attempts |
int
|
Counter for failed login attempts |
locked_until |
datetime | None
|
Timestamp until which account is locked (None if not locked) |
created_at |
datetime
|
Timestamp when user was created |
updated_at |
datetime
|
Timestamp when user was last updated |
Session |
Management
|
session_tier: Role-based tier (basic, essential, plus, premium, pro) max_sessions: Admin override for session limit (None = use tier default) |
Token |
Breach Rotation
|
min_token_version: Per-user minimum token version (increment to invalidate tokens) |
Example
from uuid_extensions import uuid7 user = User( ... id=uuid7(), ... email="user@example.com", ... password_hash="$2b$12$...", ... is_verified=False, ... is_active=True, ... failed_login_attempts=0, ... locked_until=None, ... created_at=datetime.now(UTC), ... updated_at=datetime.now(UTC), ... ) user.is_locked() False user.increment_failed_login() user.failed_login_attempts 1
Source code in src/domain/entities/user.py
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | |
Functions¶
is_locked
¶
Check if account is currently locked due to failed login attempts.
Account is locked if locked_until timestamp is in the future.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if account is locked, False otherwise. |
Example
user = User(..., locked_until=None) user.is_locked() False user.locked_until = datetime.now(UTC) + timedelta(minutes=10) user.is_locked() True
Source code in src/domain/entities/user.py
increment_failed_login
¶
Increment failed login counter and lock account after 5 attempts.
Business Rule: After 5 failed login attempts, lock account for 15 minutes.
Side Effects
- Increments failed_login_attempts by 1
- Sets locked_until to 15 minutes from now if attempts >= 5
Example
user = User(..., failed_login_attempts=4) user.increment_failed_login() user.failed_login_attempts 5 user.is_locked() True
Source code in src/domain/entities/user.py
reset_failed_login
¶
Reset failed login counter after successful login.
Called on successful authentication to reset lockout state.
Side Effects
- Resets failed_login_attempts to 0
- Clears locked_until (sets to None)
Example
user = User(..., failed_login_attempts=3, locked_until=...) user.reset_failed_login() user.failed_login_attempts 0 user.locked_until None
Source code in src/domain/entities/user.py
can_login
¶
Check if user can login (verified, active, not locked).
Convenience method combining multiple checks.
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if user can login, False otherwise. |
Example
user = User(..., is_verified=True, is_active=True) user.can_login() True user.is_verified = False user.can_login() False
Source code in src/domain/entities/user.py
get_max_sessions
¶
Get effective maximum sessions for this user.
Priority: 1. Admin override (max_sessions field) if set 2. Tier-based default from SESSION_TIER_LIMITS 3. Falls back to 'basic' tier if invalid tier
Returns:
| Type | Description |
|---|---|
int | None
|
int | None: Maximum sessions allowed (None = unlimited) |
Example
user = User(..., session_tier="premium", max_sessions=None) user.get_max_sessions() 10 user.max_sessions = 15 # Admin override user.get_max_sessions() 15 user.session_tier = "ultimate" user.max_sessions = None user.get_max_sessions() None # Unlimited
Source code in src/domain/entities/user.py
can_create_session
¶
Check if user can create a new session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
current_session_count
|
int
|
Number of active sessions user currently has. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if user can create new session, False if at limit. |
Example
user = User(..., session_tier="basic") # limit=2 user.can_create_session(1) True user.can_create_session(2) False