File size: 3,342 Bytes
9858829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6b986c1
9858829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""
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()