@@ -71,10 +71,16 @@ func (h *Handlers) loadRepoAndAuthorize(w http.ResponseWriter, r *http.Request, |
| 71 | 71 | return reposdb.Repo{}, usersdb.User{}, false |
| 72 | 72 | } |
| 73 | 73 | viewer := middleware.CurrentUserFromContext(r.Context()) |
| 74 | | - actor := policy.UserActor(viewer.ID, viewer.Username, false, false) |
| 74 | + actor := policy.UserActor(viewer.ID, viewer.Username, viewer.IsSuspended, false) |
| 75 | 75 | repoRef := policy.NewRepoRefFromRepo(row) |
| 76 | | - if !policy.Can(r.Context(), policy.Deps{Pool: h.d.Pool}, actor, action, repoRef).Allow { |
| 77 | | - h.d.Render.HTTPError(w, r, http.StatusNotFound, "") |
| 76 | + dec := policy.Can(r.Context(), policy.Deps{Pool: h.d.Pool}, actor, action, repoRef) |
| 77 | + if !dec.Allow { |
| 78 | + // Maybe404 picks 404 for "shouldn't know it exists" denials |
| 79 | + // (private + non-collab) and 403 for honest "you can't do that |
| 80 | + // to a repo you can see" denials (owner pushing to archived). |
| 81 | + // Without this we leaked existence by always 404'ing — fixed |
| 82 | + // per S00-S25 audit, finding H7. |
| 83 | + h.d.Render.HTTPError(w, r, policy.Maybe404(dec, repoRef, actor), "") |
| 78 | 84 | return reposdb.Repo{}, usersdb.User{}, false |
| 79 | 85 | } |
| 80 | 86 | return row, owner, true |
@@ -252,9 +258,10 @@ func (h *Handlers) transferCancel(w http.ResponseWriter, r *http.Request) { |
| 252 | 258 | return |
| 253 | 259 | } |
| 254 | 260 | viewer := middleware.CurrentUserFromContext(r.Context()) |
| 255 | | - actor := policy.UserActor(viewer.ID, viewer.Username, false, false) |
| 256 | | - if !policy.Can(r.Context(), policy.Deps{Pool: h.d.Pool}, actor, policy.ActionRepoAdmin, policy.NewRepoRefFromRepo(repo)).Allow { |
| 257 | | - h.d.Render.HTTPError(w, r, http.StatusNotFound, "") |
| 261 | + actor := policy.UserActor(viewer.ID, viewer.Username, viewer.IsSuspended, false) |
| 262 | + repoRef := policy.NewRepoRefFromRepo(repo) |
| 263 | + if dec := policy.Can(r.Context(), policy.Deps{Pool: h.d.Pool}, actor, policy.ActionRepoAdmin, repoRef); !dec.Allow { |
| 264 | + h.d.Render.HTTPError(w, r, policy.Maybe404(dec, repoRef, actor), "") |
| 258 | 265 | return |
| 259 | 266 | } |
| 260 | 267 | if err := lifecycle.CancelTransfer(r.Context(), h.lifecycleDeps(), viewer.ID, id); err != nil { |