From e0ab950431d9189dc66090da3fcad8be27330b3e Mon Sep 17 00:00:00 2001 From: MrWhiff Date: Tue, 9 Dec 2025 17:06:23 +0100 Subject: [PATCH] =?UTF-8?q?Astra=20OS=20Ver.=201.1=20hinzugef=C3=BCgt:=20-?= =?UTF-8?q?=20Bugfixes=20-=20Funktionen=20mit=20Dahboard=20zsw=20hinzugef?= =?UTF-8?q?=C3=BCgt=20-=20Bereit=20f=C3=BCr=20release=20-=20Icon=20hizugef?= =?UTF-8?q?=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AstraOS/Frontend/HTML/dashboard.html | 57 +++- AstraOS/Frontend/HTML/login.html | 1 + .../Frontend/HTML/maintenance_management.html | 12 + AstraOS/Frontend/HTML/sidebar.html | 23 +- AstraOS/Frontend/HTML/status_page.html | 61 +++-- AstraOS/Frontend/HTML/user_management.html | 88 +++++-- AstraOS/Frontend/media/AstraOS_Logo.ico | Bin 0 -> 187545 bytes AstraOS/astra_os.py | 245 +++++++++++++++--- 8 files changed, 390 insertions(+), 97 deletions(-) create mode 100644 AstraOS/Frontend/media/AstraOS_Logo.ico diff --git a/AstraOS/Frontend/HTML/dashboard.html b/AstraOS/Frontend/HTML/dashboard.html index 1cf8eb1..5522252 100644 --- a/AstraOS/Frontend/HTML/dashboard.html +++ b/AstraOS/Frontend/HTML/dashboard.html @@ -12,6 +12,20 @@ box-shadow: 0 0 20px rgba(192,132,252,0.3); transform: translateY(-4px); } +/* Schriftgröße für Systemstatus-Text im Wartungsmodus noch kleiner und mittig */ +#system-status-text.small { + font-size: 2rem; + text-align: center; + margin: 0 auto; + display: block; +} +#system-status-desc .wartung-desc { + font-size: 0.75rem; + display: block; + text-align: center; + margin: 0 auto; + font-weight: 500; +} {% endblock %} @@ -62,16 +76,30 @@ -
+

Systemstatus

{% set status = stats.system_status.status %} -

{{ status }}

-

Alle Systeme funktionsfähig

+

+ {{ status }} +

+

+ {% if 'wartung' in status.lower() or 'systeme im wartungsmodus' in status.lower() %} + Systeme im Wartungsmodus + {% elif 'online' in status.lower() %} + Alle Systeme funktionsfähig + {% else %} + Teilweise oder komplett offline + {% endif %} +

+ {% if maintenance_active %}border border-yellow-500/30{% else %}border border-purple-500/20{% endif %}">

Geplante Wartung

{% set maint = stats.scheduled_maintenance %} {% if maint and maint.enabled %} @@ -165,5 +193,26 @@ function updateServerLoad() { } setInterval(updateServerLoad, 5000); updateServerLoad(); + +// Systemstatus dynamisch Randfarbe anpassen +function updateSystemStatusCard() { + const card = document.getElementById('system-status-card'); + const statusText = document.getElementById('system-status-text'); + if (!card || !statusText) return; + card.classList.remove('border-green-500/40', 'border-yellow-500/40', 'border-red-500/40'); + statusText.classList.remove('small'); + const status = statusText.textContent.toLowerCase(); + if (status.includes('wartung') || status.includes('systeme im wartungsmodus')) { + card.classList.add('border-yellow-500/40'); + statusText.classList.add('small'); + } else if (status.includes('online')) { + card.classList.add('border-green-500/40'); + } else { + card.classList.add('border-red-500/40'); + } +} +setTimeout(updateSystemStatusCard, 100); // initial nach Render +// Optional: falls Systemstatus dynamisch per AJAX kommt, hier regelmäßig prüfen +setInterval(updateSystemStatusCard, 2000); {% endblock %} diff --git a/AstraOS/Frontend/HTML/login.html b/AstraOS/Frontend/HTML/login.html index 65fdbcf..7ef1865 100644 --- a/AstraOS/Frontend/HTML/login.html +++ b/AstraOS/Frontend/HTML/login.html @@ -4,6 +4,7 @@ AstraOS — Login + diff --git a/AstraOS/Frontend/HTML/maintenance_management.html b/AstraOS/Frontend/HTML/maintenance_management.html index 0a0d0c1..106cfe2 100644 --- a/AstraOS/Frontend/HTML/maintenance_management.html +++ b/AstraOS/Frontend/HTML/maintenance_management.html @@ -40,6 +40,18 @@
+ +
+
+

