V8 / users /manager.py
Drizzy0101's picture
Initial upload
f7e32a5
Raw
History Blame Contribute Delete
2.96 kB
"""User manager — handles guest sessions, authentication, and profiles."""
import json
import hashlib
import secrets
import logging
from datetime import datetime, timedelta
from typing import Optional
from database.repositories import UserRepo, SettingsRepo
from database import engine as db_engine
logger = logging.getLogger("synapse.users")
class UserManager:
"""Manages user accounts and sessions."""
def __init__(self):
self._guest_sessions: dict[str, dict] = {}
async def get_or_create_guest(self, session_id: str = None) -> dict:
if not session_id:
session_id = f"guest_{secrets.token_hex(8)}"
if session_id in self._guest_sessions:
return self._guest_sessions[session_id]
user = await UserRepo.get_by_username(session_id)
if not user:
user = await UserRepo.create(
username=session_id,
display_name="Guest",
)
self._guest_sessions[session_id] = user
return user
async def register(self, username: str, display_name: str = None,
email: str = None, password: str = None) -> dict:
existing = await UserRepo.get_by_username(username)
if existing:
raise ValueError("Username already exists")
user = await UserRepo.create(
username=username,
display_name=display_name or username,
email=email,
)
if password:
from database import engine
pw_hash = hashlib.sha256(password.encode()).hexdigest()
await SettingsRepo.set(user["id"], "password_hash", pw_hash)
return user
async def authenticate(self, username: str, password: str) -> Optional[dict]:
user = await UserRepo.get_by_username(username)
if not user:
return None
stored_hash = await SettingsRepo.get(user["id"], "password_hash")
if not stored_hash:
return None
pw_hash = hashlib.sha256(password.encode()).hexdigest()
if pw_hash != stored_hash:
return None
return user
async def get_profile(self, user_id: str) -> Optional[dict]:
return await UserRepo.get_by_id(user_id)
async def update_profile(self, user_id: str, **kwargs) -> None:
user = await UserRepo.get_by_id(user_id)
if not user:
return
prefs = json.loads(user.get("preferences", "{}"))
prefs.update(kwargs)
await UserRepo.update_preferences(user_id, prefs)
async def get_settings(self, user_id: str) -> dict:
return await SettingsRepo.get_all(user_id)
async def set_setting(self, user_id: str, key: str, value: str) -> None:
await SettingsRepo.set(user_id, key, value)
async def get_setting(self, user_id: str, key: str) -> Optional[str]:
return await SettingsRepo.get(user_id, key)
user_manager = UserManager()