86 lines
1.9 KiB
TypeScript
86 lines
1.9 KiB
TypeScript
import {
|
|
type Actor,
|
|
type JobRecord,
|
|
type ProviderName,
|
|
type TrustTier,
|
|
} from "@voidbot/shared";
|
|
|
|
export interface ProviderAccessDecision {
|
|
allowed: boolean;
|
|
tier: TrustTier;
|
|
reasonKey?: string;
|
|
}
|
|
|
|
export class PermissionEngine {
|
|
public constructor(
|
|
private readonly ownerDiscordId: string,
|
|
private readonly options: {
|
|
localLlmAllowPublic?: boolean;
|
|
} = {},
|
|
) {}
|
|
|
|
public resolveTrustTier(actor: Actor): TrustTier {
|
|
if (actor.id === this.ownerDiscordId) {
|
|
return "T2";
|
|
}
|
|
|
|
if (actor.isAdmin) {
|
|
return "T1";
|
|
}
|
|
|
|
return "T0";
|
|
}
|
|
|
|
public canUseProvider(actor: Actor, provider: ProviderName): ProviderAccessDecision {
|
|
const tier = this.resolveTrustTier(actor);
|
|
|
|
if (provider === "owner_codex") {
|
|
return actor.id === this.ownerDiscordId
|
|
? { allowed: true, tier }
|
|
: {
|
|
allowed: false,
|
|
tier,
|
|
reasonKey: "permission.owner_codex.denied",
|
|
};
|
|
}
|
|
|
|
if (provider === "openai_api") {
|
|
return {
|
|
allowed: tier === "T0" || tier === "T1" || tier === "T2",
|
|
tier,
|
|
};
|
|
}
|
|
|
|
if (provider === "local_llm") {
|
|
return this.options.localLlmAllowPublic || tier === "T1" || tier === "T2"
|
|
? {
|
|
allowed: true,
|
|
tier,
|
|
}
|
|
: {
|
|
allowed: false,
|
|
tier,
|
|
reasonKey: "permission.local_llm.denied",
|
|
};
|
|
}
|
|
|
|
return {
|
|
allowed: true,
|
|
tier,
|
|
};
|
|
}
|
|
|
|
public canReindex(actor: Actor): boolean {
|
|
const tier = this.resolveTrustTier(actor);
|
|
return tier === "T1" || tier === "T2";
|
|
}
|
|
|
|
public canManageConfiguration(actor: Actor): boolean {
|
|
const tier = this.resolveTrustTier(actor);
|
|
return tier === "T1" || tier === "T2";
|
|
}
|
|
|
|
public canApproveJob(actor: Actor, job: JobRecord): boolean {
|
|
return actor.id === this.ownerDiscordId && job.requester.id === this.ownerDiscordId;
|
|
}
|
|
}
|