feat: User-Berechtigungen für Agent-Erstellung und CLI-Nutzung

- Neue Felder CanCreateAgents und CanUseCli im UserRecord (Default: true)
- DB-Migration mit Abwärtskompatibilität (bestehende User behalten alle Rechte)
- Admin-UI: Checkboxen für beide Berechtigungen pro User
- AgentEndpoint: Prüfung auf CanCreateAgents beim Erstellen
- ChatEndpoint: CLI-Fallback nur wenn CanUseCli erlaubt
- Frontend: Neuer-Agent-Button und Agent-Page bei fehlender Berechtigung gesperrt
- Chat: Proaktive Warnung wenn kein API-Key und keine CLI-Berechtigung
- Bug Fix: is_public fehlte im Agent-INSERT (Public Agents erst nach erneutem Speichern sichtbar)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
MelekiandClaude Opus 4.6 committed 2026-03-22 18:47:56 +01:00
1 parent 500c00f948
commit f03fbd298e
13 files changed
+100 -16

No files matched your search

+12 -2
View File
@@ -38,6 +38,8 @@ public static class AdminEndpoint
displayName = u.DisplayName,
isAdmin = u.IsAdmin,
defaultPath = u.DefaultPath,
canCreateAgents = u.CanCreateAgents,
canUseCli = u.CanUseCli,
createdAt = u.CreatedAt,
updatedAt = u.UpdatedAt
});
@@ -60,6 +62,8 @@ public static class AdminEndpoint
var displayName = body.TryGetProperty("displayName", out var dn) ? dn.GetString() : null;
var isAdmin = body.TryGetProperty("isAdmin", out var ia) && ia.GetBoolean();
var defaultPath = body.TryGetProperty("defaultPath", out var dp) ? dp.GetString() : null;
var canCreateAgents = !body.TryGetProperty("canCreateAgents", out var cca) || cca.GetBoolean();
var canUseCli = !body.TryGetProperty("canUseCli", out var cuc) || cuc.GetBoolean();
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
{
@@ -84,7 +88,7 @@ public static class AdminEndpoint
}
var hash = auth.HashPassword(password);
var user = await db.CreateUser(username, hash, displayName, isAdmin, defaultPath);
var user = await db.CreateUser(username, hash, displayName, isAdmin, defaultPath, canCreateAgents, canUseCli);
ctx.Response.StatusCode = 201;
await ctx.Response.WriteAsJsonAsync(new
@@ -94,6 +98,8 @@ public static class AdminEndpoint
displayName = user.DisplayName,
isAdmin = user.IsAdmin,
defaultPath = user.DefaultPath,
canCreateAgents = user.CanCreateAgents,
canUseCli = user.CanUseCli,
createdAt = user.CreatedAt
});
}
@@ -120,6 +126,8 @@ public static class AdminEndpoint
var displayName = body.TryGetProperty("displayName", out var dn) ? dn.GetString() : user.DisplayName;
var isAdmin = body.TryGetProperty("isAdmin", out var ia) ? ia.GetBoolean() : user.IsAdmin;
var defaultPath = body.TryGetProperty("defaultPath", out var dp) ? dp.GetString() : user.DefaultPath;
var canCreateAgents = body.TryGetProperty("canCreateAgents", out var cca) ? cca.GetBoolean() : user.CanCreateAgents;
var canUseCli = body.TryGetProperty("canUseCli", out var cuc) ? cuc.GetBoolean() : user.CanUseCli;
if (string.IsNullOrWhiteSpace(username))
{
@@ -137,7 +145,7 @@ public static class AdminEndpoint
return;
}
await db.UpdateUserAdmin(userId, username, displayName, isAdmin, defaultPath);
await db.UpdateUserAdmin(userId, username, displayName, isAdmin, defaultPath, canCreateAgents, canUseCli);
var updated = await db.GetUser(userId);
await ctx.Response.WriteAsJsonAsync(new
@@ -147,6 +155,8 @@ public static class AdminEndpoint
displayName = updated.DisplayName,
isAdmin = updated.IsAdmin,
defaultPath = updated.DefaultPath,
canCreateAgents = updated.CanCreateAgents,
canUseCli = updated.CanUseCli,
createdAt = updated.CreatedAt,
updatedAt = updated.UpdatedAt
});