From e388822e9dc6bfe59df06c7b2008cba517f908fc Mon Sep 17 00:00:00 2001
From: Kemal Zebari <60799661+kemzeb@users.noreply.github.com>
Date: Fri, 3 May 2024 00:58:31 -0700
Subject: [PATCH] Don't only list code-enabled repositories when using
 repository API (#30817)

We should be listing all repositories by default.

Fixes #28483.

(cherry picked from commit 9f0ef3621a3b63ccbe93f302a446b67dc54ad725)

Conflict:
   -		if ctx.IsSigned && ctx.Doer.IsAdmin || permission.UnitAccessMode(unit_model.TypeCode) >= perm.AccessModeRead {
   +		if ctx.IsSigned && ctx.Doer.IsAdmin || permission.HasAccess() {
   because of https://codeberg.org/forgejo/forgejo/pulls/2001
---
 routers/api/v1/user/repo.go        |  4 +---
 tests/integration/api_repo_test.go | 34 ++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go
index 81f8e0f3fe..9b6701b067 100644
--- a/routers/api/v1/user/repo.go
+++ b/routers/api/v1/user/repo.go
@@ -6,10 +6,8 @@ package user
 import (
 	"net/http"
 
-	"code.gitea.io/gitea/models/perm"
 	access_model "code.gitea.io/gitea/models/perm/access"
 	repo_model "code.gitea.io/gitea/models/repo"
-	unit_model "code.gitea.io/gitea/models/unit"
 	user_model "code.gitea.io/gitea/models/user"
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/routers/api/v1/utils"
@@ -44,7 +42,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) {
 			ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
 			return
 		}
-		if ctx.IsSigned && ctx.Doer.IsAdmin || permission.UnitAccessMode(unit_model.TypeCode) >= perm.AccessModeRead {
+		if ctx.IsSigned && ctx.Doer.IsAdmin || permission.HasAccess() {
 			apiRepos = append(apiRepos, convert.ToRepo(ctx, repos[i], permission))
 		}
 	}
diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go
index 96f38edc86..a503b201bc 100644
--- a/tests/integration/api_repo_test.go
+++ b/tests/integration/api_repo_test.go
@@ -13,6 +13,7 @@ import (
 	"code.gitea.io/gitea/models/db"
 	access_model "code.gitea.io/gitea/models/perm/access"
 	repo_model "code.gitea.io/gitea/models/repo"
+	unit_model "code.gitea.io/gitea/models/unit"
 	"code.gitea.io/gitea/models/unittest"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/setting"
@@ -326,6 +327,39 @@ func TestAPIOrgRepos(t *testing.T) {
 	}
 }
 
+// See issue #28483. Tests to make sure we consider more than just code unit-enabled repositories.
+func TestAPIOrgReposWithCodeUnitDisabled(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo21"})
+	org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo21.OwnerID})
+
+	// Disable code repository unit.
+	var units []unit_model.Type
+	units = append(units, unit_model.TypeCode)
+
+	if err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo21, nil, units); err != nil {
+		assert.Fail(t, "should have been able to delete code repository unit; failed to %v", err)
+	}
+	assert.False(t, repo21.UnitEnabled(db.DefaultContext, unit_model.TypeCode))
+
+	session := loginUser(t, "user2")
+	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization)
+
+	req := NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", org3.Name).
+		AddTokenAuth(token)
+
+	resp := MakeRequest(t, req, http.StatusOK)
+	var apiRepos []*api.Repository
+	DecodeJSON(t, resp, &apiRepos)
+
+	var repoNames []string
+	for _, r := range apiRepos {
+		repoNames = append(repoNames, r.Name)
+	}
+
+	assert.Contains(t, repoNames, repo21.Name)
+}
+
 func TestAPIGetRepoByIDUnauthorized(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
 	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})