From 0403a38217db0893fc2fdcd14076bceaf81d9b76 Mon Sep 17 00:00:00 2001 From: forgejo-backport-action Date: Thu, 16 Apr 2026 21:00:50 +0200 Subject: [PATCH] [v15.0/forgejo] fix: make /repos/search?uid=-2 return zero results, no repos with that owner (#12150) **Backport:** https://codeberg.org/forgejo/forgejo/pulls/12144 API calls to `.../api/v1/repos/search?uid=-2&archived=false` currently do not apply the filter `uid` because of the negative value. This can occur when APIs are interacting with `${{ forgejo.token }}` and believe they're operating as the Forgejo Actions user, which has UID -2. In combination with the security checks that occur in the `/repos/search` API to validate that repositories accessed are visible to the user, this can result in 500 error responses when a more correct expectation would be to receive no repositories: https://codeberg.org/forgejo/forgejo/src/commit/da8898822c528a245a4cbe3e0ca02928262a4d5e/routers/api/v1/repo/repo.go#L237-L242 ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests for Go changes - I added test coverage for Go changes... - [ ] in their respective `*_test.go` for unit tests. - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I ran... - [x] `make pr-go` before pushing ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [x] I did not document these changes and I do not expect someone else to do it. ### Release notes - [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change. - [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change. Co-authored-by: Mathieu Fenniak Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12150 Reviewed-by: Gusted Co-authored-by: forgejo-backport-action Co-committed-by: forgejo-backport-action --- models/repo/repo_list.go | 2 +- tests/integration/api_repo_test.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index daa60c81e9..a0eb0ce7c2 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -361,7 +361,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { } // Restrict repositories to those the OwnerID owns or contributes to as per opts.Collaborate - if opts.OwnerID > 0 { + if opts.OwnerID != 0 { accessCond := builder.NewCond() if !opts.Collaborate.ValueOrZeroValue() { accessCond = builder.Eq{"owner_id": opts.OwnerID} diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index 60c662c28a..29edff7ac0 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -149,6 +149,7 @@ func TestAPISearchRepo(t *testing.T) { org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 18}) user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}) orgUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 17}) + actionsUser := user_model.NewActionsUser() oldAPIDefaultNum := setting.API.DefaultPagingNum defer func() { @@ -266,6 +267,12 @@ func TestAPISearchRepo(t *testing.T) { user: {count: 1, includesPrivate: true}, user4: {count: 1, includesPrivate: true}, }}, + {name: "ForgejoActionsUser/UID", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", actionsUser.ID), expectedResults: expectedResults{ + nil: {count: 0}, + actionsUser: {count: 0}, + user: {count: 0}, + user4: {count: 0}, + }}, } for _, testCase := range testCases {