mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-09 22:25:02 +03:00
92 lines
4.2 KiB
TypeScript
92 lines
4.2 KiB
TypeScript
import { expect } from "bun:test"
|
|
import { Context, Effect, Layer } from "effect"
|
|
import { HttpEffect, HttpRouter, HttpServer } from "effect/http"
|
|
import { tmpdirScoped } from "../../core/test/fixture/tmpdir"
|
|
import { it } from "../../core/test/lib/effect"
|
|
import { createRoutes } from "../src/routes"
|
|
|
|
it.live("integration policy filters /connect and blocks denied integrations and providers", () =>
|
|
Effect.gen(function* () {
|
|
const tmp = yield* tmpdirScoped("opencode-integration-policy-")
|
|
const context = yield* Layer.build(
|
|
createRoutes({
|
|
password: "secret",
|
|
database: { path: ":memory:" },
|
|
models: { fetch: false },
|
|
fs: { filewatcher: false },
|
|
config: {
|
|
directory: tmp.path,
|
|
project: false,
|
|
content: JSON.stringify({
|
|
providers: {
|
|
custom: {
|
|
name: "Configured Custom Provider",
|
|
package: "@opencode/ai/providers/openai-compatible",
|
|
settings: { apiKey: "secret" },
|
|
models: { chat: {} },
|
|
},
|
|
},
|
|
mcp: { servers: { wiki: { type: "remote", url: "http://127.0.0.1:9/mcp" } } },
|
|
policies: [
|
|
{ action: "integration.connect", resource: "*", effect: "deny" },
|
|
{ action: "integration.connect", resource: "opencode", effect: "allow" },
|
|
{ action: "integration.use", resource: "*", effect: "deny" },
|
|
{ action: "integration.use", resource: "opencode#org_01M3CAP8H43Z49CER6NT0Y3ZF1", effect: "allow" },
|
|
],
|
|
}),
|
|
},
|
|
}).pipe(Layer.provide(HttpServer.layerServices)),
|
|
)
|
|
const handler = Context.get(context, HttpRouter.HttpRouter)
|
|
.asHttpEffect()
|
|
.pipe(HttpEffect.toWebHandlerWith(context))
|
|
const request = (method: "GET" | "POST", route: string, body?: unknown) =>
|
|
Effect.promise(async (signal) => {
|
|
const url = new URL(route, "http://opencode.local")
|
|
url.searchParams.set("location[directory]", tmp.path)
|
|
const response = await handler(
|
|
new Request(url, {
|
|
method,
|
|
headers: {
|
|
authorization: `Basic ${btoa("opencode:secret")}`,
|
|
...(body === undefined ? {} : { "content-type": "application/json" }),
|
|
},
|
|
body: body === undefined ? undefined : JSON.stringify(body),
|
|
signal,
|
|
}),
|
|
)
|
|
return { status: response.status, body: response.status === 204 ? undefined : await response.json() }
|
|
})
|
|
|
|
const integrations = yield* request("GET", "/api/integration")
|
|
expect(integrations.status).toBe(200)
|
|
// MCP sign-ins are outside integration policy; `mcp.use` governs MCP servers.
|
|
const listed: { id: string; metadata?: { source?: string } }[] = integrations.body.data
|
|
expect(listed.filter((integration) => integration.metadata?.source !== "mcp").map((item) => item.id)).toEqual([
|
|
"opencode",
|
|
])
|
|
const mcp = listed.find((integration) => integration.metadata?.source === "mcp")
|
|
expect(mcp?.id).toStartWith("mcp_")
|
|
const signIn = yield* request("POST", `/api/integration/${encodeURIComponent(mcp?.id ?? "")}/connect/oauth`, {
|
|
methodID: mcp?.id,
|
|
})
|
|
expect(signIn.body?.kind).not.toBe("integration_policy")
|
|
|
|
const denied = yield* request("POST", "/api/integration/anthropic/connect/key", { key: "sk-test" })
|
|
expect(denied.status).toBe(400)
|
|
expect(denied.body).toMatchObject({ _tag: "InvalidRequestError", kind: "integration_policy" })
|
|
const credential = yield* request("POST", "/api/credential", {
|
|
integrationID: "anthropic",
|
|
value: { type: "key", key: "sk-test" },
|
|
})
|
|
expect(credential.status).toBe(400)
|
|
expect(credential.body).toMatchObject({ _tag: "InvalidRequestError", kind: "integration_policy" })
|
|
expect((yield* request("GET", "/api/credential")).body.data).toEqual([])
|
|
const wellknown = yield* request("POST", "/api/experimental/integration/wellknown", { url: "https://ai.acme.com" })
|
|
expect(wellknown.body).toMatchObject({ kind: "integration_policy" })
|
|
|
|
// The signed-out free tier and the authored provider are both denied.
|
|
expect((yield* request("GET", "/api/provider")).body.data).toEqual([])
|
|
}),
|
|
)
|