fix: Unify public-only token filtering in API queries and repo access checks#37118
Conversation
|
A few points worth addressing:
This comment was written with the help of Claude. |
e6a1872 to
4c8cc91
Compare
Resolved. |
| resp := MakeRequest(t, req, http.StatusOK) | ||
|
|
||
| var repos []api.Repository | ||
| DecodeJSON(t, resp, &repos) |
There was a problem hiding this comment.
chore: clean up tests #37715
- use modern generic syntax for remaining "DecodeJSON" calls
| if assert.Len(t, repos, 1) { | ||
| assert.Equal(t, "user5/repo4", repos[0].FullName) | ||
| } |
There was a problem hiding this comment.
require.Len(t, repos, 1)
…ea into lunny/fix_public_only_list_org
|
Pushing some fixups. Status code will be 404 to hide existance of private repos. |
Return 404 instead of 403 in repoAssignment and GetByID when a public-only token references a private repo, matching GitHub's convention of hiding repository existence. Also tidy the public-only checks: - TokenCanAccessRepo becomes a method on APIContext - Use VisibleType.IsPublic() instead of inline comparisons - Fold the two Organization sub-checks into one branch - Add coverage for watched-repo filtering Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
Two integration tests still expected 403 from the API path where repoAssignment now returns 404 for public-only tokens accessing private repos. Align the assertions with the new behavior. Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
|
I was unable to create a backport for 1.26. @lunny, please send one manually. 🍵 |
… checks (#37118) (#37773) backport #37118 This PR closes remaining `public-only` token gaps in the API by making the restriction apply consistently across repository, organization, activity, notification, and authenticated `/api/v1/user/...` routes. Previously, `public-only` tokens were still able to: - receive private results from some list/search/self endpoints, - access repository data through ID-based lookups, - and reach several authenticated self routes that should remain unavailable for public-only access. This change treats `public-only` as a cross-cutting visibility boundary: - list/search endpoints now filter private resources consistently, - repository lookups enforce the same restriction even when addressed indirectly, - and self routes that inherently expose or mutate private account state now reject `public-only` tokens. --- Generated by a coding agent with Codex 5.2 Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com> Co-authored-by: Nicolas <bircni@icloud.com>
* origin/main: (104 commits) fix(deps): update module github.com/go-git/go-git/v5 to v5.19.1 [security] (go-gitea#37786) fix(pull): handle empty pull request files view to allow reviews (go-gitea#37783) fix(markup): make RenderString never fail (go-gitea#37779) fix(markup): wrap indented code blocks for the code-copy button (go-gitea#37748) fix(permissions): Fix reading permission (go-gitea#37769) fix: add natural sort to sortTreeViewNodes (go-gitea#37772) fix: package creation unique conflict (go-gitea#37774) fix(deps): update npm dependencies (go-gitea#37768) fix(deps): update module gitlab.com/gitlab-org/api/client-go/v2 to v2.26.0 (go-gitea#37771) ci: split giteabot workflow (go-gitea#37770) [skip ci] Updated translations via Crowdin fix: Unify public-only token filtering in API queries and repo access checks (go-gitea#37118) fix(deps): update module google.golang.org/grpc to v1.81.1 (go-gitea#37762) chore: make DefaultTitleSource default to auto to match GitHub (go-gitea#37767) ci: fix cache-related issues (go-gitea#37761) chore: fix tests (go-gitea#37760) refactor(waitgroup): replace Add/Done goroutines with WaitGroup.Go (go-gitea#37764) fix(deps): update go dependencies (go-gitea#37752) chore(deps): update action dependencies (go-gitea#37751) fix(deps): update module github.com/google/go-github/v85 to v86 (go-gitea#37754) ... # Conflicts: # .github/workflows/pull-db-tests.yml # modules/storage/s3_test.go
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [code.gitea.io/gitea](https://github.com/go-gitea/gitea) | `v1.26.1` → `v1.26.2` |  |  | --- ### Release Notes <details> <summary>go-gitea/gitea (code.gitea.io/gitea)</summary> ### [`v1.26.2`](https://github.com/go-gitea/gitea/releases/tag/v1.26.2) [Compare Source](go-gitea/gitea@v1.26.1...v1.26.2) - SECURITY - fix(permissions): Fix reading permission ([#​37769](go-gitea/gitea#37769)) - fix(actions): make artifact signature payloads unambiguous ([#​37707](go-gitea/gitea#37707)) - fix: Unify public-only token filtering in API queries and repo access checks ([#​37118](go-gitea/gitea#37118)) - fix: Add missed token scope checking ([#​37735](go-gitea/gitea#37735)) - fix(oauth): bind token exchanges to the original client request ([#​37704](go-gitea/gitea#37704)) - fix(oauth): strengthen PKCE validation and refresh token replay protection ([#​37706](go-gitea/gitea#37706)) - fix(web): enforce token scopes on raw, media, and attachment downloads ([#​37698](go-gitea/gitea#37698)) - fix(security): enforce wiki git writes and LFS token access at request time ([#​37695](go-gitea/gitea#37695)) - feat(api): encrypt AWS creds ([#​37679](go-gitea/gitea#37679)) - fix(deps): update dependency mermaid to v11.15.0 \[security], add e2e test - fix(packages): Add label for private and internal package and fix composor package source permission check ([#​37610](go-gitea/gitea#37610)) - fix(git): Fix smart http request scope bug ([#​37583](go-gitea/gitea#37583)) - Fix basic auth bug ([#​37503](go-gitea/gitea#37503)) - Fix allow maintainer edit permission check ([#​37479](go-gitea/gitea#37479)) ([#​37484](go-gitea/gitea#37484)) - Fix URL sanitization to handle schemeless credentials ([#​37440](go-gitea/gitea#37440)) ([#​37471](go-gitea/gitea#37471)) - Fix attachment Content-Security-Policy ([#​37455](go-gitea/gitea#37455)) ([#​37464](go-gitea/gitea#37464)) - chore(deps): bump go-git/go-git/v5 to 5.19.0 ([#​37608](go-gitea/gitea#37608)) - BUGFIXES - fix(pull): handle empty pull request files view to allow reviews ([#​37783](go-gitea/gitea#37783)) - fix(markup): make RenderString never fail ([#​37779](go-gitea/gitea#37779)) - fix: add natural sort to sortTreeViewNodes ([#​37772](go-gitea/gitea#37772)) - fix: package creation unique conflict ([#​37774](go-gitea/gitea#37774)) - fix!: add DEFAULT\_TITLE\_SOURCE setting for pull request title default behavior ([#​37465](go-gitea/gitea#37465)) - fix: Allow direct commits for unprotected files with push restrictions ([#​37657](go-gitea/gitea#37657)) - fix(actions): wrong assumption that run id always >= job id ([#​37737](go-gitea/gitea#37737)) - fix(auth): set User-Agent on avatar fetch and sync avatar on link-account register ([#​37564](go-gitea/gitea#37564)) ([#​37588](go-gitea/gitea#37588)) - fix(actions): deadlock between PrepareRunAndInsert and UpdateTaskByState ([#​37692](go-gitea/gitea#37692)) - fix(repo): /generate must sync the branch table for the new repo ([#​37693](go-gitea/gitea#37693)) - build: Fix snap build (1.26) - fix(actions): run TransferLogs on UpdateLog{Rows:\[], NoMore:true} ([#​37631](go-gitea/gitea#37631)) - fix show correct mergebase - fix: make clone URL respect public URL detection setting ([#​37615](go-gitea/gitea#37615)) - fix: "run as root" check ([#​37622](go-gitea/gitea#37622)) - chore(deps): update dependency go to v1.26.3 ([#​37601](go-gitea/gitea#37601)) - Compare dropdown fails when selecting branch with no common merge-base ([#​37470](go-gitea/gitea#37470)) - fix: treat email addresses case-insensitively ([#​37600](go-gitea/gitea#37600)) - fix(actions): fix blank lines after ::endgroup:: ([#​37597](go-gitea/gitea#37597)) - fix(actions): report individual step status in workflow job API response ([#​37592](go-gitea/gitea#37592)) - fix: Invalid UTF-8 commit messages in JSON API responses ([#​37542](go-gitea/gitea#37542)) - fix: use consistent GetUser family functions ([#​37553](go-gitea/gitea#37553)) - fix(api): return 409 message instead of empty JSON for wrong commit id ([#​37572](go-gitea/gitea#37572)) - fix(actions): prevent panic when workflow contains null jobs ([#​37570](go-gitea/gitea#37570)) - Make ServeSetHeaders default to download attachment if filename exists ([#​37552](go-gitea/gitea#37552)) ([#​37555](go-gitea/gitea#37555)) - Fix(actions): validate workflow param to prevent 500 error ([#​37546](go-gitea/gitea#37546)) ([#​37554](go-gitea/gitea#37554)) - Don't unblock run-level-concurrency-blocked runs in the resolver ([#​37461](go-gitea/gitea#37461)) ([#​37538](go-gitea/gitea#37538)) - Fix(packages): use file names for generic web downloads ([#​37514](go-gitea/gitea#37514)) ([#​37520](go-gitea/gitea#37520)) - Fix merge autodetect can't close other PRs but only the last one when multiple PRs are pushed at once ([#​37512](go-gitea/gitea#37512)) ([#​37516](go-gitea/gitea#37516)) - Fix update branch protection order ([#​37508](go-gitea/gitea#37508)) ([#​37513](go-gitea/gitea#37513)) - Fix mCaptcha broken after Vite migration ([#​37492](go-gitea/gitea#37492)) ([#​37509](go-gitea/gitea#37509)) - Fix review submission from single-commit PR view ([#​37475](go-gitea/gitea#37475)) ([#​37485](go-gitea/gitea#37485)) - Fix scheduled action panic with null event payload ([#​37459](go-gitea/gitea#37459)) ([#​37466](go-gitea/gitea#37466)) - Make GetPossibleUserByID can handle deleted user ([#​37430](go-gitea/gitea#37430)) ([#​37431](go-gitea/gitea#37431)) - Remove excessive quote from terraform instructions ([#​37424](go-gitea/gitea#37424)) ([#​37426](go-gitea/gitea#37426)) - Fix color regressions, add `priority` color ([#​37417](go-gitea/gitea#37417)) ([#​37421](go-gitea/gitea#37421)) - MISC - Add CurrentURL template variable back ([#​37444](go-gitea/gitea#37444)) ([#​37449](go-gitea/gitea#37449)) Instances on **[Gitea Cloud](https://cloud.gitea.com)** will be automatically upgraded to this version during the specified maintenance window. </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/apoci/pulls/47
This PR closes remaining
public-onlytoken gaps in the API by making the restriction apply consistently across repository, organization, activity, notification, and authenticated/api/v1/user/...routes.Previously,
public-onlytokens were still able to:This change treats
public-onlyas a cross-cutting visibility boundary:public-onlytokens.What changed
Shared public-only filtering helpers
Added
ApplyPublicOnlyhelpers to option structs used by search/list APIs so callers can enforce public-only filtering uniformly:models/user/search.gomodels/organization/org_list.gomodels/repo/repo_list.gomodels/repo/user_repo.gomodels/activities/action.goThese helpers are now used by:
Repository access hardening
Added
TokenCanAccessRepo()inservices/context/api.goand used it to reject private repository access for public-only tokens even when the repo is resolved indirectly.This now protects cases such as:
/api/v1/repositories/{id}/api/v1/userself-route hardeningThe authenticated
/api/v1/userroute group now setsctx.ContextUser = ctx.Doerbefore public-only checks and appliescheckTokenPublicOnly()consistently.For endpoints that are inherently private account surfaces, this PR explicitly rejects public-only tokens via
rejectPublicOnly().This includes representative self routes such as:
/api/v1/user/api/v1/user/settings/api/v1/user/emails/api/v1/user/keys/api/v1/user/gpg_keys/api/v1/user/gpg_key_token/api/v1/user/gpg_key_verify/api/v1/user/applications/oauth2/api/v1/user/actions/.../api/v1/user/hooks/api/v1/user/avatar/api/v1/user/times/api/v1/user/stopwatches/api/v1/user/teams/api/v1/user/blocksFor self list endpoints that can safely expose only public data, the behavior remains filtered rather than fully blocked where appropriate.
Other route fixes
Also tightened public-only handling for:
/api/v1/notificationsand related thread endpoints/api/v1/user/orgsWhy
public-onlytokens are intended to be limited to public resources.This PR fixes cases where that boundary was incomplete:
The result is a more consistent rule set:
Testing
Added and updated integration coverage for:
public-only filtering on:
public-only rejection on:
/api/v1/user/...private surfacesRepresentative self-route regression coverage now includes:
Generated by a coding agent with Codex 5.2