Files
kuber/tests/server/trust-store.test.ts

146 lines
4.4 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import type { KubernetesObjectApi } from "@kubernetes/client-node";
import { KubernetesTrustStore } from "../../server/kubernetes-state";
import { MemoryTrustStore } from "../../server/trust-store";
type ConfigMap = {
apiVersion: string;
kind: string;
metadata: {
name: string;
namespace?: string;
labels?: Record<string, string>;
};
data?: Record<string, string>;
};
class FakeObjects {
readonly maps = new Map<string, ConfigMap>();
readonly selectors: string[] = [];
async create(value: ConfigMap): Promise<void> {
this.maps.set(value.metadata.name, structuredClone(value));
}
async read(value: ConfigMap): Promise<ConfigMap> {
const found = this.maps.get(value.metadata.name);
if (!found) throw { code: 404 };
return structuredClone(found);
}
async delete(value: ConfigMap): Promise<void> {
if (!this.maps.delete(value.metadata.name)) throw { code: 404 };
}
async list(
_apiVersion: string,
_kind: string,
_namespace?: string,
_pretty?: string,
_exact?: boolean,
_exportValue?: boolean,
_fieldSelector?: string,
labelSelector?: string,
): Promise<{ items: ConfigMap[] }> {
this.selectors.push(labelSelector ?? "");
const labels = Object.fromEntries(
(labelSelector ?? "")
.split(",")
.filter(Boolean)
.map((part) => part.split("=")),
);
return {
items: [...this.maps.values()].filter((item) =>
Object.entries(labels).every(
([key, value]) => item.metadata.labels?.[key] === value,
),
),
};
}
}
describe("namespace trust store", () => {
test("rejects invalid namespace and fingerprint", async () => {
const store = new MemoryTrustStore();
await expect(store.grant("Demo", "a".repeat(64))).rejects.toThrow();
await expect(store.grant("a".repeat(64), "a".repeat(64))).rejects.toThrow();
await expect(store.grant("demo", "bad")).rejects.toThrow();
});
test("requires explicit registration for each CWD fingerprint", async () => {
const store = new MemoryTrustStore();
const first = "a".repeat(64);
const second = "b".repeat(64);
await store.grant("demo", first);
expect(await store.has("demo", first)).toBe(true);
expect(await store.has("demo", second)).toBe(false);
await store.grant("demo", second);
expect(await store.list("demo")).toEqual([first, second]);
expect(await store.revoke("demo", first)).toBe(true);
expect(await store.has("demo", first)).toBe(false);
});
test("persists valid ConfigMap records and ignores malformed payloads", async () => {
const objects = new FakeObjects();
const store = new KubernetesTrustStore(
objects as unknown as KubernetesObjectApi,
);
const fingerprint = "a".repeat(64);
await store.grant("demo", fingerprint);
const [record] = [...objects.maps.values()];
expect(record).toMatchObject({
apiVersion: "v1",
kind: "ConfigMap",
metadata: {
namespace: "kuber-system",
labels: {
"kuber.astrxl.dev/type": "trust",
"kuber.astrxl.dev/workspace": "demo",
},
},
data: { payload: JSON.stringify({ project: "demo", fingerprint }) },
});
expect(record?.metadata.name).toMatch(/^trust-[a-f0-9]{48}$/);
expect(await store.list("demo")).toEqual([fingerprint]);
expect(objects.selectors).toContain(
"kuber.astrxl.dev/type=trust,kuber.astrxl.dev/workspace=demo",
);
objects.maps.set("trust-malformed", {
apiVersion: "v1",
kind: "ConfigMap",
metadata: {
name: "trust-malformed",
labels: {
"kuber.astrxl.dev/type": "trust",
"kuber.astrxl.dev/workspace": "demo",
},
},
data: { payload: "not-json" },
});
objects.maps.set("trust-wrong-project", {
apiVersion: "v1",
kind: "ConfigMap",
metadata: {
name: "trust-wrong-project",
labels: {
"kuber.astrxl.dev/type": "trust",
"kuber.astrxl.dev/workspace": "demo",
},
},
data: {
payload: JSON.stringify({
project: "other",
fingerprint: "b".repeat(64),
}),
},
});
expect(await store.list("demo")).toEqual([fingerprint]);
expect(await store.revoke("demo", fingerprint)).toBe(true);
expect(await store.has("demo", fingerprint)).toBe(false);
expect(await store.revoke("demo", fingerprint)).toBe(false);
});
});