| | |
| |
|
| | import sqlite3 |
| | import hashlib |
| | from pathlib import Path |
| | import streamlit as st |
| | import pandas as pd |
| | from src.security.security_report import SecurityReport |
| |
|
| | from views.home import arret_enregistrement |
| |
|
| | db_path = Path(__file__).parent.parent.parent / "database" / "db_logsv2.db" |
| |
|
| | query = """ |
| | SELECT |
| | log.id_log, |
| | log.timestamp, |
| | prompt.prompt, |
| | prompt.response, |
| | status.status, |
| | origin.origin AS origin |
| | FROM log |
| | LEFT JOIN prompt ON log.id_prompt = prompt.id_prompt |
| | LEFT JOIN status ON log.id_status = status.id_status |
| | LEFT JOIN origin ON log.id_origin = origin.id_origin |
| | ORDER BY log.timestamp DESC |
| | """ |
| |
|
| |
|
| | def check_password(): |
| | """ |
| | Fonction de vérification du mot de passe pour accéder à la page Admin. |
| | Renvoie True si le mot de passe saisi est correct, False sinon. |
| | """ |
| |
|
| | def password_entered(): |
| | """ |
| | Fonction pour comparer le hash du mot de passe saisi avec le hash attendu. |
| | Positionne la variable de session "password_correct" à True si le mot de passe est correct, |
| | à False sinon. |
| | """ |
| | if ( |
| | hashlib.sha256(st.session_state["password"].encode()).hexdigest() |
| | == "676bcf91f4659cccada503f86bfd836889318b87ab691ae812cb572f2e87aa87" |
| | ): |
| | st.session_state["password_correct"] = True |
| | else: |
| | st.session_state["password_correct"] = False |
| |
|
| | if "password_correct" not in st.session_state: |
| | |
| | st.text_input( |
| | "Password", type="password", on_change=password_entered, key="password" |
| | ) |
| | return False |
| | elif not st.session_state["password_correct"]: |
| | |
| | st.text_input( |
| | "Password", type="password", on_change=password_entered, key="password" |
| | ) |
| | st.error("😕 Password incorrect") |
| | return False |
| | else: |
| | |
| | return True |
| |
|
| |
|
| | def adm_page(): |
| | """ |
| | La page Admin permet de visualiser les données stockées dans la base de données, |
| | sous forme compacte grâce à la requête "query" définie ci-dessus. |
| | """ |
| | |
| | arret_enregistrement() |
| |
|
| | |
| | if check_password(): |
| | |
| | tab1, tab2, tab3, tab4 = st.tabs( |
| | [ |
| | "Évènements", |
| | "Rapport journalier", |
| | "Accès à l'API SmartRescue", |
| | "Paramétrer les clés API externes", |
| | ] |
| | ) |
| |
|
| | |
| | with tab1: |
| | st.markdown("## 🚨 Accès aux évènements SmartRescue") |
| |
|
| | |
| | st.sidebar.header("Filtres") |
| | items_per_page = st.sidebar.selectbox( |
| | "Éléments par page", [10, 20, 50, 100], 0 |
| | ) |
| |
|
| | start_date = st.sidebar.date_input( |
| | "Date de début", value=pd.to_datetime("2025-01-01") |
| | ) |
| | end_date = st.sidebar.date_input( |
| | "Date de fin", value=pd.to_datetime("today") |
| | ) |
| |
|
| | query_filtered = """ |
| | SELECT |
| | log.id_log, |
| | log.timestamp, |
| | prompt.prompt, |
| | prompt.response, |
| | status.status, |
| | origin.origin AS origin |
| | FROM log |
| | LEFT JOIN prompt ON log.id_prompt = prompt.id_prompt |
| | LEFT JOIN status ON log.id_status = status.id_status |
| | LEFT JOIN origin ON log.id_origin = origin.id_origin |
| | WHERE DATE(log.timestamp) >= DATE(?) AND DATE(log.timestamp) <= DATE(?) |
| | ORDER BY log.timestamp DESC |
| | """ |
| |
|
| | |
| | with sqlite3.connect(db_path) as conn: |
| | |
| | data = pd.read_sql_query( |
| | query_filtered, conn, params=(start_date, end_date) |
| | ) |
| | cols = [ |
| | "id_logs", |
| | "timestamp", |
| | "prompt", |
| | "response", |
| | "status", |
| | "origin", |
| | ] |
| |
|
| | if data.empty: |
| | data = pd.DataFrame(columns=cols) |
| |
|
| | total_items = len(data) |
| | total_pages = max(1, (total_items - 1) // items_per_page + 1) |
| |
|
| | if "current_page" not in st.session_state: |
| | st.session_state.current_page = 1 |
| |
|
| | |
| | current_page = st.sidebar.number_input( |
| | "Numéro de page", |
| | 1, |
| | total_pages, |
| | st.session_state.current_page, |
| | 1, |
| | ) |
| |
|
| | st.session_state.current_page = current_page |
| |
|
| | |
| | start_idx = (current_page - 1) * items_per_page |
| | end_idx = min(start_idx + items_per_page, total_items) |
| | st.write( |
| | f"Affichage des éléments {start_idx + 1} à {end_idx} sur {total_items}" |
| | ) |
| |
|
| | |
| | st.dataframe( |
| | data.iloc[start_idx:end_idx], use_container_width=True, hide_index=True |
| | ) |
| |
|
| | |
| | with tab2: |
| | st.markdown("## 📊 Rapport Logs") |
| | st.write( |
| | "Générez par mail un rapport détaillé des événements, incluant les alertes de sécurité, " |
| | "les activités suspectes et les tendances globales des interactions avec SmartRescue." |
| | ) |
| |
|
| | if st.button("📝 Générer le rapport"): |
| | st.write(f"db_path : {db_path}") |
| | report = SecurityReport() |
| | report.run_report() |
| | st.success("✅ Rapport généré avec succès !") |
| |
|
| | |
| | with tab3: |
| | st.markdown("## 🌐 API SmartRescue") |
| | st.markdown( |
| | """ |
| | Les données présentées dans l'onglet *Évènements* peuvent être consultées [via l'API SmartRescue](http://127.0.0.1:8901/docs). |
| | |
| | Voici quelques exemples de requêtes possibles : |
| | - Requête get sans critères : [http://127.0.0.1:8901/data](http://127.0.0.1:8901/data) |
| | - Requête get avec une date de début : [http://127.0.0.1:8901/data?start_date=2025-01-29](http://127.0.0.1:8901/data?start_date=2025-01-29) |
| | - Requête get avec une date de fin : [http://127.0.0.1:8901/data?end_date=2025-01-27](http://127.0.0.1:8901/data?end_date=2025-01-27) |
| | - Requête get avec une date de début et une date de fin : [http://127.0.0.1:8901/data?start_date=2025-01-28&end_date=2025-01-28](http://127.0.0.1:8901/data?start_date=2025-01-28&end_date=2025-01-28) |
| | """ |
| | ) |
| |
|
| | |
| | with tab4: |
| | st.markdown("## 🔑 Clés API externes") |
| |
|
| | |
| | st.write( |
| | "Pour utiliser l'API SmartRescue, vous devez fournir les clés API externes suivantes :" |
| | ) |
| |
|
| | api_key_hf = st.text_input( |
| | "HF_API_KEY", |
| | type="default", |
| | value=st.session_state.get("HF_API_KEY", ""), |
| | ) |
| | api_key_m = st.text_input( |
| | "MISTRAL_API_KEY", |
| | type="default", |
| | value=st.session_state.get("MISTRAL_API_KEY", ""), |
| | ) |
| |
|
| | if st.button("Submit"): |
| | st.session_state["HF_API_KEY"] = api_key_hf |
| | st.session_state["MISTRAL_API_KEY"] = api_key_m |
| | st.success("Les clés API ont été mises à jour avec succès.") |
| |
|