Skip to content

Commit 3c07d03

Browse files
davidsvantessonlafrikslunnyzeripath
committed
Add setting to set default and global disabled repository units. (#8788)
* Add possibility to global disable repo units. * Add Default Repo Unit app.ini setting. * Hide units * Hide disabled repo units * Minor fixes * Indicate disabled units in team settings. Co-authored-by: Lauris BH <[email protected]> Co-authored-by: Lunny Xiao <[email protected]> Co-authored-by: zeripath <[email protected]>
1 parent 36943e5 commit 3c07d03

File tree

14 files changed

+311
-136
lines changed

14 files changed

+311
-136
lines changed

custom/conf/app.ini.sample

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ DEFAULT_CLOSE_ISSUES_VIA_COMMITS_IN_ANY_BRANCH = false
4242
; Allow users to push local repositories to Gitea and have them automatically created for a user or an org
4343
ENABLE_PUSH_CREATE_USER = false
4444
ENABLE_PUSH_CREATE_ORG = false
45+
; Comma separated list of globally disabled repo units. Allowed values: repo.issues, repo.ext_issues, repo.pulls, repo.wiki, repo.ext_wiki
46+
DISABLED_REPO_UNITS =
47+
; Comma separated list of default repo units. Allowed values: repo.code, repo.releases, repo.issues, repo.pulls, repo.wiki.
48+
; Note: Code and Releases can currently not be deactivated. If you specify default repo units you should still list them for future compatibility.
49+
; External wiki and issue tracker can't be enabled by default as it requires additional settings.
50+
; Disabled repo units will not be added to new repositories regardless if it is in the default list.
51+
DEFAULT_REPO_UNITS = repo.code,repo.releases,repo.issues,repo.pulls,repo.wiki
4552

4653
[repository.editor]
4754
; List of file extensions for which lines should be wrapped in the CodeMirror editor

models/repo.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ func loadRepoConfig() {
128128
// NewRepoContext creates a new repository context
129129
func NewRepoContext() {
130130
loadRepoConfig()
131+
loadUnitConfig()
131132

132133
RemoveAllWithNotice("Clean up repository temporary data", filepath.Join(setting.AppDataPath, "tmp"))
133134
}
@@ -393,6 +394,7 @@ func (repo *Repository) getUnits(e Engine) (err error) {
393394
}
394395

395396
repo.Units, err = getUnitsByRepoID(e, repo.ID)
397+
log.Trace("repo.Units: %-+v", repo.Units)
396398
return err
397399
}
398400

@@ -1442,14 +1444,19 @@ func UpdateRepositoryUpdatedTime(repoID int64, updateTime time.Time) error {
14421444
}
14431445

14441446
// UpdateRepositoryUnits updates a repository's units
1445-
func UpdateRepositoryUnits(repo *Repository, units []RepoUnit) (err error) {
1447+
func UpdateRepositoryUnits(repo *Repository, units []RepoUnit, deleteUnitTypes []UnitType) (err error) {
14461448
sess := x.NewSession()
14471449
defer sess.Close()
14481450
if err = sess.Begin(); err != nil {
14491451
return err
14501452
}
14511453

1452-
if _, err = sess.Where("repo_id = ?", repo.ID).Delete(new(RepoUnit)); err != nil {
1454+
// Delete existing settings of units before adding again
1455+
for _, u := range units {
1456+
deleteUnitTypes = append(deleteUnitTypes, u.Type)
1457+
}
1458+
1459+
if _, err = sess.Where("repo_id = ?", repo.ID).In("type", deleteUnitTypes).Delete(new(RepoUnit)); err != nil {
14531460
return err
14541461
}
14551462

models/repo_unit.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,16 @@ func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
170170
}
171171

172172
func getUnitsByRepoID(e Engine, repoID int64) (units []*RepoUnit, err error) {
173-
return units, e.Where("repo_id = ?", repoID).Find(&units)
173+
var tmpUnits []*RepoUnit
174+
if err := e.Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil {
175+
return nil, err
176+
}
177+
178+
for _, u := range tmpUnits {
179+
if !u.Type.UnitGlobalDisabled() {
180+
units = append(units, u)
181+
}
182+
}
183+
184+
return units, nil
174185
}

models/unit.go

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"strings"
1010

1111
"code.gitea.io/gitea/modules/log"
12+
"code.gitea.io/gitea/modules/setting"
1213
)
1314

1415
// UnitType is Unit's Type
@@ -78,13 +79,89 @@ var (
7879
UnitTypeWiki,
7980
}
8081

82+
// NotAllowedDefaultRepoUnits contains units that can't be default
83+
NotAllowedDefaultRepoUnits = []UnitType{
84+
UnitTypeExternalWiki,
85+
UnitTypeExternalTracker,
86+
}
87+
8188
// MustRepoUnits contains the units could not be disabled currently
8289
MustRepoUnits = []UnitType{
8390
UnitTypeCode,
8491
UnitTypeReleases,
8592
}
93+
94+
// DisabledRepoUnits contains the units that have been globally disabled
95+
DisabledRepoUnits = []UnitType{}
8696
)
8797

98+
func loadUnitConfig() {
99+
setDefaultRepoUnits := FindUnitTypes(setting.Repository.DefaultRepoUnits...)
100+
// Default repo units set if setting is not empty
101+
if len(setDefaultRepoUnits) > 0 {
102+
// MustRepoUnits required as default
103+
DefaultRepoUnits = make([]UnitType, len(MustRepoUnits))
104+
copy(DefaultRepoUnits, MustRepoUnits)
105+
for _, defaultU := range setDefaultRepoUnits {
106+
if !defaultU.CanBeDefault() {
107+
log.Warn("Not allowed as default unit: %s", defaultU.String())
108+
continue
109+
}
110+
// MustRepoUnits already added
111+
if defaultU.CanDisable() {
112+
DefaultRepoUnits = append(DefaultRepoUnits, defaultU)
113+
}
114+
}
115+
}
116+
117+
DisabledRepoUnits = FindUnitTypes(setting.Repository.DisabledRepoUnits...)
118+
// Check that must units are not disabled
119+
for i, disabledU := range DisabledRepoUnits {
120+
if !disabledU.CanDisable() {
121+
log.Warn("Not allowed to global disable unit %s", disabledU.String())
122+
DisabledRepoUnits = append(DisabledRepoUnits[:i], DisabledRepoUnits[i+1:]...)
123+
}
124+
}
125+
// Remove disabled units from default units
126+
for _, disabledU := range DisabledRepoUnits {
127+
for i, defaultU := range DefaultRepoUnits {
128+
if defaultU == disabledU {
129+
DefaultRepoUnits = append(DefaultRepoUnits[:i], DefaultRepoUnits[i+1:]...)
130+
}
131+
}
132+
}
133+
}
134+
135+
// UnitGlobalDisabled checks if unit type is global disabled
136+
func (u UnitType) UnitGlobalDisabled() bool {
137+
for _, ud := range DisabledRepoUnits {
138+
if u == ud {
139+
return true
140+
}
141+
}
142+
return false
143+
}
144+
145+
// CanDisable checks if this unit type can be disabled.
146+
func (u *UnitType) CanDisable() bool {
147+
for _, mu := range MustRepoUnits {
148+
if *u == mu {
149+
return false
150+
}
151+
}
152+
return true
153+
}
154+
155+
// CanBeDefault checks if the unit type can be a default repo unit
156+
func (u *UnitType) CanBeDefault() bool {
157+
for _, nadU := range NotAllowedDefaultRepoUnits {
158+
if *u == nadU {
159+
return false
160+
}
161+
}
162+
return true
163+
}
164+
88165
// Unit is a section of one repository
89166
type Unit struct {
90167
Type UnitType
@@ -96,7 +173,7 @@ type Unit struct {
96173

97174
// CanDisable returns if this unit could be disabled.
98175
func (u *Unit) CanDisable() bool {
99-
return true
176+
return u.Type.CanDisable()
100177
}
101178

102179
// IsLessThan compares order of two units

models/user.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ func (u *User) GetRepositories(page, pageSize int) (err error) {
622622
}
623623

624624
// GetRepositoryIDs returns repositories IDs where user owned and has unittypes
625+
// Caller shall check that units is not globally disabled
625626
func (u *User) GetRepositoryIDs(units ...UnitType) ([]int64, error) {
626627
var ids []int64
627628

@@ -636,6 +637,7 @@ func (u *User) GetRepositoryIDs(units ...UnitType) ([]int64, error) {
636637
}
637638

638639
// GetOrgRepositoryIDs returns repositories IDs where user's team owned and has unittypes
640+
// Caller shall check that units is not globally disabled
639641
func (u *User) GetOrgRepositoryIDs(units ...UnitType) ([]int64, error) {
640642
var ids []int64
641643

@@ -656,6 +658,7 @@ func (u *User) GetOrgRepositoryIDs(units ...UnitType) ([]int64, error) {
656658
}
657659

658660
// GetAccessRepoIDs returns all repositories IDs where user's or user is a team member organizations
661+
// Caller shall check that units is not globally disabled
659662
func (u *User) GetAccessRepoIDs(units ...UnitType) ([]int64, error) {
660663
ids, err := u.GetRepositoryIDs(units...)
661664
if err != nil {

modules/setting/repository.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ var (
3737
DefaultCloseIssuesViaCommitsInAnyBranch bool
3838
EnablePushCreateUser bool
3939
EnablePushCreateOrg bool
40+
DisabledRepoUnits []string
41+
DefaultRepoUnits []string
4042

4143
// Repository editor settings
4244
Editor struct {
@@ -98,6 +100,8 @@ var (
98100
DefaultCloseIssuesViaCommitsInAnyBranch: false,
99101
EnablePushCreateUser: false,
100102
EnablePushCreateOrg: false,
103+
DisabledRepoUnits: []string{},
104+
DefaultRepoUnits: []string{},
101105

102106
// Repository editor settings
103107
Editor: struct {

options/locale/locale_en-US.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ stargazers = Stargazers
636636
forks = Forks
637637
pick_reaction = Pick your reaction
638638
reactions_more = and %d more
639+
unit_disabled = The site administrator has disabled this repository section.
639640

640641
template.items = Template Items
641642
template.git_content = Git Content (Default Branch)
@@ -1613,6 +1614,7 @@ team_desc_helper = Describe the purpose or role of the team.
16131614
team_access_desc = Repository access
16141615
team_permission_desc = Permission
16151616
team_unit_desc = Allow Access to Repository Sections
1617+
team_unit_disabled = (Disabled)
16161618

16171619
form.name_reserved = The organization name '%s' is reserved.
16181620
form.name_pattern_not_allowed = The pattern '%s' is not allowed in an organization name.

0 commit comments

Comments
 (0)