""" Authentication module for the Musora Sentiment Analysis Dashboard. Handles user authentication and access control. Works both locally (loading .env) and on Hugging Face / cloud (using secrets). """ import os import streamlit as st from pathlib import Path from dotenv import load_dotenv # Load environment variables from .env file. # On cloud deployments, env vars are set as secrets and os.getenv works directly. # Locally, we load from .env at the project root. _env_path = Path(__file__).resolve().parent.parent.parent / '.env' if _env_path.exists(): load_dotenv(_env_path) # Authorized emails — team members only. AUTHORIZED_EMAILS = { "danial@musora.com", "caleb@musora.com", "gabriel@musora.com", "jmilligan@musora.com", "dave@musora.com", "amy@musora.com" } def get_valid_token() -> str: """ Get the valid access token from environment. Returns: str: Valid access token (empty string if not set). """ return os.getenv("APP_TOKEN", "") def verify_login(email: str, token: str) -> bool: """ Verify user login credentials. Args: email: User email address. token: Access token. Returns: bool: True if credentials are valid, False otherwise. """ valid_token = get_valid_token() email_normalized = email.lower().strip() return (email_normalized in AUTHORIZED_EMAILS) and (token == valid_token) def check_authentication() -> bool: """ Check if the user is authenticated in the current session. Returns: bool: True if authenticated, False otherwise. """ return st.session_state.get("authenticated", False) def get_current_user() -> str: """ Get the currently logged-in user's email. Returns: str: User email or empty string if not authenticated. """ return st.session_state.get("user_email", "") def logout() -> None: """ Log out the current user by clearing auth-related session state. """ for key in ("authenticated", "user_email"): st.session_state.pop(key, None) def render_login_page() -> None: """ Render the login page UI and halt execution until authenticated. Call this at the top of app.py before any other page logic. Uses st.stop() to prevent the rest of the app from running. """ st.title("Musora Sentiment Analysis Dashboard") st.markdown(""" Welcome to the **Musora Sentiment Analysis Dashboard**. This tool is restricted to authorized Musora team members. Please enter your credentials below to access the dashboard. """) with st.form("login_form"): email = st.text_input( "Email Address", placeholder="your.name@musora.com", ) token = st.text_input( "Access Token", type="password", placeholder="Enter your access token", ) submitted = st.form_submit_button("Login", use_container_width=True) if submitted: if verify_login(email, token): st.session_state["authenticated"] = True st.session_state["user_email"] = email.lower().strip() st.success("Login successful! Redirecting…") st.rerun() else: st.error("Invalid email or access token. Please try again.") st.stop()