mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-03 00:23:41 +02:00
Backport #38074 ## Summary Fixes #38062. Private repositories with a code unit configured for **anonymous read access** (Settings → Public Access → Code: anonymous view) could not be cloned without credentials. The git HTTP auth gate (`httpBase`) only bypassed authentication for non-private repos, ignoring the per-unit anonymous access setting entirely. - Check anonymous permissions via `access_model.GetDoerRepoPermission(ctx, repo, nil)` + `CanAccess` before requiring auth on pull operations, so the per-unit `AnonymousAccessMode` is respected through the existing permission model - This also correctly handles `setting.Repository.ForcePrivate` (which the naive direct-field check would have missed) - Push (receive-pack) and `RequireSignInViewStrict` continue to require credentials as before Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -10,7 +10,9 @@ import (
|
||||
"testing"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
@@ -26,6 +28,8 @@ func TestGitSmartHTTP(t *testing.T) {
|
||||
testGitSmartHTTPTokenScopes(t)
|
||||
testRenamedRepoRedirect(t)
|
||||
testGitArchiveRemote(t, u)
|
||||
t.Run("AnonymousAccess-Repo", func(t *testing.T) { testGitSmartHTTPPrivateRepoAnonymousAccess(t, false) })
|
||||
t.Run("AnonymousAccess-Wiki", func(t *testing.T) { testGitSmartHTTPPrivateRepoAnonymousAccess(t, true) })
|
||||
})
|
||||
}
|
||||
|
||||
@@ -144,3 +148,33 @@ func testGitArchiveRemote(t *testing.T, u *url.URL) {
|
||||
t.Run("Fetch HEAD archive subpath", doGitRemoteArchive(u.String(), "HEAD", "test"))
|
||||
t.Run("list compression options", doGitRemoteArchive(u.String(), "--list"))
|
||||
}
|
||||
|
||||
// testGitSmartHTTPPrivateRepoAnonymousAccess tests that a private repo with
|
||||
// anonymous code access enabled can be cloned without credentials.
|
||||
func testGitSmartHTTPPrivateRepoAnonymousAccess(t *testing.T, isWiki bool) {
|
||||
// repo1 (ID=1) belongs to user2 and is public by default in fixtures
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, OwnerName: "user2", Name: "repo1"})
|
||||
unitType := util.Iif(isWiki, unit.TypeWiki, unit.TypeCode)
|
||||
repoLink := "/" + repo.FullName() + util.Iif(isWiki, ".wiki", "")
|
||||
gitPullPath := repoLink + "/info/refs?service=git-upload-pack"
|
||||
gitPushPath := repoLink + "/info/refs?service=git-receive-pack"
|
||||
|
||||
// make the repo private
|
||||
require.NoError(t, repo_model.UpdateRepositoryColsNoAutoTime(t.Context(), &repo_model.Repository{ID: repo.ID, IsPrivate: true}, "is_private"))
|
||||
|
||||
// without anonymous access: anonymous pull must require auth
|
||||
MakeRequest(t, NewRequest(t, "GET", gitPullPath), http.StatusUnauthorized)
|
||||
|
||||
// enable anonymous read access on the unit
|
||||
require.NoError(t, repo_model.UpdateRepoUnitPublicAccess(t.Context(), &repo_model.RepoUnit{RepoID: repo.ID, Type: unitType, AnonymousAccessMode: perm.AccessModeRead}))
|
||||
|
||||
// with anonymous code access: anonymous pull must succeed without credentials
|
||||
MakeRequest(t, NewRequest(t, "GET", gitPullPath), http.StatusOK)
|
||||
|
||||
// push (receive-pack) must still require auth even with anonymous code access
|
||||
MakeRequest(t, NewRequest(t, "GET", gitPushPath), http.StatusUnauthorized)
|
||||
|
||||
// RequireSignInViewStrict must override anonymous access
|
||||
defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)()
|
||||
MakeRequest(t, NewRequest(t, "GET", gitPullPath), http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ RUN_MODE = prod
|
||||
|
||||
[database]
|
||||
DB_TYPE = sqlite3
|
||||
PATH = gitea.db
|
||||
PATH = gitea-test.db
|
||||
|
||||
[indexer]
|
||||
REPO_INDEXER_ENABLED = true
|
||||
|
||||
Reference in New Issue
Block a user