From 96c651382f9ddb53c6bd477c3b500ec5d100fea1 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 18 Aug 2026 16:16:14 +0800 Subject: [PATCH] fix: grant limited-org unit read access to authenticated non-members (#38871) (#38963) backport #38871 Co-authored-by: silverwind --- models/organization/org.go | 16 +++++++++------- models/organization/org_test.go | 9 +++++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/models/organization/org.go b/models/organization/org.go index deb7d54b79c..260aaa9c997 100644 --- a/models/organization/org.go +++ b/models/organization/org.go @@ -303,7 +303,7 @@ func (org *Organization) UnitPermission(ctx context.Context, doer *user_model.Us } } - if org.Visibility.IsPublic() { + if ownerVisibilitySatisfiesDoer(org.AsUser(), doer) { return perm.AccessModeRead } @@ -445,8 +445,7 @@ func GetUsersWhoCanCreateOrgRepo(ctx context.Context, orgID int64) (map[int64]*u And("team_user.org_id = ?", orgID).Find(&users) } -// HasOrgOrUserVisible tells if the given user can see the given org or user -func HasOrgOrUserVisible(ctx context.Context, orgOrUser, user *user_model.User) bool { +func ownerVisibilitySatisfiesDoer(orgOrUser, user *user_model.User) bool { // If user is nil, it's an anonymous user/request. // The Ghost user is handled like an anonymous user. if user == nil || user.IsGhost() { @@ -461,10 +460,13 @@ func HasOrgOrUserVisible(ctx context.Context, orgOrUser, user *user_model.User) return true } - if (orgOrUser.Visibility == structs.VisibleTypePrivate || user.IsRestricted) && !OrgFromUser(orgOrUser).hasMemberWithUserID(ctx, user.ID) { - return false - } - return true + return orgOrUser.Visibility != structs.VisibleTypePrivate && !user.IsRestricted +} + +// HasOrgOrUserVisible tells if the given user can see the given org or user +func HasOrgOrUserVisible(ctx context.Context, owner, doer *user_model.User) bool { + return ownerVisibilitySatisfiesDoer(owner, doer) || + (doer != nil && OrgFromUser(owner).HasMemberWithUserID(ctx, doer.ID)) } // HasOrgsVisible tells if the given user can see at least one of the orgs provided diff --git a/models/organization/org_test.go b/models/organization/org_test.go index e24de5b054b..d359f84b9c1 100644 --- a/models/organization/org_test.go +++ b/models/organization/org_test.go @@ -10,7 +10,9 @@ import ( "gitea.dev/models/db" "gitea.dev/models/organization" + "gitea.dev/models/perm" repo_model "gitea.dev/models/repo" + "gitea.dev/models/unit" "gitea.dev/models/unittest" user_model "gitea.dev/models/user" "gitea.dev/modules/setting" @@ -626,3 +628,10 @@ func TestCreateOrganization4(t *testing.T) { assert.True(t, db.IsErrNameReserved(err)) unittest.CheckConsistencyFor(t, &organization.Organization{}, &organization.Team{}) } + +func TestOrAnyRepoUnitPermission(t *testing.T) { + defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)() + org := organization.Organization{Visibility: structs.VisibleTypeLimited} + assert.Equal(t, perm.AccessModeNone, org.UnitPermission(t.Context(), nil, unit.TypeWiki)) + assert.Equal(t, perm.AccessModeRead, org.UnitPermission(t.Context(), &user_model.User{}, unit.TypeWiki)) +}