Require at least one unit to be enabled (#24189)

Don't remember why the previous decision that `Code` and `Release` are
non-disable units globally. Since now every unit include `Code` could be
disabled, maybe we should have a new rule that the repo should have at
least one unit. So any unit could be disabled.

Fixes #20960
Fixes #7525

---------

Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: yp05327 <576951401@qq.com>
This commit is contained in:
Lunny Xiao 2023-05-06 17:39:06 +08:00 committed by GitHub
parent 0ebabf3c6b
commit e5a8ebc0ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 109 additions and 75 deletions

View file

@ -970,9 +970,11 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
}
}
if err := repo_model.UpdateRepositoryUnits(repo, units, deleteUnitTypes); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRepositoryUnits", err)
return err
if len(units)+len(deleteUnitTypes) > 0 {
if err := repo_model.UpdateRepositoryUnits(repo, units, deleteUnitTypes); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRepositoryUnits", err)
return err
}
}
log.Trace("Repository advanced settings updated: %s/%s", owner.Name, repo.Name)

View file

@ -536,6 +536,12 @@ func SettingsPost(ctx *context.Context) {
deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests)
}
if len(units) == 0 {
ctx.Flash.Error(ctx.Tr("repo.settings.update_settings_no_unit"))
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
return
}
if err := repo_model.UpdateRepositoryUnits(repo, units, deleteUnitTypes); err != nil {
ctx.ServerError("UpdateRepositoryUnits", err)
return

View file

@ -261,6 +261,27 @@ func registerRoutes(m *web.Route) {
}
}
reqUnitAccess := func(unitType unit.Type, accessMode perm.AccessMode) func(ctx *context.Context) {
return func(ctx *context.Context) {
if unitType.UnitGlobalDisabled() {
ctx.NotFound(unitType.String(), nil)
return
}
if ctx.ContextUser == nil {
ctx.NotFound(unitType.String(), nil)
return
}
if ctx.ContextUser.IsOrganization() {
if ctx.Org.Organization.UnitPermission(ctx, ctx.Doer, unitType) < accessMode {
ctx.NotFound(unitType.String(), nil)
return
}
}
}
}
addWebhookAddRoutes := func() {
m.Get("/{type}/new", repo.WebhooksNew)
m.Post("/gitea/new", web.Bind(forms.NewWebhookForm{}), repo.GiteaHooksNewPost)
@ -334,7 +355,7 @@ func registerRoutes(m *web.Route) {
m.Get("/users", explore.Users)
m.Get("/users/sitemap-{idx}.xml", sitemapEnabled, explore.Users)
m.Get("/organizations", explore.Organizations)
m.Get("/code", explore.Code)
m.Get("/code", reqUnitAccess(unit.TypeCode, perm.AccessModeRead), explore.Code)
m.Get("/topics/search", explore.TopicSearch)
}, ignExploreSignIn)
m.Group("/issues", func() {
@ -649,21 +670,6 @@ func registerRoutes(m *web.Route) {
}
}
reqUnitAccess := func(unitType unit.Type, accessMode perm.AccessMode) func(ctx *context.Context) {
return func(ctx *context.Context) {
if ctx.ContextUser == nil {
ctx.NotFound(unitType.String(), nil)
return
}
if ctx.ContextUser.IsOrganization() {
if ctx.Org.Organization.UnitPermission(ctx, ctx.Doer, unitType) < accessMode {
ctx.NotFound(unitType.String(), nil)
return
}
}
}
}
// ***** START: Organization *****
m.Group("/org", func() {
m.Group("/{org}", func() {