maneshtrader/web_core/auth/profile_auth.py

73 lines
2.1 KiB
Python

from __future__ import annotations
import hashlib
from typing import Any
DEFAULT_PROFILE_ID = "default"
PROFILE_SESSION_TIMEOUT_SEC = 1800
def normalize_profile_id(value: Any) -> str:
profile_id = str(value or "").strip()
return profile_id if profile_id else DEFAULT_PROFILE_ID
def _profile_key(value: Any) -> str:
return normalize_profile_id(value).casefold()
def normalize_pin(value: Any) -> str | None:
pin = str(value or "").strip()
if not pin:
return None
if not pin.isdigit():
return None
if len(pin) < 4 or len(pin) > 6:
return None
return pin
def hash_profile_pin(profile_id: str, pin: str) -> str:
digest_input = f"{_profile_key(profile_id)}:{pin}"
return hashlib.sha256(digest_input.encode("utf-8")).hexdigest()
def first_query_param_value(query_params: Any, key: str) -> str | None:
raw = query_params.get(key)
if raw is None:
return None
if isinstance(raw, list):
return str(raw[0]) if raw else None
return str(raw)
def is_truthy_flag(value: Any) -> bool:
normalized = str(value or "").strip().lower()
return normalized in {"1", "true", "yes", "y", "on"}
def resolve_login_profile(session_profile: Any, query_profile: Any) -> str | None:
if str(session_profile or "").strip():
return normalize_profile_id(session_profile)
if str(query_profile or "").strip():
return normalize_profile_id(query_profile)
return None
def find_existing_profile_id(profile_id: Any, available_profiles: set[str]) -> str | None:
requested_key = _profile_key(profile_id)
for existing in available_profiles:
if _profile_key(existing) == requested_key:
return existing
return None
def profile_exists(profile_id: Any, available_profiles: set[str]) -> bool:
return find_existing_profile_id(profile_id, available_profiles) is not None
def is_profile_session_expired(last_active: Any, now_epoch: float, timeout_sec: int = PROFILE_SESSION_TIMEOUT_SEC) -> bool:
if not isinstance(last_active, (int, float)):
return False
return (now_epoch - float(last_active)) > timeout_sec