| """ |
| Authentication system and state management. |
| """ |
| from dataclasses import dataclass |
| from typing import Dict, List, Optional, Any |
| from .user_store import verify_email, get_user_profile |
|
|
| @dataclass |
| class AuthState: |
| """Class to track authentication state in the conversation.""" |
| is_authenticated: bool = False |
| attempts: int = 0 |
| max_attempts: int = 3 |
| user_email: Optional[str] = None |
| user_profile: Optional[Dict[str, Any]] = None |
| |
| @property |
| def is_locked(self) -> bool: |
| """Check if the account is locked due to too many failed attempts.""" |
| return self.attempts >= self.max_attempts and not self.is_authenticated |
| |
| @property |
| def attempts_remaining(self) -> int: |
| """Get the number of attempts remaining.""" |
| if self.is_authenticated: |
| return 0 |
| return max(0, self.max_attempts - self.attempts) |
|
|
| |
| |
| |
|
|
| def attempt_login(email: str, current_state: AuthState) -> AuthState: |
| """ |
| Attempt to authenticate with the given email. |
| |
| Args: |
| email: The email to verify |
| current_state: Current authentication state |
| |
| Returns: |
| Updated authentication state |
| """ |
| |
| if current_state.is_authenticated: |
| return current_state |
| |
| |
| if current_state.is_locked: |
| return current_state |
| |
| |
| new_state = AuthState( |
| is_authenticated=False, |
| attempts=current_state.attempts + 1, |
| user_email=None, |
| user_profile=None |
| ) |
| |
| |
| if verify_email(email): |
| new_state.is_authenticated = True |
| new_state.user_email = email.lower() |
| new_state.user_profile = get_user_profile(email) |
| |
| return new_state |