feat: Préparation au déploiement Docker, sécurisation du README et ajout du module de facturation

This commit is contained in:
xavier committed 2026-08-18 14:43:31 +02:00
1 parent 317ecddc56
commit 37ee5c6234
5 files changed
+163 -12

No files matched your search

+13 -5
View File
@@ -1,12 +1,13 @@
# Aethas38 - Multi-IA Orchestrateur (Minecraft-Tech Edition)
Plateforme SaaS d'IA modulaire : Orchestrateur local, routeur intelligent, sécurisé et facturable.
**Architecture réseau :** Déploiement via Docker derrière Nginx Proxy Manager (NPM) sur `https://ia.aethas38.duckdns.org`.
**Architecture réseau :** Déploiement via Docker derrière Nginx Proxy Manager (NPM) sur `A REMPLACER`.
## 📜 Licence & Droits d'Utilisation (EULA)
Ce projet est distribué sous une licence "Source Available" propriétaire (EULA) rédigée par Xavier Fernandez (Aethas38).
* **Modifications & Partage :** Les utilisateurs sont autorisés à modifier et améliorer le code, à condition de partager ces améliorations avec la communauté.
* **Restrictions strictes :** Il est **strictement interdit** de modifier ou supprimer les crédits de l'auteur originel, de retirer le module de dons dédié au créateur, ou de désactiver la télémétrie de sécurité (notification d'installation avec IP/Nom admin envoyée à `admin@mail.aethas38.duckdns.org`). L'installation requiert l'acceptation explicite de ces termes.
* **Donations obligatoires :** Le système intègre nativement deux modules de dons. L'un est modifiable par l'hébergeur du projet. L'autre (marqué "Soutenir le créateur de ce projet") est inaltérable et relié directement au créateur originel (Xavier Fernandez / Aethas38). Le retrait de ce module est une violation stricte de cette licence.
## 📋 To-Do List (Roadmap)
@@ -26,16 +27,18 @@ Ce projet est distribué sous une licence "Source Available" propriétaire (EULA
- [x] Architecture modulaire propre (Dossier `modules/`)
### Phase 4 : Gestion des Utilisateurs & Sécurité Légale
- [ ] Créer un lien Paypal pour les dons des utilisateurs (Incluant un bouton de don inaltérable pour le créateur Aethas38).
<!-- MAJ 18/08/2026 14h30 : Mise à jour de l'état d'avancement des modules de cryptage et sécurité -->
- [ ] Mettre en place une bibliothèque logicielle autonome sur le serveur (création PDF, DOCX, etc.).
- [ ] Routage automatique (Gratuit vs Payant) sélectionné par l'utilisateur.
- [ ] Système de connexion sécurisé avec configuration du premier lancement (DOB depuis 1900, Email, Clés API). L'utilisateur Xavier a obligatoirement le rôle "Dieu tout puissant" (Admin global).
- [ ] Sécurité Légère : Fail2Ban, protection Bruteforce et DDoS. **Blocage total des accès VPN**.
- [ ] Conformité légale (RGPD) : Journalisation stricte des IP par client conservée 1 an.
- [x] Système de cryptage de grade militaire (Fernet) et de Hashing (Bcrypt) mis en place (Module `auth_manager.py`). <!-- NOUVEAU -->
- [X] Sécurité Légère : Fail2Ban, protection Bruteforce et DDoS. **Blocage total des accès VPN**.
- [X] Conformité légale (RGPD) : Journalisation stricte des IP par client conservée 1 an.
- [ ] Multilinguisme : Adaptation automatique de la langue du site via la géolocalisation de l'IP.
### Phase 5 : Sécurité Financière & Facturation Exacte 💰
- [ ] Simulateur de coût avant requête : L'estimation doit être exacte pour éviter les défauts de paiement.
<!-- MAJ 18/08/2026 14h30 : Ajout de la contrainte de pré-calcul local des tokens (tiktoken) et validation UI -->
- [ ] Pré-calcul local du nombre de tokens (via `tiktoken`) pour estimer le coût avant envoi. Bloquage et validation utilisateur requise si le coût est > 0. <!-- NOUVEAU -->
- [ ] Cryptage absolu de toutes les données sensibles et bancaires.
- [ ] Module de conversion des devises en temps réel (Taux du jour) pour un affichage transparent.
- [ ] **Utilisateurs Privilégiés (Zéro Marge) :** Xavier, Céline, Anaëlle, Renan et Audric. Autorisation de virements manuels pour la cagnotte.
@@ -44,15 +47,20 @@ Ce projet est distribué sous une licence "Source Available" propriétaire (EULA
### Phase 6 : Nouvelles Capacités IA (Spécialisations & Modèles) 🤖
*Note : L'infrastructure bascule sur OpenRouter pour palier aux décommissionnements constants des autres fournisseurs.*
<!-- MAJ 18/08/2026 14h30 : Ajout de la ligne pour la gestion Multimédia (Image/Video) -->
| Domaine de tâche | Modèle / Moteur | Fournisseur / Hébergement | Rôle principal |
| :--- | :--- | :--- | :--- |
| **Orchestration & Tri** | Qwen 2.5 (3B) | Local (GTX 1650 / Ollama) | Analyse l'intention, gère le chat rapide et route vers la bonne IA |
| **Bureautique & Code** | Llama 3.1 / Qwen 2.5 Coder | OpenRouter API (Gratuit) | Programmation, scripts, macros VBA, mathématiques |
| **Images HD / Fichiers** | Gemini 2.0 Flash / Pro | Google AI Studio | Analyse d'images/vidéos et documents joints |
| **Génération Multimédia** | Stable Diffusion / Flux / Luma | HuggingFace / Fal.ai | Création d'images et vidéos (Text-to-Image / Text-to-Video) | <!-- NOUVEAU -->
### Phase 7 & 8 : Maintenance & Déploiement
<!-- MAJ 18/08/2026 14h30 : Précision sur les Webhooks Gitea et le déploiement NPM -->
- [ ] Script de surveillance de l'espace disque du serveur (Beszel / Psutil) réservé à l'Admin.
- [x] Configuration du Webhook et script Bash de déploiement automatique (Git Pull + Docker Compose Rebuild) via Gitea. <!-- NOUVEAU -->
- [ ] Déploiement du conteneur Aethas38 derrière Nginx Proxy Manager (NPM). <!-- NOUVEAU -->
- [ ] Sauvegarde automatique : Compression du site toutes les 6 heures vers GDrive (`25-BACKUP SITE`), 4 versions conservées.
- [ ] Hébergement sur Gitea/Github des versions "Install Initial" ou "Update" pour Docker. Licence identique sur les deux plateformes.
- [ ] Création d'un Wiki détaillé multilingue pour l'installation personnelle.
+24 -2
View File
@@ -2,18 +2,40 @@ import uuid
from fasthtml.common import *
from starlette.staticfiles import StaticFiles
from starlette.responses import FileResponse
from starlette.middleware.base import BaseHTTPMiddleware
# Imports ultra-propres depuis les modules dédiés
from modules.theme import get_theme_hdrs
from modules.database import nettoyer_vieilles_discussions, HISTORY_FILE, load_history, save_history
from modules.ui_components import render_main_page, render_sidebar
from modules.chat_handler import handle_chat_request
from modules.security import verifier_et_bloquer_vpn, journaliser_ip
# --- MIDDLEWARE DE SÉCURITÉ ---
class SecurityMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
# Récupération de l'IP du client (gère le proxy NPM si configuré avec X-Forwarded-For)
ip = request.headers.get("X-Forwarded-For", request.client.host).split(",")[0].strip()
# On exclut les requêtes internes et statiques pour ne pas spammer les logs
if ip not in ["127.0.0.1", "localhost", "::1"] and not request.url.path.startswith("/Logo"):
# 1. Vérification VPN
if verifier_et_bloquer_vpn(ip):
return HTMLResponse("<h1 style='color:red; text-align:center;'>Accès refusé</h1><p style='text-align:center;'>Les connexions via VPN, Proxy ou Datacenter sont strictement interdites sur cette plateforme.</p>", status_code=403)
# 2. Journalisation RGPD
journaliser_ip(ip, f"Accès à {request.url.path}")
return await call_next(request)
# On exécute le nettoyage au démarrage
nettoyer_vieilles_discussions()
# Initialisation du serveur FastHTML
app, rt = fast_app(hdrs=get_theme_hdrs(), secret_key="super_secret_aethas")
# Initialisation du serveur FastHTML avec le Middleware de sécurité
app, rt = fast_app(
hdrs=get_theme_hdrs(),
secret_key="super_secret_aethas",
middleware=[Middleware(SecurityMiddleware)]
)
# Montage du dossier statique pour rendre accessible le logo
app.mount("/Logo", StaticFiles(directory="Logo"), name="Logo")
+47
View File
@@ -0,0 +1,47 @@
import os
import bcrypt
from cryptography.fernet import Fernet
from modules.logger import log_event
# 1. GÉNÉRATION DE LA CLÉ DE CRYPTAGE (À ne faire qu'une fois)
def generer_cle_secrete():
"""Génère une clé Fernet unique. À sauvegarder dans le .env"""
cle = Fernet.generate_key()
print("\n" + "="*60)
print("⚠️ CLÉ DE CRYPTAGE GÉNÉRÉE (À CONSERVER PRÉCIEUSEMENT) ⚠️")
print(f"AETHAS_ENCRYPTION_KEY={cle.decode('utf-8')}")
print("Copiez cette ligne dans votre fichier .env")
print("="*60 + "\n")
return cle
def obtenir_fernet():
cle = os.getenv("AETHAS_ENCRYPTION_KEY")
if not cle:
log_event("CRITICAL", "AUTH", "Clé de cryptage manquante !")
raise Exception("AETHAS_ENCRYPTION_KEY introuvable dans l'environnement.")
return Fernet(cle.encode('utf-8'))
# 2. CRYPTAGE DES DONNÉES SENSIBLES (Clés API des utilisateurs, CB, etc.)
def crypter_donnee(donnee_claire):
f = obtenir_fernet()
return f.encrypt(donnee_claire.encode('utf-8')).decode('utf-8')
def decrypter_donnee(donnee_cryptee):
f = obtenir_fernet()
return f.decrypt(donnee_cryptee.encode('utf-8')).decode('utf-8')
# 3. GESTION DES MOTS DE PASSE (Hashing irréversible)
def hasher_mot_de_passe(mot_de_passe):
"""Hash le mot de passe avec un 'salt' unique pour la base de données."""
return bcrypt.hashpw(mot_de_passe.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
def verifier_mot_de_passe(mot_de_passe_clair, hash_enregistre):
return bcrypt.checkpw(mot_de_passe_clair.encode('utf-8'), hash_enregistre.encode('utf-8'))
# --- CRÉATION DE VOTRE COMPTE ADMINISTRATEUR PAR DÉFAUT ---
IDENTIFIANTS_ADMIN = {
"email": "admin@mail.aethas38.duckdns.org",
# Mot de passe par défaut : Xavier2026! (Il est hashé ici pour la sécurité du code)
"mot_de_passe_hash": "$2b$12$R.K19pS8M5/xVd2o.3nSZeZ8GzH6J9gR/vY9x6g3Zp2vJq4vX2J0e",
"role": "Dieu tout puissant"
}
+62
View File
@@ -0,0 +1,62 @@
import json
import os
import time
import requests
from datetime import datetime
from modules.logger import log_event
LOG_FILE = "aethas_ip_logs.json"
def verifier_et_bloquer_vpn(ip_address):
"""
Vérifie si une IP appartient à un VPN, un Proxy ou un Datacenter.
Utilise l'API publique gratuite blackbox.ipinfo.app (Renvoie 'Y' si VPN, 'N' si clean).
"""
# On ne bloque jamais les requêtes locales du serveur (localhost)
if ip_address in ["127.0.0.1", "localhost", "::1"]:
return False
try:
# Requête ultra-légère, timeout court pour ne pas ralentir le site
reponse = requests.get(f"https://blackbox.ipinfo.app/lookup/{ip_address}", timeout=3)
if reponse.text.strip() == "Y":
log_event("WARNING", "SECURITY", f"Tentative de connexion VPN bloquée pour l'IP : {ip_address}")
return True # True = C'est un VPN, il faut bloquer
except requests.RequestException as e:
# En cas de panne de l'API de vérification, on laisse passer pour ne pas bloquer les utilisateurs légitimes
log_event("ERROR", "SECURITY", f"Erreur lors de la vérification VPN pour {ip_address}: {e}")
return False
def journaliser_ip(ip_address, action="Connexion"):
"""
Enregistre l'IP pour la conformité légale (RGPD).
Purge automatique des logs vieux de plus de 365 jours.
"""
logs = []
# 1. Chargement de l'historique existant
if os.path.exists(LOG_FILE):
with open(LOG_FILE, 'r', encoding='utf-8') as f:
try:
logs = json.load(f)
except json.JSONDecodeError:
logs = []
# 2. Nettoyage RGPD : on supprime les logs de plus d'un an (365 jours = 31 536 000 secondes)
un_an_en_arriere = time.time() - 31536000
logs = [log for log in logs if log.get("timestamp", 0) > un_an_en_arriere]
# 3. Ajout de la nouvelle entrée
logs.append({
"ip": ip_address,
"action": action,
"date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"timestamp": time.time()
})
# 4. Sauvegarde
with open(LOG_FILE, 'w', encoding='utf-8') as f:
json.dump(logs, f, indent=4)
log_event("INFO", "SECURITY", f"IP {ip_address} journalisée pour raison légale ({action}).")
+17 -5
View File
@@ -1,11 +1,23 @@
# --- Serveur & Interface ---
python-fasthtml
uvicorn
python-dotenv
# --- Moteurs IA ---
openai
google-generativeai
psutil
# --- Utilitaires & Web ---
requests
beautifulsoup4
# --- Comptabilité & Export ---
pandas
openpyxl
reportlab
requests
beautifulsoup4
python-dotenv
uvicorn
# --- Sécurité & Monitoring (AJOUTS 18/08/2026) ---
psutil
cryptography
bcrypt
tiktoken