cli: row 199 rotate on a due gitea key; ISSUED names rotation-due, the state the bus's status() gives a gitea key past its rotate-by date, so credentials rotate no longer refuses it; a test over every status state; BUILD.md deviation 15 (gizmoduck-0050, sage-1494, #1697)
This commit is contained in:
1 parent
ff22fadebf
commit
c6868ba413
3 files changed
+32
-3
No files matched your search
@@ -107,6 +107,13 @@ this branch, apart from one slip noted under "Runs".
|
|||||||
refuses `ref-moved` with no request to the fork; a push recorded while the bus process pushes
|
refuses `ref-moved` with no request to the fork; a push recorded while the bus process pushes
|
||||||
refuses `decision-mismatch`, filed once, and the fork holds only the ticket's oid.
|
refuses `decision-mismatch`, filed once, and the fork holds only the ticket's oid.
|
||||||
|
|
||||||
|
15. **Fix: rotate on a due gitea key (gizmoduck-0050, sage-1494).** The CLI's `ISSUED` set
|
||||||
|
(`packages/cli/src/credentials.mjs`) listed valid, expiring and expired, but the bus's `status()`
|
||||||
|
gives a gitea key past its rotate-by date `rotation-due`. So `credentials rotate` refused the one
|
||||||
|
case it exists for. `ISSUED` now names every state status() gives a held token. The test:
|
||||||
|
`cli/tests/credentials.test.mjs`, "rotate goes ahead on each held state". Its mutant (the old set)
|
||||||
|
fails that test and goes in the section 11 list.
|
||||||
|
|
||||||
## N9, for the routing commit (sage-1388)
|
## N9, for the routing commit (sage-1388)
|
||||||
|
|
||||||
Today git.push.remote is a hard wait, so every publish carries a decision, and the decision's
|
Today git.push.remote is a hard wait, so every publish carries a decision, and the decision's
|
||||||
@@ -152,6 +159,9 @@ Hash pins: none on a changed file.
|
|||||||
sage-1440 changes (the poll bound, the mid-flight tests), single files, green before the commit: cli
|
sage-1440 changes (the poll bound, the mid-flight tests), single files, green before the commit: cli
|
||||||
publish-socket (7), git-socket (24), launcher (29). Hash pins: none on a changed file.
|
publish-socket (7), git-socket (24), launcher (29). Hash pins: none on a changed file.
|
||||||
|
|
||||||
|
The rotation-due fix, single files: cli credentials (4), green; the old-set mutant fails it 3/1.
|
||||||
|
Hash pins: none on a changed file.
|
||||||
|
|
||||||
Slip, 2026-10-20 about 19:51Z: I ran `node --test packages/tasks/tests/*.test.mjs` in one command,
|
Slip, 2026-10-20 about 19:51Z: I ran `node --test packages/tasks/tests/*.test.mjs` in one command,
|
||||||
which is a package suite, without asking Sage for the slot. It passed, 97 pass and 0 fail, in under a
|
which is a package suite, without asking Sage for the slot. It passed, 97 pass and 0 fail, in under a
|
||||||
minute. Reported to Sage in megavolt-0017.
|
minute. Reported to Sage in megavolt-0017.
|
||||||
@@ -34,7 +34,9 @@ async function readToken(stdin) {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ISSUED = new Set(["valid", "expiring", "expired"]);
|
// The states the bus's status() gives a held token: gitea is valid or rotation-due, vikunja valid,
|
||||||
|
// expiring or expired. not-issued and revoked hold none.
|
||||||
|
const ISSUED = new Set(["valid", "rotation-due", "expiring", "expired"]);
|
||||||
|
|
||||||
export async function credentialsCommand(args, io, callFor) {
|
export async function credentialsCommand(args, io, callFor) {
|
||||||
const parsed = parse(args);
|
const parsed = parse(args);
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ const ROWS = [
|
|||||||
{ service: "gitea", account: null, role: "reviewer", dateKind: "rotateBy", date: "2099-01-01", state: "revoked" },
|
{ service: "gitea", account: null, role: "reviewer", dateKind: "rotateBy", date: "2099-01-01", state: "revoked" },
|
||||||
];
|
];
|
||||||
|
|
||||||
function deps(calls) {
|
function deps(calls, rows = ROWS) {
|
||||||
const answer = (who) => (business) => async (verb, args) => {
|
const answer = (who) => (business) => async (verb, args) => {
|
||||||
calls.push({ who, business, verb, args });
|
calls.push({ who, business, verb, args });
|
||||||
if (verb === "credentials") return ROWS;
|
if (verb === "credentials") return rows;
|
||||||
if (verb === "credentials.issue") return { agent: args.agent, verb: "issue", service: args.service, date: args.date, state: "valid" };
|
if (verb === "credentials.issue") return { agent: args.agent, verb: "issue", service: args.service, date: args.date, state: "valid" };
|
||||||
return { agent: args.agent, verb: verb.slice(12), services: [] };
|
return { agent: args.agent, verb: verb.slice(12), services: [] };
|
||||||
};
|
};
|
||||||
@@ -57,6 +57,23 @@ test("row 199: issue and rotate send the stdin token once to credentials.issue a
|
|||||||
await assert.rejects(main(["credentials", "issue", "coder", "gitea", "--rotate-by", "2099-01-01", "--business", "acme"], withStdin(io({ CLAUDECODE: "1" }), TOKEN), d), /outside any agent run/);
|
await assert.rejects(main(["credentials", "issue", "coder", "gitea", "--rotate-by", "2099-01-01", "--business", "acme"], withStdin(io({ CLAUDECODE: "1" }), TOKEN), d), /outside any agent run/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// gizmoduck-0050: a gitea key past its rotate-by date is rotation-due, and rotate is how a human
|
||||||
|
// clears it. Every state the bus's status() gives a held token rotates; the other two refuse.
|
||||||
|
test("row 199: rotate goes ahead on each held state, rotation-due included, and refuses not-issued, revoked and an unknown entry", async () => {
|
||||||
|
const states = { valid: true, "rotation-due": true, expiring: true, expired: true, "not-issued": false, revoked: false };
|
||||||
|
for (const [state, held] of Object.entries(states)) {
|
||||||
|
const calls = [];
|
||||||
|
const d = deps(calls, [{ service: "gitea", account: null, role: "coder", dateKind: "rotateBy", date: "2020-01-01", state }]);
|
||||||
|
const run = main(["credentials", "rotate", "coder", "gitea", "--rotate-by", "2099-06-01", "--business", "acme"], withStdin(io(), TOKEN), d);
|
||||||
|
if (held) await run;
|
||||||
|
else await assert.rejects(run, /no issued gitea credential to rotate; use issue/);
|
||||||
|
assert.deepEqual(calls.map((c) => c.verb), held ? ["credentials", "credentials.issue"] : ["credentials"], state);
|
||||||
|
}
|
||||||
|
const calls = [];
|
||||||
|
await assert.rejects(main(["credentials", "rotate", "tester", "gitea", "--rotate-by", "2099-06-01", "--business", "acme"], withStdin(io(), TOKEN), deps(calls)), /no issued gitea credential/);
|
||||||
|
assert.deepEqual(calls.map((c) => c.verb), ["credentials"]);
|
||||||
|
});
|
||||||
|
|
||||||
test("row 199: status, revoke and delete; the tester runs status and revoke only", async () => {
|
test("row 199: status, revoke and delete; the tester runs status and revoke only", async () => {
|
||||||
const calls = [];
|
const calls = [];
|
||||||
const d = deps(calls);
|
const d = deps(calls);
|
||||||
|
|||||||
Reference in new issue
Block a user