Discord Bots Wartungsmodus

+

Setzt alle Discord Bots in den Wartungsmodus (Status wird auf der Status-Seite angezeigt).

+
+ +
+
diff --git a/AstraOS/Frontend/HTML/sidebar.html b/AstraOS/Frontend/HTML/sidebar.html index 32793b8..933964f 100644 --- a/AstraOS/Frontend/HTML/sidebar.html +++ b/AstraOS/Frontend/HTML/sidebar.html @@ -4,6 +4,7 @@ {% block title %}AstraOS{% endblock %} + @@ -15,7 +16,6 @@ overflow-x: hidden; min-height: 100vh; } - /* Custom Checkbox */ .custom-checkbox-label { display: flex; align-items: center; @@ -28,7 +28,7 @@ .custom-checkbox-box { width: 20px; height: 20px; - border: 2px solid #4a5568; /* gray-600 */ + border: 2px solid #4a5568; border-radius: 4px; display: flex; align-items: center; @@ -44,18 +44,16 @@ transition: transform 0.2s ease-in-out; } .custom-checkbox-label input[type="checkbox"]:checked + .custom-checkbox-box { - background-color: #8b5cf6; /* purple-500 */ + background-color: #8b5cf6; border-color: #8b5cf6; } .custom-checkbox-label.maintenance input[type="checkbox"]:checked + .custom-checkbox-box { - background-color: #ca8a04; /* yellow-500 */ + background-color: #ca8a04; border-color: #ca8a04; } .custom-checkbox-label input[type="checkbox"]:checked + .custom-checkbox-box svg { transform: scale(1); } - - /* Footer */ footer { text-align: center; padding: 1rem; @@ -63,7 +61,6 @@ color: #888; background: rgba(0,0,0,0.3); } - /* Loading Screen fix: wirklich alles abdecken */ #startup { position: fixed; top: 0; left: 0; right: 0; bottom: 0; @@ -127,7 +124,6 @@ -
@@ -139,12 +135,9 @@

AstraOS

-
-
-
-
-
- System Status -
- +
Chainsaw Hood SCP:SL Server
- Online -
+ Lädt... +
- -
Kettensägen Gamepanel
- Online -
+ Lädt... +
- -
Discord Bots
- Wartungsarbeiten -
+ Lädt... +
- -
Datenbank
- Offline -
+ Lädt... +
+ {% endblock %} diff --git a/AstraOS/Frontend/HTML/user_management.html b/AstraOS/Frontend/HTML/user_management.html index 1b9e4e9..124dde1 100644 --- a/AstraOS/Frontend/HTML/user_management.html +++ b/AstraOS/Frontend/HTML/user_management.html @@ -7,12 +7,25 @@ {% endblock %} {% block content %} -
+

User Management

- @@ -32,13 +45,14 @@ - {% for user in users %} + {% for user_table_item in users_for_table %} - {{ user.username }} - {{ user.role_name }} - {{ user.creation_date.strftime('%d.%m.%Y') if user.creation_date else 'N/A' }} + {{ user_table_item.username }} + {{ user_table_item.role_name }} + {{ user_table_item.creation_date.strftime('%d.%m.%Y') if user_table_item.creation_date else 'N/A' }} - + + {% endfor %} @@ -47,33 +61,58 @@
- + + + +
{% endblock %} diff --git a/AstraOS/Frontend/media/AstraOS_Logo.ico b/AstraOS/Frontend/media/AstraOS_Logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..4e640e28e285721b75613a45db903ec1cc407bfc GIT binary patch literal 187545 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 N002ovPDHLkV1gOphCu)T literal 0 HcmV?d00001 diff --git a/AstraOS/astra_os.py b/AstraOS/astra_os.py index b8e69c5..c8af718 100644 --- a/AstraOS/astra_os.py +++ b/AstraOS/astra_os.py @@ -15,6 +15,8 @@ import threading from werkzeug.utils import secure_filename import requests import ipaddress +import socket +import ssl # Verwenden Sie eventlet für die Produktion async_mode = "threading" @@ -33,10 +35,14 @@ app.config['BOT_UPLOAD_FOLDER'] = BOT_UPLOAD_FOLDER # Dictionary zum Speichern laufender Bot-Prozesse running_bots = {} -# Filter, um die GET /api/server_load Anfragen aus den Logs auszublenden +# Filter, um die GET /api/server_load und GET /api/system_status Anfragen aus den Logs auszublenden class SuppressServerLoadFilter(logging.Filter): def filter(self, record): - return "GET /api/server_load" not in record.getMessage() + msg = record.getMessage() + return ( + "GET /api/server_load" not in msg + and "GET /api/system_status" not in msg + ) # Den Filter zum Werkzeug-Logger hinzufügen log = logging.getLogger('werkzeug') @@ -233,6 +239,95 @@ def login(): return render_template('login.html') +@app.route('/api/server_load') +@login_required +def api_server_load(): + # SSH zu 89.144.42.175, user root, pw iwkms@1812:( + try: + ssh = paramiko.SSHClient() + ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + # Timeout zur Verbindung hinzugefügt, um Hängenbleiben zu verhindern + ssh.connect("89.144.42.175", username="root", password="iwkms@1812:(", timeout=10) + stdin, stdout, stderr = ssh.exec_command("top -bn1 | grep 'Cpu(s)'") + output = stdout.read().decode() + ssh.close() + # Parse CPU usage + import re + match = re.search(r"(\d+\.\d+)\s*id", output) + if match: + idle = float(match.group(1)) + usage = 100 - idle + return jsonify({"percent": round(usage, 1), "status": "Online"}) + else: + return jsonify({"percent": 0, "status": "Fehler"}) + except paramiko.AuthenticationException: + print("SSH-Fehler: Authentifizierung fehlgeschlagen.") + return jsonify({"percent": 0, "status": "Auth Fehler"}) + except paramiko.SSHException as e: + print(f"SSH-Fehler: {e}") + return jsonify({"percent": 0, "status": "SSH Fehler"}) + except Exception as e: + print(f"Allgemeiner Fehler bei Server-Auslastung: {e}") + return jsonify({"percent": 0, "status": "Nicht erreichbar"}) + +@app.route('/api/system_status') +@login_required +def api_system_status(): + # Wartungsstatus prüfen + maintenance_status = dashboard_collection.find_one({"key": "scheduled_maintenance"}) if dashboard_collection is not None else None + maintenance_active = maintenance_status and maintenance_status.get('enabled', False) + discord_bots_maintenance = maintenance_status.get('discord_bots_maintenance', False) if maintenance_status else False + + # SCP:SL Server Status (UDP-Ping statt TCP) + scpsl_status = "offline" + try: + udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + udp_sock.settimeout(2) + udp_sock.sendto(b"\x00", ("89.144.42.175", 7101)) + # Wenn keine Exception, dann ist der Port erreichbar (Server antwortet nicht, aber Port offen) + scpsl_status = "online" + udp_sock.close() + except Exception as e: + print(f"[DEBUG] SCP:SL UDP-Ping failed: {e}") + scpsl_status = "offline" + if maintenance_active: + scpsl_status = "wartung" + + # Gamepanel Status + gamepanel_status = "offline" + try: + resp = requests.get("https://gamepanel.mrsniff.de", timeout=3) + if resp.status_code == 200: + gamepanel_status = "online" + except Exception: + gamepanel_status = "offline" + if maintenance_active: + gamepanel_status = "wartung" + + # Discord Bots Status (online/wartung) + discord_bots_status = "wartung" if discord_bots_maintenance or maintenance_active else "online" + + # Datenbank Status + db_status = "online" if db is not None else "offline" + if maintenance_active: + db_status = "wartung" + + return jsonify({ + "scpsl": scpsl_status, + "gamepanel": gamepanel_status, + "discord_bots": discord_bots_status, + "database": db_status, + "maintenance": maintenance_active + }) + +@app.route('/status') +@login_required +def status_page(): + # Wartungsstatus prüfen + maintenance_status = dashboard_collection.find_one({"key": "scheduled_maintenance"}) if dashboard_collection is not None else None + maintenance_active = maintenance_status and maintenance_status.get('enabled', False) + return render_template('status_page.html', active_page='status_page', maintenance_active=maintenance_active) + @app.route('/dashboard') @login_required def dashboard(): @@ -252,8 +347,25 @@ def dashboard(): # Server-Auslastung (wird per AJAX geladen, hier nur Platzhalter) server_load = {"percent": 0, "status": "Lädt..."} - # Systemstatus (hier statisch, ggf. anpassen) + # Systemstatus per API holen (wie Status-Seite) system_status = {"status": "Online"} + try: + resp = requests.get(request.url_root.rstrip('/') + '/api/system_status', cookies=request.cookies, timeout=2) + if resp.status_code == 200: + data = resp.json() + # Priorität: Wartung > Wartungsmodus > Offline > Online + if data.get("maintenance"): + system_status = {"status": "Online (Wartungsarbeiten)"} + elif any(data.get(k) == "wartung" for k in ["scpsl", "gamepanel", "discord_bots", "database"]): + system_status = {"status": "Systeme im Wartungsmodus"} + elif all(data.get(k) == "online" for k in ["scpsl", "gamepanel", "discord_bots", "database"]): + system_status = {"status": "Online"} + else: + system_status = {"status": "Offline"} + else: + system_status = {"status": "Offline"} + except Exception: + system_status = {"status": "Offline"} # Geplante Wartung (aus dashboard_stats falls vorhanden) scheduled_maintenance = dashboard_collection.find_one({"key": "scheduled_maintenance"}) if dashboard_collection is not None else None @@ -268,7 +380,7 @@ def dashboard(): maint["time_str"] = _dt_to_str(maint.get("time")) stats = { - "active_users": {"value": user_count, "percent": 0}, # Prozent ggf. später berechnen + "active_users": {"value": user_count, "percent": 0}, "server_load": server_load, "open_tickets": {"count": open_tickets}, "system_status": system_status, @@ -282,29 +394,6 @@ def dashboard(): return render_template('dashboard.html', stats=stats, active_page='dashboard') -@app.route('/api/server_load') -@login_required -def api_server_load(): - # SSH zu 89.144.42.175, user root, pw iwkms@1812:( - try: - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - ssh.connect("89.144.42.175", username="root", password="iwkms@1812:(") - stdin, stdout, stderr = ssh.exec_command("top -bn1 | grep 'Cpu(s)'") - output = stdout.read().decode() - ssh.close() - # Parse CPU usage - import re - match = re.search(r"(\d+\.\d+)\s*id", output) - if match: - idle = float(match.group(1)) - usage = 100 - idle - return jsonify({"percent": round(usage, 1), "status": "Online"}) - else: - return jsonify({"percent": 0, "status": "Fehler"}) - except Exception as e: - return jsonify({"percent": 0, "status": "Nicht erreichbar"}) - @app.route('/logout') @login_required def logout(): @@ -312,10 +401,7 @@ def logout(): flash("Sie wurden erfolgreich abgemeldet.", "info") return redirect(url_for('login')) -@app.route('/status') -@login_required -def status_page(): - return render_template('status_page.html', active_page='status_page') +# --- User Management --- @app.route('/user_management') @login_required @@ -328,12 +414,32 @@ def user_management(): users_list = list(accounts_collection.find()) roles_list = list(roles_collection.find()) - role_map = {str(role['_id']): role['name'] for role in roles_list} + # Konvertiere ObjectId in String für die JSON-Serialisierung in roles_list + for role in roles_list: + role['_id'] = str(role['_id']) + role_map = {role['_id']: role['name'] for role in roles_list} + + # Daten für das Alpine.js Modal vorbereiten (ohne Datum) + users_for_modal = {} for user in users_list: + user_id_str = str(user['_id']) + users_for_modal[user_id_str] = { + '_id': user_id_str, + 'username': user['username'], + 'role_id': str(user.get('role_id')) if user.get('role_id') else None + } + + # Erstelle eine separate Liste für die Anzeige in der Tabelle, die das Datum enthält + users_for_table = list(accounts_collection.find()) + for user in users_for_table: user['role_name'] = role_map.get(str(user.get('role_id')), 'Unbekannt') - return render_template('user_management.html', users=users_list, roles=roles_list, active_page='user_management') + return render_template('user_management.html', + users_for_modal=users_for_modal, + users_for_table=users_for_table, + roles=roles_list, + active_page='user_management') @app.route('/add_user', methods=['POST']) @login_required @@ -382,6 +488,45 @@ def add_user(): flash(f"Benutzer '{username}' wurde erfolgreich erstellt.", "success") return redirect(url_for('user_management')) +@app.route('/edit_user/', methods=['POST']) +@login_required +@permission_required('manage_users') +def edit_user(user_id): + if accounts_collection is None: + flash("Datenbankverbindung nicht verfügbar.", "danger") + return redirect(url_for('user_management')) + + username = request.form.get('username') + password = request.form.get('password') + role_id = request.form.get('role') + + if not username or not role_id: + flash("Benutzername und Rolle sind erforderlich.", "danger") + return redirect(url_for('user_management')) + + # Überprüfen, ob der neue Benutzername bereits von einem anderen Benutzer verwendet wird + existing_user = accounts_collection.find_one({'username': username}) + if existing_user and str(existing_user['_id']) != user_id: + flash("Ein anderer Benutzer mit diesem Namen existiert bereits.", "danger") + return redirect(url_for('user_management')) + + update_data = { + 'username': username, + 'role_id': ObjectId(role_id) + } + + # Passwort nur aktualisieren, wenn ein neues eingegeben wurde + if password: + update_data['password'] = generate_password_hash(password) + + accounts_collection.update_one( + {'_id': ObjectId(user_id)}, + {'$set': update_data} + ) + + flash(f"Benutzer '{username}' wurde erfolgreich aktualisiert.", "success") + return redirect(url_for('user_management')) + @app.route('/delete_user/', methods=['POST']) @login_required @permission_required('manage_users') @@ -398,6 +543,8 @@ def delete_user(user_id): flash("Benutzer wurde erfolgreich gelöscht.", "success") return redirect(url_for('user_management')) +# --- Role Management --- + @app.route('/role_management') @login_required @permission_required('view_role_management') @@ -781,8 +928,10 @@ def maintenance_login(): def maintenance_management(): maint_info = dashboard_collection.find_one({"key": "scheduled_maintenance"}) if dashboard_collection is not None else {} if maint_info and maint_info.get('time'): - # Konvertiere UTC-Zeit aus DB in ein für datetime-local passendes Format maint_info['time_local_str'] = maint_info['time'].strftime('%Y-%m-%dT%H:%M') + # Discord Bots Wartungsstatus für das Template bereitstellen + if 'discord_bots_maintenance' not in maint_info: + maint_info['discord_bots_maintenance'] = False return render_template('maintenance_management.html', active_page='maintenance_management', maint_info=maint_info) @app.route('/update_maintenance', methods=['POST']) @@ -797,12 +946,14 @@ def update_maintenance(): status_message = request.form.get('status_message', 'Keine') duration = request.form.get('duration_minutes') time_str = request.form.get('maintenance_time') + discord_bots_maintenance = request.form.get('discord_bots_maintenance') == 'on' update_data = { "enabled": is_enabled, "status": status_message, "duration_minutes": int(duration) if duration and duration.isdigit() else None, - "time": datetime.fromisoformat(time_str) if time_str else None + "time": datetime.fromisoformat(time_str) if time_str else None, + "discord_bots_maintenance": discord_bots_maintenance } dashboard_collection.update_one( @@ -815,4 +966,26 @@ def update_maintenance(): return redirect(url_for('maintenance_management')) if __name__ == '__main__': - socketio.run(app, host='0.0.0.0', port=5000, debug=True, allow_unsafe_werkzeug=True) + # Optionale SSL-Unterstützung: + # Legen Sie entweder die Umgebungsvariablen SSL_CERT_FILE und SSL_KEY_FILE fest + # oder legen Sie die Dateien certs/fullchain.pem und certs/privkey.pem im Projektordner ab. + cert_file = os.environ.get('SSL_CERT_FILE', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'certs', 'fullchain.pem')) + key_file = os.environ.get('SSL_KEY_FILE', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'certs', 'privkey.pem')) + + use_ssl = os.path.exists(cert_file) and os.path.exists(key_file) + + # Sitzungscookies nur als Secure markieren, wenn tatsächlich HTTPS verwendet wird + app.config['SESSION_COOKIE_SECURE'] = bool(use_ssl) + + if use_ssl: + print(f"INFO: Starte mit SSL, cert={cert_file}, key={key_file}") + # Für bessere Kontrolle können Sie auch ein SSLContext erstellen: + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 + context.load_cert_chain(certfile=cert_file, keyfile=key_file) + # In Produktion debug=False setzen und Port 443 verwenden (oder Reverse Proxy) + socketio.run(app, host='0.0.0.0', port=443, debug=False, ssl_context=context) + else: + print("WARNUNG: SSL-Zertifikat nicht gefunden. Starte ohne HTTPS (nur für Entwicklung).") + # allow_unsafe_werkzeug bleibt hier, da dies Entwicklungsmodus ist + socketio.run(app, host='0.0.0.0', port=5000, debug=True, allow_unsafe_werkzeug=True)