Coockies werden jetzt überprüft beim aufbauen der Seite. Ob der angemeldete Spieler mit dieser ID und der gespeicherten Discord ID WIRKLICH der aktuell angemeldete ist.

This commit is contained in:
Daniel Nagel 2026-03-09 12:05:11 +00:00
parent 32ce9cdaa7
commit 1221ae74cb
16 changed files with 62 additions and 20 deletions

View File

@ -1 +1 @@
{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":1,"display_name":"Chaos Servitor","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"}
{"authenticated":true,"discord_id":"277898241750859776","discord_name":"mrteels","db_id":2,"display_name":"Blinder Grot","discord_avatar_url":"https://cdn.discordapp.com/avatars/277898241750859776/7c3446bb51fafd72b1b4c21124b4994f.png"}

View File

@ -1,7 +1,29 @@
import sqlite3
import random
from data.setup_database import DB_PATH
def validate_user_session(db_id, discord_id):
"""Prüft, ob das Cookie noch zur aktuellen Datenbank passt."""
connection = sqlite3.connect(DB_PATH)
cursor = connection.cursor()
cursor.execute("SELECT discord_id FROM players WHERE id = ?", (db_id,))
result = cursor.fetchone()
connection.close()
# 1. Fall: Die ID gibt es gar nicht mehr in der Datenbank
if result is None:
return False
# 2. Fall: Die ID gehört jetzt einem anderen Discord-Account (Datenbank wurde resettet)
if str(result[0]) != str(discord_id):
return False
# 3. Fall: Alles ist korrekt!
return True
def change_display_name(player_id, new_name):
connection = sqlite3.connect(DB_PATH)
cursor = connection.cursor()

View File

@ -1,6 +1,7 @@
import sqlite3
import os
from data import setup_database, data_api
from data.setup_database import DB_PATH

View File

@ -1,13 +1,15 @@
import sqlite3
import os
import json
from dotenv import load_dotenv
load_dotenv()
DB_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "league_database.db")
dummy_is_in = True
# 1. Sucht den exakten, absoluten Pfad zu diesem Skript (z.B. /srv/Diceghost-Liga-System/data/)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 2. Klebt den Datenbank-Namen an diesen Ordner
DB_PATH = os.path.join(BASE_DIR, "league_database.db")
def init_db():
@ -116,9 +118,9 @@ def seed_gamesystems():
connection = sqlite3.connect(DB_PATH)
cursor = connection.cursor()
systems = [
("Warhammer 40k", "/gui/pictures/wsdg.png", "Die Schlacht um die Galaxie in einer entfernten Zukunft.", 0, 100),
("Warhammer Age of Sigmar", "/gui/pictures/wsdg.png", "Der ewige Krieg um die Reiche der Sterblichen in einer epischen Fantasy-Welt.", 0, 50),
("Spearhead", "/gui/pictures/wsdg.png", "Schnelle und taktische Scharmützel für actiongeladene Kämpfe.", 0, 50)
("Warhammer 40k", "40k_logo.png", "Die Schlacht um die Galaxie in einer entfernten Zukunft.", 0, 100),
("Warhammer Age of Sigmar", "aos_logo.png", "Der ewige Krieg um die Reiche der Sterblichen in einer epischen Fantasy-Welt.", 0, 50),
("Spearhead", "aos_logo.png", "Schnelle und taktische Scharmützel für actiongeladene Kämpfe.", 0, 50)
]
# executemany ist eine extrem schnelle SQL For-Schleife für Inserts

View File

@ -58,7 +58,7 @@ def setup_login_routes():
# 3. Prüfen: Hat er die richtige Rolle?
member_json = member_response.json()
# Wir holen die Liste aller Rollen des Nutzers. Wenn er keine hat, nehmen wir eine leere Liste []
# Liste aller Rollen des Nutzers. Wenn er keine hat, nehmen wir eine leere Liste []
user_roles = member_json.get('roles', [])
# Wir prüfen, ob mindestens eine der beiden Rollen-IDs in seiner Liste auftaucht

View File

