fix: correctly check permissions

This commit is contained in:
Alpha Nerd 2026-06-02 08:34:31 +02:00
parent b4d8fd75d2
commit 9ce4dbf015
Signed by: alpha-nerd
SSH key fingerprint: SHA256:QkkAgVoYi9TQ0UKPkiKSfnerZy2h4qhi3SVPXJmBN+M

View file

@ -665,11 +665,15 @@ async function assertPermissions() {
return
}
// Otherwise the actor must have write access, i.e. be a collaborator/member.
// Forgejo: GET .../collaborators/{user} returns 204 if a collaborator, 404 if not.
// We use a raw fetch (not forgejoFetch) because the 204 response has no JSON body.
// Otherwise the actor must have at least write access. We query the effective
// permission endpoint rather than the bare collaborators endpoint, because the
// latter only lists *direct* collaborators and 404s for users who inherit
// access through an organization team (e.g. the "owners" team).
// Forgejo: GET .../collaborators/{user}/permission returns
// { permission: "admin" | "write" | "read" | "none", ... }
// accounting for direct collaboration, team membership, and org ownership.
const { forgejoToken } = getForgejoConfig()
const url = forgejoApiUrl("repos", context.repo.owner, context.repo.repo, "collaborators", actor)
const url = forgejoApiUrl("repos", context.repo.owner, context.repo.repo, "collaborators", actor, "permission")
let res: Response
try {
res = await fetch(url, { headers: { Authorization: `token ${forgejoToken}` } })
@ -678,9 +682,16 @@ async function assertPermissions() {
throw new Error(`Could not verify permissions for "${actor}": ${error.message}`)
}
if (res.status === 204 || res.ok) {
console.log(" permission: write (collaborator)")
return
if (res.ok) {
const { permission } = (await res.json().catch(() => ({}))) as { permission?: string }
if (permission === "admin" || permission === "write") {
console.log(` permission: ${permission}`)
return
}
throw new Error(
`User "${actor}" is not authorized to trigger this action ` +
`(requires write access to ${context.repo.owner}/${context.repo.repo}, has "${permission ?? "none"}").`,
)
}
if (res.status === 404) {
throw new Error(