72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
"""
|
|
Password State Tracker
|
|
|
|
Tracks password state for students after password reset to prevent ambiguity.
|
|
After a successful password reset, we update the tracked password so subsequent
|
|
tests use the correct password.
|
|
"""
|
|
from typing import Dict, Optional
|
|
|
|
|
|
class PasswordTracker:
|
|
"""
|
|
Tracks password state for students.
|
|
|
|
After a successful password reset, the password is updated in memory
|
|
so subsequent tests use the correct password.
|
|
"""
|
|
|
|
_instance: Optional['PasswordTracker'] = None
|
|
_passwords: Dict[str, str] = {} # CPID -> current password
|
|
|
|
def __new__(cls):
|
|
"""Singleton pattern"""
|
|
if cls._instance is None:
|
|
cls._instance = super().__new__(cls)
|
|
return cls._instance
|
|
|
|
def get_password(self, cpid: str, default_password: str) -> str:
|
|
"""
|
|
Get current password for a student.
|
|
|
|
Args:
|
|
cpid: Student CPID
|
|
default_password: Default/initial password (if not tracked)
|
|
|
|
Returns:
|
|
str: Current password (tracked or default)
|
|
"""
|
|
return self._passwords.get(cpid, default_password)
|
|
|
|
def update_password(self, cpid: str, new_password: str):
|
|
"""
|
|
Update password for a student after successful reset.
|
|
|
|
Args:
|
|
cpid: Student CPID
|
|
new_password: New password (after reset)
|
|
"""
|
|
self._passwords[cpid] = new_password
|
|
print(f"✅ Password updated for {cpid} - future tests will use new password")
|
|
|
|
def reset_tracker(self):
|
|
"""Reset all tracked passwords (useful for test cleanup)"""
|
|
self._passwords.clear()
|
|
print("✅ Password tracker reset")
|
|
|
|
def clear_student(self, cpid: str):
|
|
"""Clear password tracking for a specific student"""
|
|
if cpid in self._passwords:
|
|
del self._passwords[cpid]
|
|
print(f"✅ Password tracking cleared for {cpid}")
|
|
|
|
|
|
# Global instance
|
|
password_tracker = PasswordTracker()
|
|
|
|
|
|
|
|
|
|
|
|
|