""" Session Manager - Singleton pattern for managing authenticated user session """ from typing import Optional, Dict, Any class SessionManager: """ Singleton session manager to maintain authenticated user state throughout the application lifecycle. """ _instance = None def __new__(cls): """Implement singleton pattern""" if cls._instance is None: cls._instance = super(SessionManager, cls).__new__(cls) cls._instance._initialized = False return cls._instance def __init__(self): """Initialize the session manager (only once)""" if self._initialized: return self._current_user = None # {username, user_type} self._initialized = True @classmethod def get_instance(cls) -> 'SessionManager': """ Get the singleton instance of SessionManager Returns: The singleton SessionManager instance """ if cls._instance is None: cls._instance = cls() return cls._instance def login(self, username: str, password: str) -> bool: """ Authenticate and login a user Args: username: The username to authenticate password: The password to verify Returns: True if login successful, False otherwise """ from db.bip_users_dao import BIPUsersDAO dao = BIPUsersDAO() user_info = dao.authenticate(username, password) if user_info: self._current_user = { 'username': user_info['username'], 'user_type': user_info['user_type'] } return True return False def login_by_computer_name(self) -> bool: """ Attempt silent login using computer name Returns: True if login successful, False otherwise """ import socket from db.bip_users_dao import BIPUsersDAO computer_name = socket.gethostname() dao = BIPUsersDAO() user_info = dao.authenticate_by_computer_name(computer_name) if user_info: self._current_user = { 'username': user_info['username'], 'user_type': user_info['user_type'] } return True return False def logout(self): """Logout the current user and clear session""" self._current_user = None def is_authenticated(self) -> bool: """ Check if a user is currently authenticated Returns: True if user is logged in, False otherwise """ return self._current_user is not None def is_admin(self) -> bool: """ Check if the current user is an admin Returns: True if current user is admin, False otherwise """ if not self._current_user: return False return self._current_user.get('user_type') == 'Admin' def is_guest(self) -> bool: """ Check if the current user is a guest Returns: True if current user is guest, False otherwise """ if not self._current_user: return False return self._current_user.get('user_type') == 'Guest' def get_username(self) -> Optional[str]: """ Get the current username Returns: Current username if authenticated, None otherwise """ if not self._current_user: return None return self._current_user.get('username') def get_user_type(self) -> Optional[str]: """ Get the current user type Returns: Current user type if authenticated, None otherwise """ if not self._current_user: return None return self._current_user.get('user_type') def get_user_info(self) -> Optional[dict]: """ Get all current user information Returns: Dict with username and user_type if authenticated, None otherwise """ return self._current_user def switch_user(self, user_info: Dict[str, Any]) -> bool: """ Switch to a different user (Admin only feature) This allows an Admin user to operate as a different user with that user's permissions. Args: user_info: Dict with {id, username, user_type} Returns: True if switch successful """ if not self._current_user: return False # Store original admin user for reference if not hasattr(self, '_original_admin_user'): self._original_admin_user = self._current_user.copy() self._current_user = { 'username': user_info['username'], 'user_type': user_info['user_type'] } return True def get_original_admin(self) -> Optional[Dict[str, Any]]: """ Get the original Admin user before any user switch Returns: Original admin user dict if a switch occurred, None otherwise """ return getattr(self, '_original_admin_user', None)