Skip to content

Commit 43c252d

Browse files
authored
Calculate PublicOnly for org membership only once (#32234)
Refactoring of #32211 this move the PublicOnly() filter calcuation next to the DB querys and let it be decided by the Doer --- *Sponsored by Kithara Software GmbH*
1 parent b1f42a0 commit 43c252d

File tree

7 files changed

+72
-53
lines changed

7 files changed

+72
-53
lines changed

models/organization/org.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,9 @@ func (org *Organization) LoadTeams(ctx context.Context) ([]*Team, error) {
141141
}
142142

143143
// GetMembers returns all members of organization.
144-
func (org *Organization) GetMembers(ctx context.Context) (user_model.UserList, map[int64]bool, error) {
144+
func (org *Organization) GetMembers(ctx context.Context, doer *user_model.User) (user_model.UserList, map[int64]bool, error) {
145145
return FindOrgMembers(ctx, &FindOrgMembersOpts{
146+
Doer: doer,
146147
OrgID: org.ID,
147148
})
148149
}
@@ -195,16 +196,22 @@ func (org *Organization) CanCreateRepo() bool {
195196
// FindOrgMembersOpts represensts find org members conditions
196197
type FindOrgMembersOpts struct {
197198
db.ListOptions
198-
OrgID int64
199-
PublicOnly bool
199+
Doer *user_model.User
200+
IsDoerMember bool
201+
OrgID int64
202+
}
203+
204+
func (opts FindOrgMembersOpts) PublicOnly() bool {
205+
return opts.Doer == nil || !(opts.IsDoerMember || opts.Doer.IsAdmin)
200206
}
201207

202208
// CountOrgMembers counts the organization's members
203209
func CountOrgMembers(ctx context.Context, opts *FindOrgMembersOpts) (int64, error) {
204210
sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID)
205-
if opts.PublicOnly {
211+
if opts.PublicOnly() {
206212
sess.And("is_public = ?", true)
207213
}
214+
208215
return sess.Count(new(OrgUser))
209216
}
210217

@@ -525,9 +532,10 @@ func GetOrgsCanCreateRepoByUserID(ctx context.Context, userID int64) ([]*Organiz
525532
// GetOrgUsersByOrgID returns all organization-user relations by organization ID.
526533
func GetOrgUsersByOrgID(ctx context.Context, opts *FindOrgMembersOpts) ([]*OrgUser, error) {
527534
sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID)
528-
if opts.PublicOnly {
535+
if opts.PublicOnly() {
529536
sess.And("is_public = ?", true)
530537
}
538+
531539
if opts.ListOptions.PageSize > 0 {
532540
sess = db.SetSessionPagination(sess, opts)
533541

models/organization/org_test.go

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package organization_test
55

66
import (
7+
"sort"
78
"testing"
89

910
"code.gitea.io/gitea/models/db"
@@ -103,7 +104,7 @@ func TestUser_GetTeams(t *testing.T) {
103104
func TestUser_GetMembers(t *testing.T) {
104105
assert.NoError(t, unittest.PrepareTestDatabase())
105106
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
106-
members, _, err := org.GetMembers(db.DefaultContext)
107+
members, _, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
107108
assert.NoError(t, err)
108109
if assert.Len(t, members, 3) {
109110
assert.Equal(t, int64(2), members[0].ID)
@@ -210,37 +211,42 @@ func TestFindOrgs(t *testing.T) {
210211
func TestGetOrgUsersByOrgID(t *testing.T) {
211212
assert.NoError(t, unittest.PrepareTestDatabase())
212213

213-
orgUsers, err := organization.GetOrgUsersByOrgID(db.DefaultContext, &organization.FindOrgMembersOpts{
214-
ListOptions: db.ListOptions{},
215-
OrgID: 3,
216-
PublicOnly: false,
214+
opts := &organization.FindOrgMembersOpts{
215+
Doer: &user_model.User{IsAdmin: true},
216+
OrgID: 3,
217+
}
218+
assert.False(t, opts.PublicOnly())
219+
orgUsers, err := organization.GetOrgUsersByOrgID(db.DefaultContext, opts)
220+
assert.NoError(t, err)
221+
sort.Slice(orgUsers, func(i, j int) bool {
222+
return orgUsers[i].ID < orgUsers[j].ID
217223
})
224+
assert.EqualValues(t, []*organization.OrgUser{{
225+
ID: 1,
226+
OrgID: 3,
227+
UID: 2,
228+
IsPublic: true,
229+
}, {
230+
ID: 2,
231+
OrgID: 3,
232+
UID: 4,
233+
IsPublic: false,
234+
}, {
235+
ID: 9,
236+
OrgID: 3,
237+
UID: 28,
238+
IsPublic: true,
239+
}}, orgUsers)
240+
241+
opts = &organization.FindOrgMembersOpts{OrgID: 3}
242+
assert.True(t, opts.PublicOnly())
243+
orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, opts)
218244
assert.NoError(t, err)
219-
if assert.Len(t, orgUsers, 3) {
220-
assert.Equal(t, organization.OrgUser{
221-
ID: orgUsers[0].ID,
222-
OrgID: 3,
223-
UID: 2,
224-
IsPublic: true,
225-
}, *orgUsers[0])
226-
assert.Equal(t, organization.OrgUser{
227-
ID: orgUsers[1].ID,
228-
OrgID: 3,
229-
UID: 4,
230-
IsPublic: false,
231-
}, *orgUsers[1])
232-
assert.Equal(t, organization.OrgUser{
233-
ID: orgUsers[2].ID,
234-
OrgID: 3,
235-
UID: 28,
236-
IsPublic: true,
237-
}, *orgUsers[2])
238-
}
245+
assert.Len(t, orgUsers, 2)
239246

240247
orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, &organization.FindOrgMembersOpts{
241248
ListOptions: db.ListOptions{},
242249
OrgID: unittest.NonexistentID,
243-
PublicOnly: false,
244250
})
245251
assert.NoError(t, err)
246252
assert.Len(t, orgUsers, 0)

models/organization/org_user_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func TestUserListIsPublicMember(t *testing.T) {
9494
func testUserListIsPublicMember(t *testing.T, orgID int64, expected map[int64]bool) {
9595
org, err := organization.GetOrgByID(db.DefaultContext, orgID)
9696
assert.NoError(t, err)
97-
_, membersIsPublic, err := org.GetMembers(db.DefaultContext)
97+
_, membersIsPublic, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
9898
assert.NoError(t, err)
9999
assert.Equal(t, expected, membersIsPublic)
100100
}
@@ -121,7 +121,7 @@ func TestUserListIsUserOrgOwner(t *testing.T) {
121121
func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bool) {
122122
org, err := organization.GetOrgByID(db.DefaultContext, orgID)
123123
assert.NoError(t, err)
124-
members, _, err := org.GetMembers(db.DefaultContext)
124+
members, _, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
125125
assert.NoError(t, err)
126126
assert.Equal(t, expected, organization.IsUserOrgOwner(db.DefaultContext, members, orgID))
127127
}

routers/api/v1/org/member.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ import (
1818
)
1919

2020
// listMembers list an organization's members
21-
func listMembers(ctx *context.APIContext, publicOnly bool) {
21+
func listMembers(ctx *context.APIContext, isMember bool) {
2222
opts := &organization.FindOrgMembersOpts{
23-
OrgID: ctx.Org.Organization.ID,
24-
PublicOnly: publicOnly,
25-
ListOptions: utils.GetListOptions(ctx),
23+
Doer: ctx.Doer,
24+
IsDoerMember: isMember,
25+
OrgID: ctx.Org.Organization.ID,
26+
ListOptions: utils.GetListOptions(ctx),
2627
}
2728

2829
count, err := organization.CountOrgMembers(ctx, opts)
@@ -73,16 +74,19 @@ func ListMembers(ctx *context.APIContext) {
7374
// "404":
7475
// "$ref": "#/responses/notFound"
7576

76-
publicOnly := true
77+
var (
78+
isMember bool
79+
err error
80+
)
81+
7782
if ctx.Doer != nil {
78-
isMember, err := ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID)
83+
isMember, err = ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID)
7984
if err != nil {
8085
ctx.Error(http.StatusInternalServerError, "IsOrgMember", err)
8186
return
8287
}
83-
publicOnly = !isMember && !ctx.Doer.IsAdmin
8488
}
85-
listMembers(ctx, publicOnly)
89+
listMembers(ctx, isMember)
8690
}
8791

8892
// ListPublicMembers list an organization's public members
@@ -112,7 +116,7 @@ func ListPublicMembers(ctx *context.APIContext) {
112116
// "404":
113117
// "$ref": "#/responses/notFound"
114118

115-
listMembers(ctx, true)
119+
listMembers(ctx, false)
116120
}
117121

118122
// IsMember check if a user is a member of an organization

routers/web/org/home.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,12 @@ func home(ctx *context.Context, viewRepositories bool) {
9595
}
9696

9797
opts := &organization.FindOrgMembersOpts{
98-
OrgID: org.ID,
99-
PublicOnly: ctx.Org.PublicMemberOnly,
100-
ListOptions: db.ListOptions{Page: 1, PageSize: 25},
98+
Doer: ctx.Doer,
99+
OrgID: org.ID,
100+
IsDoerMember: ctx.Org.IsMember,
101+
ListOptions: db.ListOptions{Page: 1, PageSize: 25},
101102
}
103+
102104
members, _, err := organization.FindOrgMembers(ctx, opts)
103105
if err != nil {
104106
ctx.ServerError("FindOrgMembers", err)

routers/web/org/members.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ func Members(ctx *context.Context) {
3434
}
3535

3636
opts := &organization.FindOrgMembersOpts{
37-
OrgID: org.ID,
38-
PublicOnly: true,
37+
Doer: ctx.Doer,
38+
OrgID: org.ID,
3939
}
4040

4141
if ctx.Doer != nil {
@@ -44,9 +44,9 @@ func Members(ctx *context.Context) {
4444
ctx.Error(http.StatusInternalServerError, "IsOrgMember")
4545
return
4646
}
47-
opts.PublicOnly = !isMember && !ctx.Doer.IsAdmin
47+
opts.IsDoerMember = isMember
4848
}
49-
ctx.Data["PublicOnly"] = opts.PublicOnly
49+
ctx.Data["PublicOnly"] = opts.PublicOnly()
5050

5151
total, err := organization.CountOrgMembers(ctx, opts)
5252
if err != nil {

services/context/org.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ type Organization struct {
2626
Organization *organization.Organization
2727
OrgLink string
2828
CanCreateOrgRepo bool
29-
PublicMemberOnly bool // Only display public members
3029

3130
Team *organization.Team
3231
Teams []*organization.Team
@@ -176,10 +175,10 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
176175
ctx.Data["OrgLink"] = ctx.Org.OrgLink
177176

178177
// Member
179-
ctx.Org.PublicMemberOnly = ctx.Doer == nil || !ctx.Org.IsMember && !ctx.Doer.IsAdmin
180178
opts := &organization.FindOrgMembersOpts{
181-
OrgID: org.ID,
182-
PublicOnly: ctx.Org.PublicMemberOnly,
179+
Doer: ctx.Doer,
180+
OrgID: org.ID,
181+
IsDoerMember: ctx.Org.IsMember,
183182
}
184183
ctx.Data["NumMembers"], err = organization.CountOrgMembers(ctx, opts)
185184
if err != nil {

0 commit comments

Comments
 (0)