feat(foundry): close the operational map data loop
This commit is contained in:
@@ -125,3 +125,94 @@ test("managed Foundry grant provisioning signs digest-only requests and persists
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test("managed Foundry grant provisioning keeps successor capabilities separate and revokes an exact predecessor generation", async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), "foundry-reader-grant-generation-"));
|
||||
const privateKeyFile = join(root, "private-key.pem");
|
||||
const grantsDir = join(root, "grants");
|
||||
const { privateKey } = generateKeyPairSync("ed25519");
|
||||
await writeFile(privateKeyFile, privateKey.export({ type: "pkcs8", format: "pem" }), { mode: 0o400 });
|
||||
await chmod(privateKeyFile, 0o400);
|
||||
const requests = [];
|
||||
const fetchImpl = async (input, options) => {
|
||||
const url = new URL(input);
|
||||
const parsed = JSON.parse(String(options.body));
|
||||
requests.push({ method: options.method, path: url.pathname, body: parsed });
|
||||
const bindingKey = url.pathname.match(/by-key\/([^/]+)/)?.[1];
|
||||
if (url.pathname.endsWith("/plan")) {
|
||||
const id = parsed.allowedDataProductIds[0];
|
||||
return Response.json({
|
||||
ok: true,
|
||||
sourceScope: "resolved-server-side",
|
||||
dataProducts: [{
|
||||
id,
|
||||
version: id.endsWith(".v2") ? "2.0.0" : "1.0.0",
|
||||
deliveryMode: "snapshot+patch",
|
||||
semanticTypes: ["map.moving_object"],
|
||||
active: true,
|
||||
}],
|
||||
});
|
||||
}
|
||||
if (url.pathname.endsWith("/revoke")) {
|
||||
const generation = Number(url.pathname.split("/").at(-2));
|
||||
return Response.json({
|
||||
ok: true,
|
||||
idempotent: false,
|
||||
readerBinding: {
|
||||
bindingKey: decodeURIComponent(bindingKey),
|
||||
generation,
|
||||
active: false,
|
||||
expiresAt: null,
|
||||
sourceScope: "resolved-server-side",
|
||||
allowedDataProductIds: ["fleet.positions.current.v1"],
|
||||
},
|
||||
});
|
||||
}
|
||||
return Response.json({
|
||||
ok: true,
|
||||
idempotent: false,
|
||||
readerBinding: {
|
||||
bindingKey: decodeURIComponent(bindingKey),
|
||||
generation: parsed.generation,
|
||||
active: true,
|
||||
expiresAt: null,
|
||||
sourceScope: "resolved-server-side",
|
||||
allowedDataProductIds: parsed.allowedDataProductIds,
|
||||
},
|
||||
});
|
||||
};
|
||||
const provisioner = createFoundryReaderGrantProvisioner({
|
||||
dataPlaneUrl: "http://edp.test",
|
||||
privateKeyFile,
|
||||
grantsDir,
|
||||
serviceId,
|
||||
keyId,
|
||||
audience,
|
||||
fetchImpl,
|
||||
randomBytesImpl: (size) => Buffer.alloc(size, requests.length + 1),
|
||||
randomUUIDImpl: () => "33333333-3333-4333-8333-333333333333",
|
||||
production: false,
|
||||
});
|
||||
const successorTarget = structuredClone(target);
|
||||
successorTarget.binding.dataProductId = "fleet.positions.current.v2";
|
||||
try {
|
||||
const first = await provisioner.ensure(target, { generation: 1 });
|
||||
const second = await provisioner.ensure(successorTarget, { generation: 2 });
|
||||
assert.equal(first.generation, 1);
|
||||
assert.equal(second.generation, 2);
|
||||
const firstToken = await provisioner.readToken(target, { generation: 1 });
|
||||
const secondToken = await provisioner.readToken(successorTarget, { generation: 2 });
|
||||
assert.notEqual(firstToken, secondToken);
|
||||
const files = (await readdir(grantsDir)).sort();
|
||||
const baseFile = files.find((entry) => !entry.includes(".g"));
|
||||
assert.ok(baseFile);
|
||||
assert.deepEqual(files, [baseFile, `${baseFile}.g2`]);
|
||||
const revoked = await provisioner.revoke(target, { generation: 1 });
|
||||
assert.equal(revoked.generation, 1);
|
||||
assert.ok(requests.some((request) => request.method === "POST" && request.path.endsWith("/generations/1/revoke")));
|
||||
assert.equal(requests.some((request) => JSON.stringify(request.body).includes(firstToken)), false);
|
||||
assert.equal(requests.some((request) => JSON.stringify(request.body).includes(secondToken)), false);
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user