Skip to content

Commit 40a30db

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Calculate `PublicOnly` for org membership only once (go-gitea#32234) Add `DEFAULT_MIRROR_REPO_UNITS` and `DEFAULT_TEMPLATE_REPO_UNITS` options (go-gitea#32416) Add a doctor check to disable the "Actions" unit for mirrors (go-gitea#32424) Refactor sidebar assignee&milestone&project selectors (go-gitea#32465)
2 parents 6e76bb8 + 43c252d commit 40a30db

35 files changed

+704
-883
lines changed

custom/conf/app.example.ini

+8
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,14 @@ LEVEL = Info
10071007
;; The set of allowed values and rules are the same as DEFAULT_REPO_UNITS.
10081008
;DEFAULT_FORK_REPO_UNITS = repo.code,repo.pulls
10091009
;;
1010+
;; Comma separated list of default mirror repo units.
1011+
;; The set of allowed values and rules are the same as DEFAULT_REPO_UNITS.
1012+
;DEFAULT_MIRROR_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.wiki,repo.projects,repo.packages
1013+
;;
1014+
;; Comma separated list of default template repo units.
1015+
;; The set of allowed values and rules are the same as DEFAULT_REPO_UNITS.
1016+
;DEFAULT_TEMPLATE_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages
1017+
;;
10101018
;; Prefix archive files by placing them in a directory named after the repository
10111019
;PREFIX_ARCHIVE_FILES = true
10121020
;;

models/organization/org.go

+13-5
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

+32-26
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

+2-2
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
}

models/unit/unit.go

+40
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,27 @@ var (
8080
TypePullRequests,
8181
}
8282

83+
// DefaultMirrorRepoUnits contains the default unit types for mirrors
84+
DefaultMirrorRepoUnits = []Type{
85+
TypeCode,
86+
TypeIssues,
87+
TypeReleases,
88+
TypeWiki,
89+
TypeProjects,
90+
TypePackages,
91+
}
92+
93+
// DefaultTemplateRepoUnits contains the default unit types for templates
94+
DefaultTemplateRepoUnits = []Type{
95+
TypeCode,
96+
TypeIssues,
97+
TypePullRequests,
98+
TypeReleases,
99+
TypeWiki,
100+
TypeProjects,
101+
TypePackages,
102+
}
103+
83104
// NotAllowedDefaultRepoUnits contains units that can't be default
84105
NotAllowedDefaultRepoUnits = []Type{
85106
TypeExternalWiki,
@@ -147,6 +168,7 @@ func LoadUnitConfig() error {
147168
if len(DefaultRepoUnits) == 0 {
148169
return errors.New("no default repository units found")
149170
}
171+
// default fork repo units
150172
setDefaultForkRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultForkRepoUnits...)
151173
if len(invalidKeys) > 0 {
152174
log.Warn("Invalid keys in default fork repo units: %s", strings.Join(invalidKeys, ", "))
@@ -155,6 +177,24 @@ func LoadUnitConfig() error {
155177
if len(DefaultForkRepoUnits) == 0 {
156178
return errors.New("no default fork repository units found")
157179
}
180+
// default mirror repo units
181+
setDefaultMirrorRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultMirrorRepoUnits...)
182+
if len(invalidKeys) > 0 {
183+
log.Warn("Invalid keys in default mirror repo units: %s", strings.Join(invalidKeys, ", "))
184+
}
185+
DefaultMirrorRepoUnits = validateDefaultRepoUnits(DefaultMirrorRepoUnits, setDefaultMirrorRepoUnits)
186+
if len(DefaultMirrorRepoUnits) == 0 {
187+
return errors.New("no default mirror repository units found")
188+
}
189+
// default template repo units
190+
setDefaultTemplateRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultTemplateRepoUnits...)
191+
if len(invalidKeys) > 0 {
192+
log.Warn("Invalid keys in default template repo units: %s", strings.Join(invalidKeys, ", "))
193+
}
194+
DefaultTemplateRepoUnits = validateDefaultRepoUnits(DefaultTemplateRepoUnits, setDefaultTemplateRepoUnits)
195+
if len(DefaultTemplateRepoUnits) == 0 {
196+
return errors.New("no default template repository units found")
197+
}
158198
return nil
159199
}
160200

modules/base/tool.go

+3
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ func StringsToInt64s(strs []string) ([]int64, error) {
147147
}
148148
ints := make([]int64, 0, len(strs))
149149
for _, s := range strs {
150+
if s == "" {
151+
continue
152+
}
150153
n, err := strconv.ParseInt(s, 10, 64)
151154
if err != nil {
152155
return nil, err

modules/base/tool_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ func TestStringsToInt64s(t *testing.T) {
152152
}
153153
testSuccess(nil, nil)
154154
testSuccess([]string{}, []int64{})
155+
testSuccess([]string{""}, []int64{})
155156
testSuccess([]string{"-1234"}, []int64{-1234})
156157
testSuccess([]string{"1", "4", "16", "64", "256"}, []int64{1, 4, 16, 64, 256})
157158

modules/container/set.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ func (s Set[T]) AddMultiple(values ...T) {
3131
}
3232
}
3333

34-
// Contains determines whether a set contains the specified elements.
35-
// Returns true if the set contains the specified element; otherwise, false.
34+
// Contains determines whether a set contains all these elements.
35+
// Returns true if the set contains all these elements; otherwise, false.
3636
func (s Set[T]) Contains(values ...T) bool {
3737
ret := true
3838
for _, value := range values {

modules/container/set_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ func TestSet(t *testing.T) {
1818

1919
assert.True(t, s.Contains("key1"))
2020
assert.True(t, s.Contains("key2"))
21+
assert.True(t, s.Contains("key1", "key2"))
2122
assert.False(t, s.Contains("key3"))
23+
assert.False(t, s.Contains("key1", "key3"))
2224

2325
assert.True(t, s.Remove("key2"))
2426
assert.False(t, s.Contains("key2"))

modules/setting/repository.go

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ var (
4343
DisabledRepoUnits []string
4444
DefaultRepoUnits []string
4545
DefaultForkRepoUnits []string
46+
DefaultMirrorRepoUnits []string
47+
DefaultTemplateRepoUnits []string
4648
PrefixArchiveFiles bool
4749
DisableMigrations bool
4850
DisableStars bool `ini:"DISABLE_STARS"`
@@ -161,6 +163,8 @@ var (
161163
DisabledRepoUnits: []string{},
162164
DefaultRepoUnits: []string{},
163165
DefaultForkRepoUnits: []string{},
166+
DefaultMirrorRepoUnits: []string{},
167+
DefaultTemplateRepoUnits: []string{},
164168
PrefixArchiveFiles: true,
165169
DisableMigrations: false,
166170
DisableStars: false,

modules/templates/helper.go

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func NewFuncMap() template.FuncMap {
3131
"ctx": func() any { return nil }, // template context function
3232

3333
"DumpVar": dumpVar,
34+
"NIL": func() any { return nil },
3435

3536
// -----------------------------------------------------------------
3637
// html/template related functions

routers/api/v1/org/member.go

+13-9
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

+5-3
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

+4-4
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 {

0 commit comments

Comments
 (0)