import os import urllib.parse import requests from nicegui import ui, app from data import data_api def get_auth_url(): client_id = os.getenv("DISCORD_CLIENT_ID") app_url = os.getenv("APP_URL") redirect_uri = f"{app_url}/login/discord" encoded_redirect_uri = urllib.parse.quote(redirect_uri, safe="") # NEU: guilds.members.read erlaubt uns, die Rollen des Users in einem bestimmten Server abzufragen return f"https://discord.com/api/oauth2/authorize?client_id={client_id}&redirect_uri={encoded_redirect_uri}&response_type=code&scope=identify%20guilds.members.read" def setup_login_routes(): client_id = os.getenv("DISCORD_CLIENT_ID") client_secret = os.getenv("DISCORD_CLIENT_SECRET") app_url = os.getenv("APP_URL") redirect_uri = f"{app_url}/login/discord" @ui.page('/login/discord', dark=True) def discord_callback(code: str = None): if not code: ui.label('Fehler: Kein Code erhalten.').classes('text-red-500') return token_data = { 'client_id': client_id, 'client_secret': client_secret, 'grant_type': 'authorization_code', 'code': code, 'redirect_uri': redirect_uri } token_response = requests.post('https://discord.com/api/oauth2/token', data=token_data) token_json = token_response.json() if 'access_token' in token_json: access_token = token_json['access_token'] user_headers = {'Authorization': f"Bearer {access_token}"} # 1. Die IDs aus der .env laden (Passe die Namen an, falls sie bei dir anders heißen!) guild_id = os.getenv("DISCORD_SERVER_ID") role_diceghosts = os.getenv("DISCORD_SERVER_DICEGHOST_ID") role_friend = os.getenv("DISCORD_SERVER_FRIEND_ID") # 2. Prüfen: Ist der Nutzer überhaupt auf unserem Server? # Wir fragen Discord gezielt nach dem Profil des Nutzers auf DEINEM Server. member_response = requests.get(f'https://discord.com/api/users/@me/guilds/{guild_id}/member', headers=user_headers) # Ein HTTP Status-Code 200 bedeutet "OK". Alles andere (z.B. 404 Not Found) bedeutet: Er ist nicht auf dem Server! if member_response.status_code != 200: ui.label('Zugriff verweigert: Du bist nicht auf dem Diceghosts Server!').classes('text-red-500 text-xl font-bold p-4') return # Bricht die Funktion hier ab. Kein Login! # 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 [] user_roles = member_json.get('roles', []) # Wir prüfen, ob mindestens eine der beiden Rollen-IDs in seiner Liste auftaucht if role_diceghosts not in user_roles and role_friend not in user_roles: ui.label('Zugriff verweigert: Du hast nicht die benötigte Rolle (Diceghosts oder Friend)!').classes('text-red-500 text-xl font-bold p-4') return # Bricht die Funktion hier ab. Kein Login! # --- AB HIER: ZUGANG GEWÄHRT! --- # Jetzt laden wir noch seine allgemeinen Discord-Daten (für Name und Profilbild) user_response = requests.get('https://discord.com/api/users/@me', headers=user_headers) user_json = user_response.json() discord_id = user_json['id'] discord_name = user_json['username'] # --- BILD ABFANGEN --- avatar_hash = user_json.get('avatar') if avatar_hash: avatar_url = f"https://cdn.discordapp.com/avatars/{discord_id}/{avatar_hash}.png" else: avatar_url = "https://cdn.discordapp.com/embed/avatars/0.png" # In die Datenbank eintragen player = data_api.get_or_create_player(discord_id, discord_name, avatar_url) # Session updaten app.storage.user['authenticated'] = True app.storage.user['discord_id'] = discord_id app.storage.user['discord_name'] = discord_name app.storage.user['db_id'] = player[0] app.storage.user['display_name'] = player[2] app.storage.user['discord_avatar_url'] = player[3] ui.navigate.to('/') else: ui.label('Fehler beim Login!').classes('text-red-500')