-- ===================================================================== -- aether-admin — Kern -- -- Ein einziger Weg führt von der Oberfläche zu einer Aktion: `aufruf`. -- Der Kern nimmt ihn entgegen, prüft das Recht anhand der Rechte-Matrix -- und ruft die registrierte Funktion. Jedes Fachmodul meldet nur seine -- Aktionen an — die Prüfung passiert hier, an einer Stelle, für alle. -- ===================================================================== Admin = Admin or {} Admin.Kern = {} -- Registrierte Aktionen: ['modul.aktion'] = funktion local aktionen = {} --- Registriert eine Aktion. --- @param modul string Modulkennung (z. B. 'spieler') --- @param aktion string Aktionsname (z. B. 'kick') --- @param funktion function fun(handelnder, daten): ergebnis, fehler function Admin.Kern.Registriere(modul, aktion, funktion) aktionen[modul .. '.' .. aktion] = funktion end --- Führt eine Aktion aus — inklusive Rechteprüfung. --- @param quelle number Server-ID des Admins --- @param modul string --- @param aktion string --- @param daten table Nutzdaten --- @return any Ergebnis, string|nil Fehler function Admin.Kern.FuehreAus(quelle, modul, aktion, daten) local schluessel = tostring(modul) .. '.' .. tostring(aktion) local funktion = aktionen[schluessel] if not funktion then return nil, 'Unbekannte Aktion.' end -- Panel-Grundrecht if not Admin.Auth.DarfOeffnen(quelle) then return nil, 'Kein Zugriff auf das Admin-Panel.' end -- Recht auf genau diese Aktion local benoetigt = AdminConfig.RechtFuer(schluessel) if not Admin.Auth.Hat(quelle, benoetigt) then return nil, ('Dafür fehlt dir die Berechtigung (%s).'):format(benoetigt) end local handelnder = Admin.Auth.Handelnder(quelle) local erfolg, ergebnis, fehler = pcall(funktion, handelnder, daten or {}) if not erfolg then print(('[aether-admin] Fehler in %s: %s'):format(schluessel, tostring(ergebnis))) return nil, 'Interner Fehler in der Aktion.' end return ergebnis, fehler end --- Liefert die für einen Admin sichtbaren Sektionen (nach Gruppe gefiltert) --- @param quelle number --- @return table Liste { id, label, icon, grp } function Admin.Kern.SichtbareSektionen(quelle) local gruppe = Admin.Auth.Gruppe(quelle) local liste = {} for _, eintrag in ipairs(AdminConfig.Sektionen) do if eintrag.grp then liste[#liste + 1] = { grp = eintrag.grp } elseif AdminConfig.Erfuellt(gruppe, eintrag.min) then liste[#liste + 1] = { id = eintrag.id, label = eintrag.label, icon = eintrag.icon, } end end return liste end --- Baut das Rechte-Abbild für die Oberfläche: welche Aktionen darf dieser --- Admin? Die UI blendet danach Knöpfe aus — die echte Prüfung bleibt aber --- serverseitig. Das hier ist nur Kosmetik, kein Torwächter. --- @param quelle number --- @return table { ['modul.aktion'] = true, ... } function Admin.Kern.RechteAbbild(quelle) local gruppe = Admin.Auth.Gruppe(quelle) local abbild = {} for schluessel, benoetigt in pairs(AdminConfig.Rechte) do abbild[schluessel] = AdminConfig.Erfuellt(gruppe, benoetigt) end return abbild end