68 lines
3.2 KiB
Python
68 lines
3.2 KiB
Python
import logging
|
|
|
|
import streamlit as st
|
|
from streamlit_authenticator import Authenticate
|
|
# Imports from this module
|
|
from page_classes.funding_milestones_page_class import NetworkFundingMilestonesReportPage
|
|
from utility_classes.base_report_page import BaseReportPage
|
|
from page_classes.page_class_constants import REPORT_CONFIGS
|
|
from utility_classes.dashboard_config_parser import DashboardConfig
|
|
from streamlit_constants import DASHBOARD_CONFIG_OBJECT_KEY
|
|
|
|
class AuthenticationPageWrapper:
|
|
"""
|
|
Wraps a report page to enforce user authentication before rendering.
|
|
|
|
This class acts as a security gateway. It isolates the authentication state logic
|
|
from the underlying report rendering, ensuring that unauthenticated users
|
|
cannot instantiate or view protected components, while handling page-level configurations.
|
|
|
|
:param inner_report_page: The uninstantiated class of the report to display.
|
|
:type inner_report_page: type[BaseReportPage]
|
|
:param report_config: Keyword arguments required to instantiate the report.
|
|
:type report_config: dict
|
|
"""
|
|
def __init__(self, inner_report_page:type[BaseReportPage], report_config:dict):
|
|
self.inner_report_page = inner_report_page
|
|
self.report_config = report_config
|
|
self.app_config:DashboardConfig = st.session_state[DASHBOARD_CONFIG_OBJECT_KEY]
|
|
self.logger = logging.getLogger(__name__)
|
|
|
|
def run(self):
|
|
"""
|
|
Executes the authentication check and manages the encapsulated report lifecycle.
|
|
|
|
Checks the Streamlit session state for valid credentials. If authenticated,
|
|
it safely constructs and renders the underlying report page, catching and logging
|
|
any initialization or rendering exceptions to prevent application crashes.
|
|
"""
|
|
authenticator: Authenticate = st.session_state.get('authenticator')
|
|
|
|
st.set_page_config(layout='wide')
|
|
|
|
if st.session_state.get('authentication_status'):
|
|
st.sidebar.write(f'Welcome *{st.session_state.get("name")}*')
|
|
authenticator.logout(location="sidebar")
|
|
|
|
# Unpack the arguments and construct the page object
|
|
try:
|
|
page_class = self.inner_report_page(**self.report_config)
|
|
except Exception as e:
|
|
self.logger.exception(f"Failed to construct the report page. Got {e}")
|
|
st.error(f"Construction of page failed. A detailed error has been added to the logs. {self.app_config.get_errors_contact_string()}")
|
|
st.stop()
|
|
|
|
# Display it
|
|
try:
|
|
page_class.render(st.container())
|
|
except Exception as e:
|
|
self.logger.exception(f"Failed to render the page. Got {e}")
|
|
st.error(f"Rendering of page failed. A detailed error has been added to the logs. {self.app_config.get_errors_contact_string()}")
|
|
st.stop()
|
|
|
|
elif st.session_state.get('authentication_status') is False:
|
|
st.error(f'Username/password is incorrect. {self.app_config.get_errors_contact_string()}')
|
|
elif st.session_state.get('authentication_status') is None:
|
|
st.warning('Please enter your username and password')
|
|
|