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:
1 parent
500c00f948
commit
f03fbd298e
13 files changed
+100
-16
No files matched your search
@@ -19,8 +19,8 @@ public partial class DatabaseService
|
||||
agent.CreatedAt = now;
|
||||
agent.UpdatedAt = now;
|
||||
await conn.ExecuteAsync(@"
|
||||
INSERT INTO agents (agent_id, user_id, name, avatar, avatar_small, description, model, tool_choice, custom_commands, auto_commit, use_soul, use_identity, use_user_info, use_memory, use_auto_context, use_github_search, use_serper_search, use_web_search, web_search_version, allow_user_choice, task_instruction, avatar_scale, avatar_offset_x, avatar_offset_y, is_deleted, created_at, updated_at)
|
||||
VALUES (@AgentId, @UserId, @Name, @Avatar, @AvatarSmall, @Description, @Model, @ToolChoice, @CustomCommands, @AutoCommit, @UseSoul, @UseIdentity, @UseUserInfo, @UseMemory, @UseAutoContext, @UseGitHubSearch, @UseSerperSearch, @UseWebSearch, @WebSearchVersion, @AllowUserChoice, @TaskInstruction, @AvatarScale, @AvatarOffsetX, @AvatarOffsetY, 0, @CreatedAt, @UpdatedAt)
|
||||
INSERT INTO agents (agent_id, user_id, name, avatar, avatar_small, description, model, tool_choice, custom_commands, auto_commit, use_soul, use_identity, use_user_info, use_memory, use_auto_context, use_github_search, use_serper_search, use_web_search, web_search_version, allow_user_choice, task_instruction, avatar_scale, avatar_offset_x, avatar_offset_y, is_public, is_deleted, created_at, updated_at)
|
||||
VALUES (@AgentId, @UserId, @Name, @Avatar, @AvatarSmall, @Description, @Model, @ToolChoice, @CustomCommands, @AutoCommit, @UseSoul, @UseIdentity, @UseUserInfo, @UseMemory, @UseAutoContext, @UseGitHubSearch, @UseSerperSearch, @UseWebSearch, @WebSearchVersion, @AllowUserChoice, @TaskInstruction, @AvatarScale, @AvatarOffsetX, @AvatarOffsetY, @IsPublic, 0, @CreatedAt, @UpdatedAt)
|
||||
", agent);
|
||||
return agent;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -367,6 +367,10 @@ public partial class DatabaseService
|
||||
// users: ausgewählter API-Key (legacy, wird durch agent_api_keys ersetzt)
|
||||
TryAddColumn(conn, "users", "selected_api_key_id", "TEXT");
|
||||
|
||||
// users: Berechtigungen (Default: true für Abwärtskompatibilität)
|
||||
TryAddColumn(conn, "users", "can_create_agents", "INTEGER NOT NULL DEFAULT 1");
|
||||
TryAddColumn(conn, "users", "can_use_cli", "INTEGER NOT NULL DEFAULT 1");
|
||||
|
||||
conn.Execute(@"
|
||||
CREATE TABLE IF NOT EXISTS agent_api_keys (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
Reference in new issue
Block a user