bus: row 236 r3, a revoke during a settle whoami ends revoked in the 401 and token-unknown branches (Dewey N5, #1742)
This commit is contained in:
1 parent
77dd43c9e3
commit
7965efd0fb
3 files changed
+41
-2
No files matched your search
@@ -74,6 +74,10 @@ Each is a reading of the design where it left room. Dewey may rule otherwise.
|
|||||||
another id with `gitea-user-foreign`, any other status leaves the entry. Skips go in `grant.swept` and
|
another id with `gitea-user-foreign`, any other status leaves the entry. Skips go in `grant.swept` and
|
||||||
the sweep answer as `skipped: [{agent, user, id, reason}]`; a skipped entry is not left, so the next
|
the sweep answer as `skipped: [{agent, user, id, reason}]`; a skipped entry is not left, so the next
|
||||||
sweep does not retry it.
|
sweep does not retry it.
|
||||||
|
20. r3, Dewey N5 (dewey-0783): the settle's 401 branch and its grant-token-unknown branch take the same
|
||||||
|
revoke check. A revoke during the whoami ends the grant `revoked`, not `grant-lost`, and the
|
||||||
|
token-unknown branch neither holds the agent again nor writes `grant-token-unknown`, so no start
|
||||||
|
names a file the revoke unlinked.
|
||||||
|
|
||||||
## Named for DEFERRED (r2, Dewey N1-N4)
|
## Named for DEFERRED (r2, Dewey N1-N4)
|
||||||
|
|
||||||
@@ -126,3 +130,6 @@ r2 tests, each red on 8bf442be9 by reading:
|
|||||||
interrupted settled:back` after the revoke deleted it.
|
interrupted settled:back` after the revoke deleted it.
|
||||||
- B2: "X-G14: a sweep retries a fire only for the user it fired: a remade or gone user is skipped and
|
- B2: "X-G14: a sweep retries a fire only for the user it fired: a remade or gone user is skipped and
|
||||||
named". On 8bf442be9 the retry fires the remade user (token list, delete, PATCH) and has no `skipped`.
|
named". On 8bf442be9 the retry fires the remade user (token list, delete, PATCH) and has no `skipped`.
|
||||||
|
- N5 (r3): "X-G11: a revoke during a settle whoami that finds a foreign token or a 401 ends it revoked, not
|
||||||
|
held or lost". On 77dd43c9e the branches end `grant-token-unknown` (the agent back in tokenUnknown) and
|
||||||
|
`grant-lost`.
|
||||||
@@ -1808,13 +1808,16 @@ export class Broker {
|
|||||||
try {
|
try {
|
||||||
this.#giteaKeys.unregister(business, agent);
|
this.#giteaKeys.unregister(business, agent);
|
||||||
} catch {}
|
} catch {}
|
||||||
this.#store.transaction(() => {
|
return this.#store.transaction(() => {
|
||||||
|
if (revoked()) return 'revoked';
|
||||||
this.#store.run('DELETE FROM gitea_grants WHERE business=? AND agent=?', business, agent);
|
this.#store.run('DELETE FROM gitea_grants WHERE business=? AND agent=?', business, agent);
|
||||||
this.#giteaFailed(business, decision, agent, 'grant-lost', { user, ...(serviceLeft.length ? { serviceLeft } : {}) });
|
this.#giteaFailed(business, decision, agent, 'grant-lost', { user, ...(serviceLeft.length ? { serviceLeft } : {}) });
|
||||||
});
|
|
||||||
return 'grant-lost';
|
return 'grant-lost';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (who.status === 200 && who.id !== null) {
|
if (who.status === 200 && who.id !== null) {
|
||||||
|
// A revoke during the whoami unlinked the file: holding it again would name a file that is gone.
|
||||||
|
if (this.#store.transaction(revoked)) return 'revoked';
|
||||||
// A live token this grant didn't mint: memory drops it, and the file, the record and both tokens stay.
|
// A live token this grant didn't mint: memory drops it, and the file, the record and both tokens stay.
|
||||||
try {
|
try {
|
||||||
this.#giteaKeys.hold(business, agent);
|
this.#giteaKeys.hold(business, agent);
|
||||||
|
|||||||
@@ -991,6 +991,35 @@ test('X-G11: a revoke while a sweep settles a rotation, forward or back, ends it
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('X-G11: a revoke during a settle whoami that finds a foreign token or a 401 ends it revoked, not held or lost', async (t) => {
|
||||||
|
for (const kind of ['grant-token-unknown', 'grant-lost']) {
|
||||||
|
const f = await setup(t);
|
||||||
|
const { id } = await openRotation(f);
|
||||||
|
// A token this grant did not mint, or one Gitea does not know.
|
||||||
|
const file = kind === 'grant-token-unknown' ? f.gitea.addToken(USER, 'foreign', SEAT_SCOPES).sha1 : 'f'.repeat(40);
|
||||||
|
writeFileSync(f.tokenFile, file + '\n');
|
||||||
|
let release;
|
||||||
|
const held = new Promise((r) => (release = r));
|
||||||
|
const seat = (e) => e.method === 'GET' && e.path === '/api/v1/token' && e.as !== 'mosaic-grant';
|
||||||
|
f.gitea.rule(seat, async () => {
|
||||||
|
await held;
|
||||||
|
return { pass: true };
|
||||||
|
});
|
||||||
|
const sweep = f.call('human', 'grants.sweep', { service: 'gitea' });
|
||||||
|
await until(() => f.gitea.requests.some(seat));
|
||||||
|
const revoke = f.call('human', 'grants.revoke', { service: 'gitea', agent: 'coder', reason: 'stop' });
|
||||||
|
release();
|
||||||
|
await revoke;
|
||||||
|
const swept = await sweep;
|
||||||
|
await f.broker.giteaIdle();
|
||||||
|
assert.deepEqual(swept.settled, [{ decision: id, outcome: 'revoked' }], kind);
|
||||||
|
assert.equal(f.ended(id).code, 'revoked');
|
||||||
|
assert.equal(f.grantEvents().some((e) => e.grantDecision === id && e.code === kind), false);
|
||||||
|
assert.deepEqual([...tokenUnknown(f.store, 'demo').keys()], []);
|
||||||
|
assert.equal(f.record(), undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('X-G12: a token that reaches wider than its forks fails with the repository named', async (t) => {
|
test('X-G12: a token that reaches wider than its forks fails with the repository named', async (t) => {
|
||||||
const collab = await setup(t);
|
const collab = await setup(t);
|
||||||
collab.gitea.addRepo('other', 'secret', { collaborators: [USER] });
|
collab.gitea.addRepo('other', 'secret', { collaborators: [USER] });
|
||||||
|
|||||||
Reference in new issue
Block a user