gitea: say that a repository made private later is granted only at the next start or by hand, and let one unreadable permission refuse its repository, not the whole pass
mesh/delivery merged: source.main moved to novox/mesh-catalog@a4f5df797b68
mesh/check being carried to b4a7bb9dea50 on a4f5df797b68
mesh/delivery merged: source.main moved to novox/mesh-catalog@a4f5df797b68
mesh/check being carried to b4a7bb9dea50 on a4f5df797b68
This commit is contained in:
@@ -10,8 +10,11 @@
|
||||
// - **at the start**, one pass over every repository of every user and organisation;
|
||||
// - **on the forge's own event** (the system webhook, webhook.ts): `forge.repository.created` and `forge.fork` at
|
||||
// once, and the first event of any repository this process has not yet seen readable, since the forge may not
|
||||
// send a repository's creation for every owner, and a repository made private later sends no creation at all.
|
||||
// Nothing polls for it.
|
||||
// send a repository's creation for every owner. Nothing polls for it.
|
||||
//
|
||||
// **Not caught: a repository made private later.** The forge sends no event for a change of visibility, and a public
|
||||
// repository is already seen readable by the start's pass, so its events ask nothing. Such a repository is granted at
|
||||
// the module's next start, or now by `gitea_grant_read`; `gitea_unreadable_repos` shows it meanwhile.
|
||||
//
|
||||
// **The grant needs the site administrator's login.** Adding a collaborator asks the repository's administration,
|
||||
// which on another user's repository only the site administrator holds; the module holds that login for setting the
|
||||
@@ -76,8 +79,14 @@ export class ReadAll {
|
||||
const repos = await this.forge.everyRepository();
|
||||
const out: Unreadable[] = [];
|
||||
for (const repo of repos) {
|
||||
const u = await this.judge(repo);
|
||||
if (u) out.push(u);
|
||||
try {
|
||||
const u = await this.judge(repo);
|
||||
if (u) out.push(u);
|
||||
} catch (err) {
|
||||
// A permission the forge would not answer is said for that repository; the rest are still looked at.
|
||||
out.push({ repository: repo.full_name, permission: "unknown", private: repo.private, archived: repo.archived,
|
||||
why: `the forge did not answer ${this.account}'s permission on it — ${err instanceof Error ? err.message : String(err)}` });
|
||||
}
|
||||
}
|
||||
return { checked: repos.length, unreadable: out };
|
||||
}
|
||||
@@ -97,7 +106,14 @@ export class ReadAll {
|
||||
} else repos = await this.forge.everyRepository();
|
||||
const result: Granted = { checked: repos.length, granted: [], refused: [] };
|
||||
for (const repo of repos) {
|
||||
const u = await this.judge(repo);
|
||||
let u: Unreadable | null;
|
||||
try {
|
||||
u = await this.judge(repo);
|
||||
} catch (err) {
|
||||
// One repository whose permission cannot be read is a refusal of its own, never the end of the pass.
|
||||
result.refused.push({ repository: repo.full_name, why: `its permission could not be read — ${err instanceof Error ? err.message : String(err)}` });
|
||||
continue;
|
||||
}
|
||||
if (!u) continue;
|
||||
try {
|
||||
await this.forge.addReadCollaborator(repo.owner, repo.name, this.account);
|
||||
@@ -106,7 +122,13 @@ export class ReadAll {
|
||||
continue;
|
||||
}
|
||||
// Read back: the forge's own word that the account reads it now, never the grant's answer alone.
|
||||
const after = await this.forge.repositoryPermission(repo.owner, repo.name, this.account);
|
||||
let after: string;
|
||||
try {
|
||||
after = await this.forge.repositoryPermission(repo.owner, repo.name, this.account);
|
||||
} catch (err) {
|
||||
result.refused.push({ repository: repo.full_name, why: `granted, but its permission could not be read back — ${err instanceof Error ? err.message : String(err)}` });
|
||||
continue;
|
||||
}
|
||||
if (READS.has(after)) {
|
||||
this.readable.add(repo.full_name);
|
||||
result.granted.push(repo.full_name);
|
||||
@@ -136,6 +158,8 @@ export class ReadAll {
|
||||
return;
|
||||
}
|
||||
const made = event.name === "forge.repository.created" || event.name === "forge.fork";
|
||||
// Seen readable once, its events ask nothing: so a repository made private after that is not caught here (the
|
||||
// forge says no change of visibility), only at the next start or by gitea_grant_read.
|
||||
if (!made && this.readable.has(full)) return;
|
||||
const r = await this.grant([full]);
|
||||
if (r.granted.length) this.log(`${this.account} was given read on ${full}, on the forge's ${event.name}`);
|
||||
|
||||
Reference in New Issue
Block a user