""" auth.py — Authentication & Session Validation Credentials via HF Secrets (env vars in Docker). Set in HF Space Secrets: SUBTITLE_USER — login username SUBTITLE_PASS — login password """ import os import hmac import hashlib import streamlit as st # ───────────────────────────────────────────────────────────────────────────── # Credential helpers # ───────────────────────────────────────────────────────────────────────────── def _get_credentials() -> tuple[str, str]: """Read from HF Secrets → env vars. Local fallback for dev.""" username = os.environ.get("SUBTITLE_USER", "admin") password = os.environ.get("SUBTITLE_PASS", "subtitle2024") return username, password def _sha256(value: str) -> str: return hashlib.sha256(value.encode("utf-8")).hexdigest() def verify_credentials(username: str, password: str) -> bool: """Constant-time comparison to prevent timing attacks.""" valid_user, valid_pass = _get_credentials() user_ok = hmac.compare_digest(_sha256(username), _sha256(valid_user)) pass_ok = hmac.compare_digest(_sha256(password), _sha256(valid_pass)) return user_ok and pass_ok # ───────────────────────────────────────────────────────────────────────────── # Session helpers # ───────────────────────────────────────────────────────────────────────────── def is_authenticated() -> bool: return st.session_state.get("authenticated", False) def login(username: str, password: str) -> bool: if verify_credentials(username, password): st.session_state["authenticated"] = True st.session_state["current_user"] = username return True return False def logout() -> None: """Wipe entire session — returns user to login screen.""" for key in list(st.session_state.keys()): del st.session_state[key] # ───────────────────────────────────────────────────────────────────────────── # Login page UI # ───────────────────────────────────────────────────────────────────────────── def render_login_page() -> None: st.markdown(""" """, unsafe_allow_html=True) _, col, _ = st.columns([1, 1.6, 1]) with col: st.markdown('
', unsafe_allow_html=True) st.markdown('', unsafe_allow_html=True) st.markdown('
Myanmar Subtitle Translator
', unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) with st.container(border=True): username = st.text_input("Username", key="li_user", placeholder="username") password = st.text_input("Password", type="password", key="li_pass", placeholder="••••••••") if st.button("Sign In →", key="li_btn", use_container_width=True): if not username or not password: st.markdown( '
⚠ Username နှင့် Password ထည့်ပါ
', unsafe_allow_html=True) elif login(username, password): st.rerun() else: st.markdown( '
✕ Username သို့ Password မှားသည်
', unsafe_allow_html=True) st.markdown( '', unsafe_allow_html=True)