Upload folder via GUI - src
This commit is contained in:
@@ -60,12 +60,36 @@ public class ApiHandler extends BaseHandler implements HttpHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Archiv-Aktionen ──────────────────────────────────────────
|
||||
if (path.startsWith("/api/archive/")) {
|
||||
handleArchiveApi(ex, session, path, method);
|
||||
return;
|
||||
}
|
||||
|
||||
// ── FAQ-Aktionen ─────────────────────────────────────────────
|
||||
if (path.startsWith("/api/faq")) {
|
||||
handleFaqApi(ex, session, path, method);
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Benutzer-Verwaltung ──────────────────────────────────────
|
||||
if (path.startsWith("/api/users")) {
|
||||
handleUsersApi(ex, session, path, method);
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Backup ───────────────────────────────────────────────────
|
||||
if (path.equals("/api/backup") && method.equals("POST")) {
|
||||
if (!session.isAdmin()) { sendJson(ex, 403, err("Kein Zugriff")); return; }
|
||||
java.io.File backup = plugin.getDatabaseManager().createBackup();
|
||||
if (backup != null) {
|
||||
sendJson(ex, 200, "{\"ok\":true,\"file\":\"" + jsonEsc(backup.getName()) + "\"}");
|
||||
} else {
|
||||
sendJson(ex, 500, err("Backup fehlgeschlagen"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
sendJson(ex, 404, "{\"ok\":false,\"error\":\"Unbekannter Endpunkt\"}");
|
||||
|
||||
} catch (Exception e) {
|
||||
@@ -287,6 +311,156 @@ public class ApiHandler extends BaseHandler implements HttpHandler {
|
||||
sendJson(ex, 404, err("Unbekannter FAQ-Endpunkt"));
|
||||
}
|
||||
|
||||
// ─────────────────────────── Archiv-API ────────────────────────────────
|
||||
|
||||
/**
|
||||
* POST /api/archive/{id}/delete – Ticket permanent löschen (admin only)
|
||||
* POST /api/archive/{id}/restore – Ticket wiederherstellen (admin only)
|
||||
*/
|
||||
private void handleArchiveApi(HttpExchange ex, WebSession session, String path, String method) throws IOException {
|
||||
if (!session.canViewArchive()) { sendJson(ex, 403, err("Kein Zugriff")); return; }
|
||||
if (!method.equals("POST")) { sendJson(ex, 405, err("Method not allowed")); return; }
|
||||
|
||||
// /api/archive/{id}/{action}
|
||||
String[] parts = path.split("/");
|
||||
if (parts.length < 5) { sendJson(ex, 400, err("Ungültiger Pfad")); return; }
|
||||
|
||||
int ticketId;
|
||||
try { ticketId = Integer.parseInt(parts[3]); }
|
||||
catch (NumberFormatException e) { sendJson(ex, 400, err("Ungültige ID")); return; }
|
||||
|
||||
String action = parts[4];
|
||||
var db = plugin.getDatabaseManager();
|
||||
|
||||
switch (action) {
|
||||
case "delete" -> {
|
||||
if (!session.isAdmin()) { sendJson(ex, 403, err("Nur Admins dürfen löschen")); return; }
|
||||
boolean ok = db.deleteArchivedTicket(ticketId);
|
||||
sendJson(ex, ok ? 200 : 404, ok ? "{\"ok\":true}" : err("Ticket nicht gefunden"));
|
||||
}
|
||||
case "restore" -> {
|
||||
if (!session.isAdmin()) { sendJson(ex, 403, err("Nur Admins dürfen wiederherstellen")); return; }
|
||||
boolean ok = db.restoreArchivedTicket(ticketId);
|
||||
sendJson(ex, ok ? 200 : 500, ok ? "{\"ok\":true}" : err("Wiederherstellen fehlgeschlagen"));
|
||||
}
|
||||
default -> sendJson(ex, 404, err("Unbekannte Archiv-Aktion: " + action));
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────── Benutzer-API ──────────────────────────────
|
||||
|
||||
/**
|
||||
* GET /api/users – Alle Benutzer auflisten (admin only)
|
||||
* POST /api/users – Neuen Benutzer anlegen (admin only)
|
||||
* body: {username, password, role}
|
||||
* POST /api/users/{name}/password – Passwort ändern (admin only)
|
||||
* body: {password}
|
||||
* DELETE /api/users/{name} – Benutzer löschen (admin only)
|
||||
*/
|
||||
private void handleUsersApi(HttpExchange ex, WebSession session, String path, String method) throws IOException {
|
||||
if (!session.isAdmin()) { sendJson(ex, 403, err("Kein Zugriff")); return; }
|
||||
|
||||
// GET /api/users – Liste
|
||||
if (path.equals("/api/users") && method.equals("GET")) {
|
||||
org.bukkit.configuration.ConfigurationSection users =
|
||||
plugin.getConfig().getConfigurationSection("web-panel.users");
|
||||
StringBuilder json = new StringBuilder("[");
|
||||
if (users != null) {
|
||||
boolean first = true;
|
||||
for (String key : users.getKeys(false)) {
|
||||
if (!first) json.append(",");
|
||||
first = false;
|
||||
String role = plugin.getConfig().getString("web-panel.users." + key + ".role", "supporter");
|
||||
json.append("{\"username\":\"").append(jsonEsc(key))
|
||||
.append("\",\"role\":\"").append(jsonEsc(role)).append("\"}");
|
||||
}
|
||||
}
|
||||
json.append("]");
|
||||
sendJson(ex, 200, json.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
// POST /api/users – Anlegen
|
||||
if (path.equals("/api/users") && method.equals("POST")) {
|
||||
Map<String, String> body = parseJsonBody(ex);
|
||||
String username = body.getOrDefault("username", "").trim();
|
||||
String password = body.getOrDefault("password", "").trim();
|
||||
String role = body.getOrDefault("role", "supporter").trim().toLowerCase();
|
||||
|
||||
if (username.isEmpty() || password.isEmpty()) {
|
||||
sendJson(ex, 400, err("Benutzername und Passwort erforderlich")); return;
|
||||
}
|
||||
if (!role.equals("admin") && !role.equals("supporter") && !role.equals("archive_viewer")) {
|
||||
sendJson(ex, 400, err("Ungültige Rolle (admin/supporter/archive_viewer)")); return;
|
||||
}
|
||||
// Prüfen ob Benutzer schon existiert
|
||||
org.bukkit.configuration.ConfigurationSection existing =
|
||||
plugin.getConfig().getConfigurationSection("web-panel.users");
|
||||
if (existing != null) {
|
||||
for (String k : existing.getKeys(false)) {
|
||||
if (k.equalsIgnoreCase(username)) {
|
||||
sendJson(ex, 409, err("Benutzer existiert bereits")); return;
|
||||
}
|
||||
}
|
||||
}
|
||||
String hash = de.ticketsystem.web.SessionManager.sha256(password);
|
||||
plugin.getConfig().set("web-panel.users." + username + ".password-hash", hash);
|
||||
plugin.getConfig().set("web-panel.users." + username + ".role", role);
|
||||
plugin.saveConfig();
|
||||
sendJson(ex, 200, "{\"ok\":true}");
|
||||
return;
|
||||
}
|
||||
|
||||
// POST /api/users/{name}/password – Passwort ändern
|
||||
if (path.matches("/api/users/[^/]+/password") && method.equals("POST")) {
|
||||
String targetUser = path.split("/")[3];
|
||||
Map<String, String> body = parseJsonBody(ex);
|
||||
String newPass = body.getOrDefault("password", "").trim();
|
||||
if (newPass.isEmpty()) { sendJson(ex, 400, err("Passwort darf nicht leer sein")); return; }
|
||||
|
||||
String cfgPath = findUserConfigPath(targetUser);
|
||||
if (cfgPath == null) { sendJson(ex, 404, err("Benutzer nicht gefunden")); return; }
|
||||
|
||||
String hash = de.ticketsystem.web.SessionManager.sha256(newPass);
|
||||
plugin.getConfig().set(cfgPath + ".password-hash", hash);
|
||||
plugin.getConfig().set(cfgPath + ".password", null);
|
||||
plugin.saveConfig();
|
||||
// Alle Sessions dieses Benutzers invalidieren
|
||||
sessionManager.invalidateUser(targetUser);
|
||||
sendJson(ex, 200, "{\"ok\":true}");
|
||||
return;
|
||||
}
|
||||
|
||||
// DELETE /api/users/{name} – Löschen
|
||||
if (path.matches("/api/users/[^/]+") && method.equals("DELETE")) {
|
||||
String targetUser = path.split("/")[3];
|
||||
// Darf sich nicht selbst löschen
|
||||
if (targetUser.equalsIgnoreCase(session.getUsername())) {
|
||||
sendJson(ex, 400, err("Du kannst dich nicht selbst löschen")); return;
|
||||
}
|
||||
String cfgPath = findUserConfigPath(targetUser);
|
||||
if (cfgPath == null) { sendJson(ex, 404, err("Benutzer nicht gefunden")); return; }
|
||||
plugin.getConfig().set(cfgPath, null);
|
||||
plugin.saveConfig();
|
||||
sessionManager.invalidateUser(targetUser);
|
||||
sendJson(ex, 200, "{\"ok\":true}");
|
||||
return;
|
||||
}
|
||||
|
||||
sendJson(ex, 404, err("Unbekannter Benutzer-Endpunkt"));
|
||||
}
|
||||
|
||||
/** Sucht den config.yml-Pfad eines Benutzers (case-insensitiv). */
|
||||
private String findUserConfigPath(String username) {
|
||||
org.bukkit.configuration.ConfigurationSection users =
|
||||
plugin.getConfig().getConfigurationSection("web-panel.users");
|
||||
if (users == null) return null;
|
||||
for (String key : users.getKeys(false)) {
|
||||
if (key.equalsIgnoreCase(username)) return "web-panel.users." + key;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ─────────────────────────── Hilfsmethoden ─────────────────────────────
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user