fix: fail closed without a repo push transport
This commit is contained in:
parent
83589aa2c2
commit
b03619e359
2 changed files with 50 additions and 4 deletions
|
|
@ -51,10 +51,11 @@ async function authorizeRepoPush(options, deps = {}) {
|
||||||
const map = await requestJson(fetchImpl, `${baseUrl}/api/navigation-map/read`, common, session.session_token);
|
const map = await requestJson(fetchImpl, `${baseUrl}/api/navigation-map/read`, common, session.session_token);
|
||||||
await requestJson(fetchImpl, `${baseUrl}/api/navigation-map/ack`, { ...common, map_hash: map.map_hash }, session.session_token);
|
await requestJson(fetchImpl, `${baseUrl}/api/navigation-map/ack`, { ...common, map_hash: map.map_hash }, session.session_token);
|
||||||
const grant = await requestJson(fetchImpl, `${baseUrl}/api/repo-push/grant`, { ...common, repo }, session.session_token);
|
const grant = await requestJson(fetchImpl, `${baseUrl}/api/repo-push/grant`, { ...common, repo }, session.session_token);
|
||||||
if (grant.transport && grant.transport.status !== "ready") {
|
if (!grant.transport || grant.transport.status !== "ready") {
|
||||||
output(`[LL-REPO-PUSH-TRANSPORT-BLOCKED] ${grant.transport.diagnostic_code || "repo_push_transport_unavailable"}`);
|
const transport = grant.transport || {};
|
||||||
output(`NEXT_STEP=${grant.transport.next_step || "读取服务器 operation receipt。"}`);
|
output(`[LL-REPO-PUSH-TRANSPORT-BLOCKED] ${transport.diagnostic_code || "repo_push_transport_unavailable"}`);
|
||||||
const error = new Error(grant.transport.diagnostic_code || "repo_push_transport_unavailable");
|
output(`NEXT_STEP=${transport.next_step || "服务器没有返回可验证的受限推送通道;禁止重试裸 git push,读取 operation receipt。"}`);
|
||||||
|
const error = new Error(transport.diagnostic_code || "repo_push_transport_unavailable");
|
||||||
error.receipt = grant.receipt;
|
error.receipt = grant.receipt;
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,13 @@ const path = require("node:path");
|
||||||
const { createApp } = require("./server");
|
const { createApp } = require("./server");
|
||||||
const { authorizeRepoPush } = require("./authorize-repo-push");
|
const { authorizeRepoPush } = require("./authorize-repo-push");
|
||||||
|
|
||||||
|
function response(status, body) {
|
||||||
|
return new Response(JSON.stringify(body), {
|
||||||
|
status,
|
||||||
|
headers: { "content-type": "application/json" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
test("repo-push helper stops with a server receipt when no safe transport is deployed", async () => {
|
test("repo-push helper stops with a server receipt when no safe transport is deployed", async () => {
|
||||||
const mail = [];
|
const mail = [];
|
||||||
const directory = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-repo-push-"));
|
const directory = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-repo-push-"));
|
||||||
|
|
@ -56,3 +63,41 @@ test("repo-push helper stops with a server receipt when no safe transport is dep
|
||||||
fs.rmSync(directory, { recursive: true, force: true });
|
fs.rmSync(directory, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("repo-push helper fails closed when an older server omits transport state", async () => {
|
||||||
|
const calls = [];
|
||||||
|
const grantPromise = authorizeRepoPush({
|
||||||
|
url: "https://example.invalid/authz",
|
||||||
|
persona: "ICE-GL-ZY001",
|
||||||
|
repo: "bingshuo/guanghu-ice-heart",
|
||||||
|
poll: 1,
|
||||||
|
}, {
|
||||||
|
sleep: async () => {},
|
||||||
|
output: line => calls.push(line),
|
||||||
|
fetch: async url => {
|
||||||
|
if (url.endsWith("/api/public/workorders")) {
|
||||||
|
return response(200, {
|
||||||
|
request_url: "https://example.invalid/authz/request/opaque",
|
||||||
|
workorder_id: "workorder",
|
||||||
|
claim_token: "claim",
|
||||||
|
expires_in: 60,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (url.endsWith("/claim")) return response(200, { session_token: "session" });
|
||||||
|
if (url.endsWith("/api/navigation-map/read")) return response(200, { map_hash: "map" });
|
||||||
|
if (url.endsWith("/api/navigation-map/ack")) return response(200, { ok: true });
|
||||||
|
if (url.endsWith("/api/repo-push/grant")) {
|
||||||
|
return response(200, {
|
||||||
|
ok: true,
|
||||||
|
repo: "bingshuo/guanghu-ice-heart",
|
||||||
|
receipt: { diagnostic_code: "repo_push_transport_unavailable" },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw new Error(`unexpected URL: ${url}`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await assert.rejects(grantPromise, /repo_push_transport_unavailable/);
|
||||||
|
assert.ok(calls.some(line => line.includes("LL-REPO-PUSH-TRANSPORT-BLOCKED")));
|
||||||
|
assert.ok(calls.some(line => line.includes("禁止重试裸 git push")));
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue