transient.chat/models/state.py

45 lines
1.9 KiB
Python

from typing import Dict, List, Set
import hashlib
import secrets
# In-Memory Data Stores
# Ephemeral in-memory state: zero persistent database, zero disk logging.
user_sessions: Dict[str, dict] = {} # {username: {'key': str, 'last_active': str}}
messages: Dict[str, List[dict]] = {} # {room_name: [{'username': str, 'ciphertext': str, 'iv': str, 'timestamp': str}]}
room_users: Dict[str, Dict[str, str]] = {} # {room_name: {username: last_active_timestamp}}
room_passwords: Dict[str, str] = {} # {room_name: "salt:hash"} - secure room password hashes
authorized_room_users: Dict[str, Set[str]] = {} # {room_name: {username, ...}} - validated sessions for room
room_owners: Dict[str, str] = {} # {room_name: owner_username}
kicked_users: Dict[str, Set[str]] = {} # {room_name: {kicked_username}}
banned_ips: Set[str] = set()
banned_usernames: Set[str] = set()
user_ips: Dict[str, str] = {} # {username: ip_address}
video_state: Dict[str, dict] = {} # {room_name: {'url': str, 'started_at': str, 'is_paused': bool, 'is_active': bool}}
nuked_rooms: Dict[str, float] = {} # {room_name: expiry_timestamp_epoch}
def hash_room_password(password: str) -> str:
"""Hashes a room password using PBKDF2-HMAC-SHA256 with a cryptographically secure salt."""
salt = secrets.token_hex(16)
key_hash = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt.encode("utf-8"),
100000,
)
return f"{salt}:{key_hash.hex()}"
def verify_room_password(password: str, stored_hash: str) -> bool:
"""Verifies a room password against the stored salt:hash in constant time."""
try:
salt, expected_hash = stored_hash.split(":", 1)
test_hash = hashlib.pbkdf2_hmac(
"sha256",
password.encode("utf-8"),
salt.encode("utf-8"),
100000,
)
return secrets.compare_digest(test_hash.hex(), expected_hash)
except Exception:
return False