@ -8,6 +8,21 @@ def setup_routes(admin_discord_id):
def home_page():
gui_style.apply_design()
# --- SICHERHEITS-CHECK (Hassan, DER TÜRSTEHER) ---
if app.storage.user.get('authenticated', False):
db_id = app.storage.user.get('db_id')
discord_id = app.storage.user.get('discord_id')
# Fehlt die Discord-ID (altes Cookie) ODER sagt die Datenbank, dass da was nicht stimmt?
if not discord_id or not data_api.validate_user_session(db_id, discord_id):
# Ausweis ungültig! Wir vernichten das Cookie sofort.
app.storage.user.clear()
ui.notify("Deine Sitzung ist ungültig oder abgelaufen. Bitte neu einloggen!", color="negative")
ui.navigate.reload()
return
# -----------------------------------------
# ---------------------------
# --- NAVIGATIONSLEISTE (HEADER) ---
# ---------------------------
@ -20,7 +35,7 @@ def setup_routes(admin_discord_id):
ui.image("gui/pictures/wsdg.png").classes('w-20 h-20 rounded-full')
ui.label('Diceghost Liga').classes('text-2xl font-bold text-white')
# --- RECHTE SEITE ---
# --- MITTE ---
discord_id = app.storage.user.get("discord_id")
if discord_id == admin_discord_id:
ui.button('Admin Panel', on_click=lambda: ui.navigate.to('/admin'))
@ -28,7 +43,7 @@ def setup_routes(admin_discord_id):
# --- RECHTE SEITE ---
if app.storage.user.get('authenticated', False):
with ui.row().classes('items-center gap-4'):
ui.image(app.storage.user.get('discord_avatar_url')).classes('w-15 h-15 rounded-full')
discord_name = app.storage.user.get('discord_name')
display_name = app.storage.user.get('display_name')
player_id = app.storage.user.get('db_id')
@ -41,7 +56,7 @@ def setup_routes(admin_discord_id):
# --- ANSICHT 1: Der normale Text mit Edit-Button ---
with ui.row().classes('items-center gap-2') as display_row:
ui.label(display_name).classes('text-xl font-bold text-white')
ui.label('aka').classes('text-sm text-gray-500')
ui.label("'aka'").classes('text-sm text-gray-500')
ui.label(discord_name).classes('text-lg text-gray-400')
# Ein runder Button (.props('round'))
@ -185,7 +200,6 @@ def setup_routes(admin_discord_id):
with ui.element('div').classes("w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 items-center"):
# LOGIK UMGEKEHRT: Wir schleifen über den Katalog der verfügbaren Systeme!
for sys in systems:
sys_id = sys['id']
sys_name = sys['name']

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

View File

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

17
main.py
View File

@ -1,16 +1,19 @@
import os
from nicegui import app
from dotenv import load_dotenv
from nicegui import ui
from nicegui import ui, app
from gui import main_gui, match_gui, discord_login, league_statistic, admin_gui, match_history_gui
from data import database
from gui import main_gui, match_gui, discord_login, league_statistic, admin_gui, match_history_gui
# 1. Lade die geheimen Variablen aus der .env Datei in den Speicher
load_dotenv()
# Festschreiben des Bilder Ordnerns.
app.add_static_files('/pictures', 'gui/pictures')
# Festschreiben des Ordners für die Bilder (Darf hier bleiben!)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
PICTURE_DIR = os.path.join(BASE_DIR, "gui", "pictures")
# Fester Pfad für den Webserver
app.add_static_files('/pictures', PICTURE_DIR)
# 2. Variablen abrufen
client_id = os.getenv("DISCORD_CLIENT_ID")
@ -30,4 +33,4 @@ match_history_gui.setup_routes()
# 4. Wir starten die NiceGUI App
ui.run(title="Westside Diceghost Liga", port=9000, storage_secret="ein_sehr_geheimes_passwort_fuer_die_cookies", favicon="gui/pictures/wsdg.png")
ui.run(title="Westside Diceghost Liga", port=9000, storage_secret="EIN_super-geheimes_Pa$$wort#!", favicon="gui/pictures/wsdg.png")