Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* 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)
  • Loading branch information
zjjhot committed Nov 11, 2024
2 parents 6e76bb8 + 43c252d commit 40a30db
Show file tree
Hide file tree
Showing 35 changed files with 704 additions and 883 deletions.
8 changes: 8 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,14 @@ LEVEL = Info
;; The set of allowed values and rules are the same as DEFAULT_REPO_UNITS.
;DEFAULT_FORK_REPO_UNITS = repo.code,repo.pulls
;;
;; Comma separated list of default mirror repo units.
;; The set of allowed values and rules are the same as DEFAULT_REPO_UNITS.
;DEFAULT_MIRROR_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.wiki,repo.projects,repo.packages
;;
;; Comma separated list of default template repo units.
;; The set of allowed values and rules are the same as DEFAULT_REPO_UNITS.
;DEFAULT_TEMPLATE_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages
;;
;; Prefix archive files by placing them in a directory named after the repository
;PREFIX_ARCHIVE_FILES = true
;;
Expand Down
18 changes: 13 additions & 5 deletions models/organization/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,9 @@ func (org *Organization) LoadTeams(ctx context.Context) ([]*Team, error) {
}

// GetMembers returns all members of organization.
func (org *Organization) GetMembers(ctx context.Context) (user_model.UserList, map[int64]bool, error) {
func (org *Organization) GetMembers(ctx context.Context, doer *user_model.User) (user_model.UserList, map[int64]bool, error) {
return FindOrgMembers(ctx, &FindOrgMembersOpts{
Doer: doer,
OrgID: org.ID,
})
}
Expand Down Expand Up @@ -195,16 +196,22 @@ func (org *Organization) CanCreateRepo() bool {
// FindOrgMembersOpts represensts find org members conditions
type FindOrgMembersOpts struct {
db.ListOptions
OrgID int64
PublicOnly bool
Doer *user_model.User
IsDoerMember bool
OrgID int64
}

func (opts FindOrgMembersOpts) PublicOnly() bool {
return opts.Doer == nil || !(opts.IsDoerMember || opts.Doer.IsAdmin)
}

// CountOrgMembers counts the organization's members
func CountOrgMembers(ctx context.Context, opts *FindOrgMembersOpts) (int64, error) {
sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID)
if opts.PublicOnly {
if opts.PublicOnly() {
sess.And("is_public = ?", true)
}

return sess.Count(new(OrgUser))
}

Expand Down Expand Up @@ -525,9 +532,10 @@ func GetOrgsCanCreateRepoByUserID(ctx context.Context, userID int64) ([]*Organiz
// GetOrgUsersByOrgID returns all organization-user relations by organization ID.
func GetOrgUsersByOrgID(ctx context.Context, opts *FindOrgMembersOpts) ([]*OrgUser, error) {
sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID)
if opts.PublicOnly {
if opts.PublicOnly() {
sess.And("is_public = ?", true)
}

if opts.ListOptions.PageSize > 0 {
sess = db.SetSessionPagination(sess, opts)

Expand Down
58 changes: 32 additions & 26 deletions models/organization/org_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package organization_test

import (
"sort"
"testing"

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

orgUsers, err := organization.GetOrgUsersByOrgID(db.DefaultContext, &organization.FindOrgMembersOpts{
ListOptions: db.ListOptions{},
OrgID: 3,
PublicOnly: false,
opts := &organization.FindOrgMembersOpts{
Doer: &user_model.User{IsAdmin: true},
OrgID: 3,
}
assert.False(t, opts.PublicOnly())
orgUsers, err := organization.GetOrgUsersByOrgID(db.DefaultContext, opts)
assert.NoError(t, err)
sort.Slice(orgUsers, func(i, j int) bool {
return orgUsers[i].ID < orgUsers[j].ID
})
assert.EqualValues(t, []*organization.OrgUser{{
ID: 1,
OrgID: 3,
UID: 2,
IsPublic: true,
}, {
ID: 2,
OrgID: 3,
UID: 4,
IsPublic: false,
}, {
ID: 9,
OrgID: 3,
UID: 28,
IsPublic: true,
}}, orgUsers)

opts = &organization.FindOrgMembersOpts{OrgID: 3}
assert.True(t, opts.PublicOnly())
orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, opts)
assert.NoError(t, err)
if assert.Len(t, orgUsers, 3) {
assert.Equal(t, organization.OrgUser{
ID: orgUsers[0].ID,
OrgID: 3,
UID: 2,
IsPublic: true,
}, *orgUsers[0])
assert.Equal(t, organization.OrgUser{
ID: orgUsers[1].ID,
OrgID: 3,
UID: 4,
IsPublic: false,
}, *orgUsers[1])
assert.Equal(t, organization.OrgUser{
ID: orgUsers[2].ID,
OrgID: 3,
UID: 28,
IsPublic: true,
}, *orgUsers[2])
}
assert.Len(t, orgUsers, 2)

orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, &organization.FindOrgMembersOpts{
ListOptions: db.ListOptions{},
OrgID: unittest.NonexistentID,
PublicOnly: false,
})
assert.NoError(t, err)
assert.Len(t, orgUsers, 0)
Expand Down
4 changes: 2 additions & 2 deletions models/organization/org_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func TestUserListIsPublicMember(t *testing.T) {
func testUserListIsPublicMember(t *testing.T, orgID int64, expected map[int64]bool) {
org, err := organization.GetOrgByID(db.DefaultContext, orgID)
assert.NoError(t, err)
_, membersIsPublic, err := org.GetMembers(db.DefaultContext)
_, membersIsPublic, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
assert.NoError(t, err)
assert.Equal(t, expected, membersIsPublic)
}
Expand All @@ -121,7 +121,7 @@ func TestUserListIsUserOrgOwner(t *testing.T) {
func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bool) {
org, err := organization.GetOrgByID(db.DefaultContext, orgID)
assert.NoError(t, err)
members, _, err := org.GetMembers(db.DefaultContext)
members, _, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
assert.NoError(t, err)
assert.Equal(t, expected, organization.IsUserOrgOwner(db.DefaultContext, members, orgID))
}
Expand Down
40 changes: 40 additions & 0 deletions models/unit/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,27 @@ var (
TypePullRequests,
}

// DefaultMirrorRepoUnits contains the default unit types for mirrors
DefaultMirrorRepoUnits = []Type{
TypeCode,
TypeIssues,
TypeReleases,
TypeWiki,
TypeProjects,
TypePackages,
}

// DefaultTemplateRepoUnits contains the default unit types for templates
DefaultTemplateRepoUnits = []Type{
TypeCode,
TypeIssues,
TypePullRequests,
TypeReleases,
TypeWiki,
TypeProjects,
TypePackages,
}

// NotAllowedDefaultRepoUnits contains units that can't be default
NotAllowedDefaultRepoUnits = []Type{
TypeExternalWiki,
Expand Down Expand Up @@ -147,6 +168,7 @@ func LoadUnitConfig() error {
if len(DefaultRepoUnits) == 0 {
return errors.New("no default repository units found")
}
// default fork repo units
setDefaultForkRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultForkRepoUnits...)
if len(invalidKeys) > 0 {
log.Warn("Invalid keys in default fork repo units: %s", strings.Join(invalidKeys, ", "))
Expand All @@ -155,6 +177,24 @@ func LoadUnitConfig() error {
if len(DefaultForkRepoUnits) == 0 {
return errors.New("no default fork repository units found")
}
// default mirror repo units
setDefaultMirrorRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultMirrorRepoUnits...)
if len(invalidKeys) > 0 {
log.Warn("Invalid keys in default mirror repo units: %s", strings.Join(invalidKeys, ", "))
}
DefaultMirrorRepoUnits = validateDefaultRepoUnits(DefaultMirrorRepoUnits, setDefaultMirrorRepoUnits)
if len(DefaultMirrorRepoUnits) == 0 {
return errors.New("no default mirror repository units found")
}
// default template repo units
setDefaultTemplateRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultTemplateRepoUnits...)
if len(invalidKeys) > 0 {
log.Warn("Invalid keys in default template repo units: %s", strings.Join(invalidKeys, ", "))
}
DefaultTemplateRepoUnits = validateDefaultRepoUnits(DefaultTemplateRepoUnits, setDefaultTemplateRepoUnits)
if len(DefaultTemplateRepoUnits) == 0 {
return errors.New("no default template repository units found")
}
return nil
}

Expand Down
3 changes: 3 additions & 0 deletions modules/base/tool.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ func StringsToInt64s(strs []string) ([]int64, error) {
}
ints := make([]int64, 0, len(strs))
for _, s := range strs {
if s == "" {
continue
}
n, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions modules/base/tool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func TestStringsToInt64s(t *testing.T) {
}
testSuccess(nil, nil)
testSuccess([]string{}, []int64{})
testSuccess([]string{""}, []int64{})
testSuccess([]string{"-1234"}, []int64{-1234})
testSuccess([]string{"1", "4", "16", "64", "256"}, []int64{1, 4, 16, 64, 256})

Expand Down
4 changes: 2 additions & 2 deletions modules/container/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ func (s Set[T]) AddMultiple(values ...T) {
}
}

// Contains determines whether a set contains the specified elements.
// Returns true if the set contains the specified element; otherwise, false.
// Contains determines whether a set contains all these elements.
// Returns true if the set contains all these elements; otherwise, false.
func (s Set[T]) Contains(values ...T) bool {
ret := true
for _, value := range values {
Expand Down
2 changes: 2 additions & 0 deletions modules/container/set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ func TestSet(t *testing.T) {

assert.True(t, s.Contains("key1"))
assert.True(t, s.Contains("key2"))
assert.True(t, s.Contains("key1", "key2"))
assert.False(t, s.Contains("key3"))
assert.False(t, s.Contains("key1", "key3"))

assert.True(t, s.Remove("key2"))
assert.False(t, s.Contains("key2"))
Expand Down
4 changes: 4 additions & 0 deletions modules/setting/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ var (
DisabledRepoUnits []string
DefaultRepoUnits []string
DefaultForkRepoUnits []string
DefaultMirrorRepoUnits []string
DefaultTemplateRepoUnits []string
PrefixArchiveFiles bool
DisableMigrations bool
DisableStars bool `ini:"DISABLE_STARS"`
Expand Down Expand Up @@ -161,6 +163,8 @@ var (
DisabledRepoUnits: []string{},
DefaultRepoUnits: []string{},
DefaultForkRepoUnits: []string{},
DefaultMirrorRepoUnits: []string{},
DefaultTemplateRepoUnits: []string{},
PrefixArchiveFiles: true,
DisableMigrations: false,
DisableStars: false,
Expand Down
1 change: 1 addition & 0 deletions modules/templates/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func NewFuncMap() template.FuncMap {
"ctx": func() any { return nil }, // template context function

"DumpVar": dumpVar,
"NIL": func() any { return nil },

// -----------------------------------------------------------------
// html/template related functions
Expand Down
22 changes: 13 additions & 9 deletions routers/api/v1/org/member.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import (
)

// listMembers list an organization's members
func listMembers(ctx *context.APIContext, publicOnly bool) {
func listMembers(ctx *context.APIContext, isMember bool) {
opts := &organization.FindOrgMembersOpts{
OrgID: ctx.Org.Organization.ID,
PublicOnly: publicOnly,
ListOptions: utils.GetListOptions(ctx),
Doer: ctx.Doer,
IsDoerMember: isMember,
OrgID: ctx.Org.Organization.ID,
ListOptions: utils.GetListOptions(ctx),
}

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

publicOnly := true
var (
isMember bool
err error
)

if ctx.Doer != nil {
isMember, err := ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID)
isMember, err = ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "IsOrgMember", err)
return
}
publicOnly = !isMember && !ctx.Doer.IsAdmin
}
listMembers(ctx, publicOnly)
listMembers(ctx, isMember)
}

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

listMembers(ctx, true)
listMembers(ctx, false)
}

// IsMember check if a user is a member of an organization
Expand Down
8 changes: 5 additions & 3 deletions routers/web/org/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ func home(ctx *context.Context, viewRepositories bool) {
}

opts := &organization.FindOrgMembersOpts{
OrgID: org.ID,
PublicOnly: ctx.Org.PublicMemberOnly,
ListOptions: db.ListOptions{Page: 1, PageSize: 25},
Doer: ctx.Doer,
OrgID: org.ID,
IsDoerMember: ctx.Org.IsMember,
ListOptions: db.ListOptions{Page: 1, PageSize: 25},
}

members, _, err := organization.FindOrgMembers(ctx, opts)
if err != nil {
ctx.ServerError("FindOrgMembers", err)
Expand Down
8 changes: 4 additions & 4 deletions routers/web/org/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ func Members(ctx *context.Context) {
}

opts := &organization.FindOrgMembersOpts{
OrgID: org.ID,
PublicOnly: true,
Doer: ctx.Doer,
OrgID: org.ID,
}

if ctx.Doer != nil {
Expand All @@ -44,9 +44,9 @@ func Members(ctx *context.Context) {
ctx.Error(http.StatusInternalServerError, "IsOrgMember")
return
}
opts.PublicOnly = !isMember && !ctx.Doer.IsAdmin
opts.IsDoerMember = isMember
}
ctx.Data["PublicOnly"] = opts.PublicOnly
ctx.Data["PublicOnly"] = opts.PublicOnly()

total, err := organization.CountOrgMembers(ctx, opts)
if err != nil {
Expand Down
Loading

0 comments on commit 40a30db

Please sign in to comment.