fix: update ClawdbotConfig to MoltbotConfig for upstream compatibility

This commit is contained in:
ronitchidara 2026-01-28 17:05:10 +05:30
parent 0652049c3d
commit d5cd25f24d
4 changed files with 45 additions and 44 deletions

View File

@ -1,6 +1,6 @@
import { beforeEach, describe, expect, it, vi } from "vitest"; import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../config/config.js"; import type { MoltbotConfig } from "../config/config.js";
import { normalizeDiscordMessagingTarget } from "../channels/plugins/normalize/discord.js"; import { normalizeDiscordMessagingTarget } from "../channels/plugins/normalize/discord.js";
import { listDiscordDirectoryPeersLive } from "./directory-live.js"; import { listDiscordDirectoryPeersLive } from "./directory-live.js";
import { parseDiscordTarget, resolveDiscordChannelId, resolveDiscordTarget } from "./targets.js"; import { parseDiscordTarget, resolveDiscordChannelId, resolveDiscordTarget } from "./targets.js";
@ -75,7 +75,7 @@ describe("resolveDiscordChannelId", () => {
}); });
describe("resolveDiscordTarget", () => { describe("resolveDiscordTarget", () => {
const cfg = { channels: { discord: {} } } as ClawdbotConfig; const cfg = { channels: { discord: {} } } as MoltbotConfig;
const listPeers = vi.mocked(listDiscordDirectoryPeersLive); const listPeers = vi.mocked(listDiscordDirectoryPeersLive);
beforeEach(() => { beforeEach(() => {

View File

@ -732,7 +732,7 @@ describe("security audit", () => {
it("does not warn on Venice-style opus-45 model names", async () => { it("does not warn on Venice-style opus-45 model names", async () => {
// Venice uses "claude-opus-45" format (no dash between 4 and 5) // Venice uses "claude-opus-45" format (no dash between 4 and 5)
const cfg: ClawdbotConfig = { const cfg: MoltbotConfig = {
agents: { defaults: { model: { primary: "venice/claude-opus-45" } } }, agents: { defaults: { model: { primary: "venice/claude-opus-45" } } },
}; };

View File

@ -1,5 +1,5 @@
import { describe, expect, it, beforeEach, afterEach } from "vitest"; import { describe, expect, it, beforeEach, afterEach } from "vitest";
import type { ClawdbotConfig } from "../config/types.js"; import type { MoltbotConfig } from "../config/types.js";
import { import {
isRbacEnabled, isRbacEnabled,
getRoleForUser, getRoleForUser,
@ -42,12 +42,12 @@ describe("rbac", () => {
describe("getRoleForUser", () => { describe("getRoleForUser", () => {
it("returns null when RBAC is disabled", () => { it("returns null when RBAC is disabled", () => {
const config: ClawdbotConfig = { rbac: { enabled: false } }; const config: MoltbotConfig = { rbac: { enabled: false } };
expect(getRoleForUser("user-1", config)).toBeNull(); expect(getRoleForUser("user-1", config)).toBeNull();
}); });
it("returns assigned role when user is assigned", () => { it("returns assigned role when user is assigned", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "admin" }, assignments: { "user-1": "admin" },
@ -59,7 +59,7 @@ describe("rbac", () => {
}); });
it("returns default role when user is not assigned", () => { it("returns default role when user is not assigned", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
defaultRole: "viewer", defaultRole: "viewer",
@ -70,14 +70,14 @@ describe("rbac", () => {
}); });
it("returns null when no assignment and no default role", () => { it("returns null when no assignment and no default role", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { enabled: true }, rbac: { enabled: true },
}; };
expect(getRoleForUser("user-1", config)).toBeNull(); expect(getRoleForUser("user-1", config)).toBeNull();
}); });
it("uses custom role definitions", () => { it("uses custom role definitions", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
roles: { roles: {
@ -97,21 +97,21 @@ describe("rbac", () => {
describe("hasPermission", () => { describe("hasPermission", () => {
it("allows everything when RBAC is disabled", () => { it("allows everything when RBAC is disabled", () => {
const config: ClawdbotConfig = { rbac: { enabled: false } }; const config: MoltbotConfig = { rbac: { enabled: false } };
const result = hasPermission("user-1", "exec.elevated", config); const result = hasPermission("user-1", "exec.elevated", config);
expect(result.allowed).toBe(true); expect(result.allowed).toBe(true);
expect(result.reason).toBe("rbac-disabled"); expect(result.reason).toBe("rbac-disabled");
}); });
it("denies when user has no role", () => { it("denies when user has no role", () => {
const config: ClawdbotConfig = { rbac: { enabled: true } }; const config: MoltbotConfig = { rbac: { enabled: true } };
const result = hasPermission("user-1", "exec", config); const result = hasPermission("user-1", "exec", config);
expect(result.allowed).toBe(false); expect(result.allowed).toBe(false);
expect(result.reason).toBe("no-role-assigned"); expect(result.reason).toBe("no-role-assigned");
}); });
it("allows when user has the permission", () => { it("allows when user has the permission", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -123,7 +123,7 @@ describe("rbac", () => {
}); });
it("denies when user lacks the permission", () => { it("denies when user lacks the permission", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -135,7 +135,7 @@ describe("rbac", () => {
}); });
it("admin role grants all permissions", () => { it("admin role grants all permissions", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "admin" }, assignments: { "user-1": "admin" },
@ -150,7 +150,7 @@ describe("rbac", () => {
describe("canExecuteCommand", () => { describe("canExecuteCommand", () => {
it("allows basic commands with exec permission", () => { it("allows basic commands with exec permission", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -161,7 +161,7 @@ describe("rbac", () => {
}); });
it("denies elevated commands without exec.elevated permission", () => { it("denies elevated commands without exec.elevated permission", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -172,7 +172,7 @@ describe("rbac", () => {
}); });
it("allows elevated commands with exec.elevated permission", () => { it("allows elevated commands with exec.elevated permission", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "admin" }, assignments: { "user-1": "admin" },
@ -183,7 +183,7 @@ describe("rbac", () => {
}); });
it("detects sudo in various positions", () => { it("detects sudo in various positions", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -198,7 +198,7 @@ describe("rbac", () => {
describe("canAccessAgent", () => { describe("canAccessAgent", () => {
it("allows all agents when no restrictions", () => { it("allows all agents when no restrictions", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -210,7 +210,7 @@ describe("rbac", () => {
}); });
it("denies access to restricted agents", () => { it("denies access to restricted agents", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
roles: { roles: {
@ -228,7 +228,7 @@ describe("rbac", () => {
}); });
it("admin bypasses agent restrictions", () => { it("admin bypasses agent restrictions", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "admin" }, assignments: { "user-1": "admin" },
@ -242,7 +242,7 @@ describe("rbac", () => {
describe("canUseTool", () => { describe("canUseTool", () => {
it("allows all tools when no restrictions", () => { it("allows all tools when no restrictions", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -253,7 +253,7 @@ describe("rbac", () => {
}); });
it("denies tools on deny list", () => { it("denies tools on deny list", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
roles: { roles: {
@ -271,7 +271,7 @@ describe("rbac", () => {
}); });
it("only allows tools on allow list when specified", () => { it("only allows tools on allow list when specified", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
roles: { roles: {
@ -289,7 +289,7 @@ describe("rbac", () => {
}); });
it("deny takes precedence over allow", () => { it("deny takes precedence over allow", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
roles: { roles: {
@ -307,7 +307,7 @@ describe("rbac", () => {
}); });
it("read-only role cannot use tools", () => { it("read-only role cannot use tools", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "viewer" }, assignments: { "user-1": "viewer" },
@ -321,7 +321,7 @@ describe("rbac", () => {
describe("canApproveExec", () => { describe("canApproveExec", () => {
it("allows with exec.approve permission", () => { it("allows with exec.approve permission", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "operator" }, assignments: { "user-1": "operator" },
@ -332,7 +332,7 @@ describe("rbac", () => {
}); });
it("denies without exec.approve permission", () => { it("denies without exec.approve permission", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "user" }, assignments: { "user-1": "user" },
@ -345,14 +345,14 @@ describe("rbac", () => {
describe("getUserPermissionSummary", () => { describe("getUserPermissionSummary", () => {
it("returns disabled when RBAC is off", () => { it("returns disabled when RBAC is off", () => {
const config: ClawdbotConfig = { rbac: { enabled: false } }; const config: MoltbotConfig = { rbac: { enabled: false } };
const summary = getUserPermissionSummary("user-1", config); const summary = getUserPermissionSummary("user-1", config);
expect(summary.enabled).toBe(false); expect(summary.enabled).toBe(false);
expect(summary.roleId).toBeUndefined(); expect(summary.roleId).toBeUndefined();
}); });
it("returns role details when RBAC is on", () => { it("returns role details when RBAC is on", () => {
const config: ClawdbotConfig = { const config: MoltbotConfig = {
rbac: { rbac: {
enabled: true, enabled: true,
assignments: { "user-1": "admin" }, assignments: { "user-1": "admin" },
@ -366,7 +366,7 @@ describe("rbac", () => {
}); });
it("returns enabled with no role when user unassigned", () => { it("returns enabled with no role when user unassigned", () => {
const config: ClawdbotConfig = { rbac: { enabled: true } }; const config: MoltbotConfig = { rbac: { enabled: true } };
const summary = getUserPermissionSummary("user-1", config); const summary = getUserPermissionSummary("user-1", config);
expect(summary.enabled).toBe(true); expect(summary.enabled).toBe(true);
expect(summary.roleId).toBeUndefined(); expect(summary.roleId).toBeUndefined();

View File

@ -5,7 +5,7 @@
* When RBAC is disabled, all permissions are granted (backwards compatible). * When RBAC is disabled, all permissions are granted (backwards compatible).
*/ */
import type { ClawdbotConfig } from "../config/types.js"; import type { MoltbotConfig } from "../config/types.js";
import type { RbacConfig, RbacPermission, RbacRoleDefinition } from "../config/types.rbac.js"; import type { RbacConfig, RbacPermission, RbacRoleDefinition } from "../config/types.rbac.js";
import { auditRbacDenied } from "./audit-log.js"; import { auditRbacDenied } from "./audit-log.js";
@ -43,7 +43,7 @@ const DEFAULT_ROLES: Record<string, RbacRoleDefinition> = {
/** /**
* Check if RBAC is enabled in the config. * Check if RBAC is enabled in the config.
*/ */
export function isRbacEnabled(config?: ClawdbotConfig): boolean { export function isRbacEnabled(config?: MoltbotConfig): boolean {
return config?.rbac?.enabled === true; return config?.rbac?.enabled === true;
} }
@ -54,7 +54,7 @@ export function isRbacEnabled(config?: ClawdbotConfig): boolean {
* SECURITY: Call this during gateway startup to catch configuration * SECURITY: Call this during gateway startup to catch configuration
* errors early rather than failing silently at runtime. * errors early rather than failing silently at runtime.
*/ */
export function validateRbacConfig(config?: ClawdbotConfig): string[] | null { export function validateRbacConfig(config?: MoltbotConfig): string[] | null {
if (!isRbacEnabled(config)) { if (!isRbacEnabled(config)) {
return null; // RBAC disabled, no validation needed return null; // RBAC disabled, no validation needed
} }
@ -85,9 +85,10 @@ export function validateRbacConfig(config?: ClawdbotConfig): string[] | null {
if (rbacConfig?.assignments) { if (rbacConfig?.assignments) {
const roles = { ...DEFAULT_ROLES, ...rbacConfig.roles }; const roles = { ...DEFAULT_ROLES, ...rbacConfig.roles };
for (const [userId, roleId] of Object.entries(rbacConfig.assignments)) { for (const [userId, roleId] of Object.entries(rbacConfig.assignments)) {
if (roleId && !roles[roleId]) { const roleIdStr = String(roleId);
if (roleId && !roles[roleIdStr]) {
errors.push( errors.push(
`RBAC assignment for user '${userId}' references unknown role '${roleId}'. ` + `RBAC assignment for user '${userId}' references unknown role '${roleIdStr}'. ` +
`Available roles: ${Object.keys(roles).join(", ")}`, `Available roles: ${Object.keys(roles).join(", ")}`,
); );
} }
@ -100,7 +101,7 @@ export function validateRbacConfig(config?: ClawdbotConfig): string[] | null {
/** /**
* Get the RBAC config with defaults applied. * Get the RBAC config with defaults applied.
*/ */
function getRbacConfig(config?: ClawdbotConfig): RbacConfig { function getRbacConfig(config?: MoltbotConfig): RbacConfig {
return { return {
enabled: false, enabled: false,
roles: DEFAULT_ROLES, roles: DEFAULT_ROLES,
@ -125,7 +126,7 @@ function getRoles(rbacConfig: RbacConfig): Record<string, RbacRoleDefinition> {
*/ */
export function getRoleForUser( export function getRoleForUser(
senderId: string, senderId: string,
config?: ClawdbotConfig, config?: MoltbotConfig,
): { roleId: string; role: RbacRoleDefinition } | null { ): { roleId: string; role: RbacRoleDefinition } | null {
const rbacConfig = getRbacConfig(config); const rbacConfig = getRbacConfig(config);
const roles = getRoles(rbacConfig); const roles = getRoles(rbacConfig);
@ -151,7 +152,7 @@ export function getRoleForUser(
export function hasPermission( export function hasPermission(
senderId: string, senderId: string,
permission: RbacPermission, permission: RbacPermission,
config?: ClawdbotConfig, config?: MoltbotConfig,
): RbacCheckResult { ): RbacCheckResult {
// If RBAC is disabled, allow everything // If RBAC is disabled, allow everything
if (!isRbacEnabled(config)) { if (!isRbacEnabled(config)) {
@ -190,7 +191,7 @@ export function hasPermission(
export function canExecuteCommand( export function canExecuteCommand(
senderId: string, senderId: string,
command: string, command: string,
config?: ClawdbotConfig, config?: MoltbotConfig,
): RbacCheckResult { ): RbacCheckResult {
// If RBAC is disabled, allow everything // If RBAC is disabled, allow everything
if (!isRbacEnabled(config)) { if (!isRbacEnabled(config)) {
@ -244,7 +245,7 @@ function isElevatedCommand(command: string): boolean {
export function canAccessAgent( export function canAccessAgent(
senderId: string, senderId: string,
agentId: string, agentId: string,
config?: ClawdbotConfig, config?: MoltbotConfig,
): RbacCheckResult { ): RbacCheckResult {
// If RBAC is disabled, allow everything // If RBAC is disabled, allow everything
if (!isRbacEnabled(config)) { if (!isRbacEnabled(config)) {
@ -298,7 +299,7 @@ export function canAccessAgent(
export function canUseTool( export function canUseTool(
senderId: string, senderId: string,
toolName: string, toolName: string,
config?: ClawdbotConfig, config?: MoltbotConfig,
): RbacCheckResult { ): RbacCheckResult {
// If RBAC is disabled, allow everything // If RBAC is disabled, allow everything
if (!isRbacEnabled(config)) { if (!isRbacEnabled(config)) {
@ -364,7 +365,7 @@ export function canUseTool(
/** /**
* Check if a user can approve exec requests. * Check if a user can approve exec requests.
*/ */
export function canApproveExec(senderId: string, config?: ClawdbotConfig): RbacCheckResult { export function canApproveExec(senderId: string, config?: MoltbotConfig): RbacCheckResult {
return hasPermission(senderId, "exec.approve", config); return hasPermission(senderId, "exec.approve", config);
} }
@ -373,7 +374,7 @@ export function canApproveExec(senderId: string, config?: ClawdbotConfig): RbacC
*/ */
export function getUserPermissionSummary( export function getUserPermissionSummary(
senderId: string, senderId: string,
config?: ClawdbotConfig, config?: MoltbotConfig,
): { ): {
enabled: boolean; enabled: boolean;
roleId?: string; roleId?: string;