Spaces:
Sleeping
Sleeping
| """ | |
| shared/auth.py — Unified authentication for TrueSight. | |
| Uses SQLite + bcrypt for credential storage. | |
| """ | |
| import os | |
| import sqlite3 | |
| import hashlib | |
| import hmac | |
| DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "users.db") | |
| def _get_db(): | |
| """Get a connection to the users database.""" | |
| conn = sqlite3.connect(DB_PATH) | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS users ( | |
| username TEXT PRIMARY KEY, | |
| password TEXT NOT NULL | |
| ) | |
| """) | |
| conn.commit() | |
| return conn | |
| def _hash_password(password: str) -> str: | |
| """Hash a password with SHA-256 + salt.""" | |
| salt = os.urandom(16) | |
| pwd_hash = hashlib.pbkdf2_hmac("sha256", password.encode(), salt, 100000) | |
| return (salt + pwd_hash).hex() | |
| def _verify_password(password: str, stored_hash: str) -> bool: | |
| """Verify a password against a stored hash.""" | |
| stored_bytes = bytes.fromhex(stored_hash) | |
| salt = stored_bytes[:16] | |
| stored_pwd_hash = stored_bytes[16:] | |
| pwd_hash = hashlib.pbkdf2_hmac("sha256", password.encode(), salt, 100000) | |
| return hmac.compare_digest(pwd_hash, stored_pwd_hash) | |
| def register_user(username: str, password: str) -> tuple: | |
| """ | |
| Register a new user. | |
| Returns (success: bool, message: str). | |
| """ | |
| if not username or not password: | |
| return False, "Username and password are required." | |
| if len(username) < 3: | |
| return False, "Username must be at least 3 characters." | |
| if len(password) < 4: | |
| return False, "Password must be at least 4 characters." | |
| conn = _get_db() | |
| try: | |
| cur = conn.cursor() | |
| cur.execute("SELECT 1 FROM users WHERE username=?", (username,)) | |
| if cur.fetchone(): | |
| return False, "Username already exists." | |
| hashed = _hash_password(password) | |
| cur.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, hashed)) | |
| conn.commit() | |
| return True, "Account created successfully!" | |
| except Exception as e: | |
| return False, f"Registration failed: {e}" | |
| finally: | |
| conn.close() | |
| def authenticate_user(username: str, password: str) -> tuple: | |
| """ | |
| Authenticate a user. | |
| Returns (success: bool, message: str). | |
| """ | |
| if not username or not password: | |
| return False, "Username and password are required." | |
| conn = _get_db() | |
| try: | |
| cur = conn.cursor() | |
| cur.execute("SELECT password FROM users WHERE username=?", (username,)) | |
| row = cur.fetchone() | |
| if not row: | |
| return False, "Invalid username or password." | |
| if _verify_password(password, row[0]): | |
| return True, "Login successful!" | |
| else: | |
| return False, "Invalid username or password." | |
| except Exception as e: | |
| return False, f"Authentication failed: {e}" | |
| finally: | |
| conn.close() | |