mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 19:10:58 +00:00
refactor: share plugin config trust helpers
This commit is contained in:
@@ -1,8 +1,11 @@
|
|||||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||||
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
|
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
|
||||||
import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
|
import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
|
||||||
|
import {
|
||||||
|
isWorkspacePluginAllowedByConfig,
|
||||||
|
normalizePluginConfigId,
|
||||||
|
} from "../plugins/plugin-config-trust.js";
|
||||||
import type { PluginOrigin } from "../plugins/plugin-origin.types.js";
|
import type { PluginOrigin } from "../plugins/plugin-origin.types.js";
|
||||||
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
|
||||||
import { normalizeProviderId } from "./provider-id.js";
|
import { normalizeProviderId } from "./provider-id.js";
|
||||||
|
|
||||||
export type ProviderAuthAliasLookupParams = {
|
export type ProviderAuthAliasLookupParams = {
|
||||||
@@ -17,8 +20,6 @@ type ProviderAuthAliasCandidate = {
|
|||||||
target: string;
|
target: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PluginEntriesConfig = NonNullable<NonNullable<OpenClawConfig["plugins"]>["entries"]>;
|
|
||||||
|
|
||||||
const PROVIDER_AUTH_ALIAS_ORIGIN_PRIORITY: Readonly<Record<PluginOrigin, number>> = {
|
const PROVIDER_AUTH_ALIAS_ORIGIN_PRIORITY: Readonly<Record<PluginOrigin, number>> = {
|
||||||
config: 0,
|
config: 0,
|
||||||
bundled: 1,
|
bundled: 1,
|
||||||
@@ -33,54 +34,16 @@ function resolveProviderAuthAliasOriginPriority(origin: PluginOrigin | undefined
|
|||||||
return PROVIDER_AUTH_ALIAS_ORIGIN_PRIORITY[origin] ?? Number.MAX_SAFE_INTEGER;
|
return PROVIDER_AUTH_ALIAS_ORIGIN_PRIORITY[origin] ?? Number.MAX_SAFE_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizePluginConfigId(id: unknown): string {
|
|
||||||
return normalizeOptionalLowercaseString(id) ?? "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasPluginId(list: unknown, pluginId: string): boolean {
|
|
||||||
return Array.isArray(list) && list.some((entry) => normalizePluginConfigId(entry) === pluginId);
|
|
||||||
}
|
|
||||||
|
|
||||||
function findPluginEntry(
|
|
||||||
entries: PluginEntriesConfig | undefined,
|
|
||||||
pluginId: string,
|
|
||||||
): { enabled?: boolean } | undefined {
|
|
||||||
if (!entries || typeof entries !== "object" || Array.isArray(entries)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
for (const [key, value] of Object.entries(entries)) {
|
|
||||||
if (normalizePluginConfigId(key) !== pluginId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return value && typeof value === "object" && !Array.isArray(value)
|
|
||||||
? (value as { enabled?: boolean })
|
|
||||||
: {};
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isWorkspacePluginTrustedForAuthAliases(
|
function isWorkspacePluginTrustedForAuthAliases(
|
||||||
plugin: PluginManifestRecord,
|
plugin: PluginManifestRecord,
|
||||||
config: OpenClawConfig | undefined,
|
config: OpenClawConfig | undefined,
|
||||||
): boolean {
|
): boolean {
|
||||||
const pluginsConfig = config?.plugins;
|
return isWorkspacePluginAllowedByConfig({
|
||||||
if (pluginsConfig?.enabled === false) {
|
config,
|
||||||
return false;
|
isImplicitlyAllowed: (pluginId) =>
|
||||||
}
|
normalizePluginConfigId(config?.plugins?.slots?.contextEngine) === pluginId,
|
||||||
|
plugin,
|
||||||
const pluginId = normalizePluginConfigId(plugin.id);
|
});
|
||||||
if (!pluginId || hasPluginId(pluginsConfig?.deny, pluginId)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entry = findPluginEntry(pluginsConfig?.entries, pluginId);
|
|
||||||
if (entry?.enabled === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (entry?.enabled === true || hasPluginId(pluginsConfig?.allow, pluginId)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return normalizePluginConfigId(pluginsConfig?.slots?.contextEngine) === pluginId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldUsePluginAuthAliases(
|
function shouldUsePluginAuthAliases(
|
||||||
|
|||||||
56
src/plugins/plugin-config-trust.ts
Normal file
56
src/plugins/plugin-config-trust.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||||
|
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
||||||
|
import type { PluginManifestRecord } from "./manifest-registry.js";
|
||||||
|
|
||||||
|
type PluginEntriesConfig = NonNullable<NonNullable<OpenClawConfig["plugins"]>["entries"]>;
|
||||||
|
|
||||||
|
export function normalizePluginConfigId(id: unknown): string {
|
||||||
|
return normalizeOptionalLowercaseString(id) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasPluginConfigId(list: unknown, pluginId: string): boolean {
|
||||||
|
return Array.isArray(list) && list.some((entry) => normalizePluginConfigId(entry) === pluginId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findPluginConfigEntry(
|
||||||
|
entries: PluginEntriesConfig | undefined,
|
||||||
|
pluginId: string,
|
||||||
|
): { enabled?: boolean } | undefined {
|
||||||
|
if (!entries || typeof entries !== "object" || Array.isArray(entries)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
for (const [key, value] of Object.entries(entries)) {
|
||||||
|
if (normalizePluginConfigId(key) !== pluginId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return value && typeof value === "object" && !Array.isArray(value)
|
||||||
|
? (value as { enabled?: boolean })
|
||||||
|
: {};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isWorkspacePluginAllowedByConfig(params: {
|
||||||
|
config: OpenClawConfig | undefined;
|
||||||
|
isImplicitlyAllowed?: (pluginId: string) => boolean;
|
||||||
|
plugin: PluginManifestRecord;
|
||||||
|
}): boolean {
|
||||||
|
const pluginsConfig = params.config?.plugins;
|
||||||
|
if (pluginsConfig?.enabled === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pluginId = normalizePluginConfigId(params.plugin.id);
|
||||||
|
if (!pluginId || hasPluginConfigId(pluginsConfig?.deny, pluginId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entry = findPluginConfigEntry(pluginsConfig?.entries, pluginId);
|
||||||
|
if (entry?.enabled === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entry?.enabled === true || hasPluginConfigId(pluginsConfig?.allow, pluginId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return params.isImplicitlyAllowed?.(pluginId) ?? false;
|
||||||
|
}
|
||||||
@@ -2,8 +2,11 @@ import { resolveProviderAuthAliasMap } from "../agents/provider-auth-aliases.js"
|
|||||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||||
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
|
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";
|
||||||
import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
|
import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
|
||||||
|
import {
|
||||||
|
isWorkspacePluginAllowedByConfig,
|
||||||
|
normalizePluginConfigId,
|
||||||
|
} from "../plugins/plugin-config-trust.js";
|
||||||
import { hasKind } from "../plugins/slots.js";
|
import { hasKind } from "../plugins/slots.js";
|
||||||
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
|
|
||||||
|
|
||||||
const CORE_PROVIDER_AUTH_ENV_VAR_CANDIDATES = {
|
const CORE_PROVIDER_AUTH_ENV_VAR_CANDIDATES = {
|
||||||
anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
|
anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
|
||||||
@@ -25,59 +28,17 @@ export type ProviderEnvVarLookupParams = {
|
|||||||
includeUntrustedWorkspacePlugins?: boolean;
|
includeUntrustedWorkspacePlugins?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PluginEntriesConfig = NonNullable<NonNullable<OpenClawConfig["plugins"]>["entries"]>;
|
|
||||||
|
|
||||||
function normalizePluginConfigId(id: unknown): string {
|
|
||||||
return normalizeOptionalLowercaseString(id) ?? "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasPluginId(list: unknown, pluginId: string): boolean {
|
|
||||||
return Array.isArray(list) && list.some((entry) => normalizePluginConfigId(entry) === pluginId);
|
|
||||||
}
|
|
||||||
|
|
||||||
function findPluginEntry(
|
|
||||||
entries: PluginEntriesConfig | undefined,
|
|
||||||
pluginId: string,
|
|
||||||
): { enabled?: boolean } | undefined {
|
|
||||||
if (!entries || typeof entries !== "object" || Array.isArray(entries)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
for (const [key, value] of Object.entries(entries)) {
|
|
||||||
if (normalizePluginConfigId(key) !== pluginId) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return value && typeof value === "object" && !Array.isArray(value)
|
|
||||||
? (value as { enabled?: boolean })
|
|
||||||
: {};
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isWorkspacePluginTrustedForProviderEnvVars(
|
function isWorkspacePluginTrustedForProviderEnvVars(
|
||||||
plugin: PluginManifestRecord,
|
plugin: PluginManifestRecord,
|
||||||
config: OpenClawConfig | undefined,
|
config: OpenClawConfig | undefined,
|
||||||
): boolean {
|
): boolean {
|
||||||
const pluginsConfig = config?.plugins;
|
return isWorkspacePluginAllowedByConfig({
|
||||||
if (pluginsConfig?.enabled === false) {
|
config,
|
||||||
return false;
|
isImplicitlyAllowed: (pluginId) =>
|
||||||
}
|
hasKind(plugin.kind, "context-engine") &&
|
||||||
|
normalizePluginConfigId(config?.plugins?.slots?.contextEngine) === pluginId,
|
||||||
const pluginId = normalizePluginConfigId(plugin.id);
|
plugin,
|
||||||
if (!pluginId || hasPluginId(pluginsConfig?.deny, pluginId)) {
|
});
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entry = findPluginEntry(pluginsConfig?.entries, pluginId);
|
|
||||||
if (entry?.enabled === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (entry?.enabled === true || hasPluginId(pluginsConfig?.allow, pluginId)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
hasKind(plugin.kind, "context-engine") &&
|
|
||||||
normalizePluginConfigId(pluginsConfig?.slots?.contextEngine) === pluginId
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldUsePluginProviderEnvVars(
|
function shouldUsePluginProviderEnvVars(
|
||||||
|
|||||||
Reference in New Issue
Block a user