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

+7 -7
View File
@@ -159,24 +159,24 @@ public partial class DatabaseService
new { userId, settings, now = DateTime.UtcNow.ToString("o") });
}
public async Task<UserRecord> CreateUser(string username, string passwordHash, string displayName, bool isAdmin, string defaultPath = null)
public async Task<UserRecord> CreateUser(string username, string passwordHash, string displayName, bool isAdmin, string defaultPath = null, bool canCreateAgents = true, bool canUseCli = true)
{
using var conn = CreateConnection();
var now = DateTime.UtcNow.ToString("o");
var userId = Guid.NewGuid().ToString("N");
await conn.ExecuteAsync(@"
INSERT INTO users (user_id, username, password_hash, display_name, is_admin, default_path, created_at, updated_at)
VALUES (@userId, @username, @passwordHash, @displayName, @isAdmin, @defaultPath, @now, @now)",
new { userId, username, passwordHash, displayName, isAdmin, defaultPath, now });
INSERT INTO users (user_id, username, password_hash, display_name, is_admin, default_path, can_create_agents, can_use_cli, created_at, updated_at)
VALUES (@userId, @username, @passwordHash, @displayName, @isAdmin, @defaultPath, @canCreateAgents, @canUseCli, @now, @now)",
new { userId, username, passwordHash, displayName, isAdmin, defaultPath, canCreateAgents, canUseCli, now });
return await GetUser(userId);
}
public async Task UpdateUserAdmin(string userId, string username, string displayName, bool isAdmin, string defaultPath)
public async Task UpdateUserAdmin(string userId, string username, string displayName, bool isAdmin, string defaultPath, bool canCreateAgents, bool canUseCli)
{
using var conn = CreateConnection();
await conn.ExecuteAsync(
"UPDATE users SET username = @username, display_name = @displayName, is_admin = @isAdmin, default_path = @defaultPath, updated_at = @now WHERE user_id = @userId",
new { userId, username, displayName, isAdmin, defaultPath, now = DateTime.UtcNow.ToString("o") });
"UPDATE users SET username = @username, display_name = @displayName, is_admin = @isAdmin, default_path = @defaultPath, can_create_agents = @canCreateAgents, can_use_cli = @canUseCli, updated_at = @now WHERE user_id = @userId",
new { userId, username, displayName, isAdmin, defaultPath, canCreateAgents, canUseCli, now = DateTime.UtcNow.ToString("o") });
}
public async Task DeleteUser(string userId)