feat: Trivial default quota configuration
This adds a new configuration setting: `[quota.default].TOTAL`, which will be used if no groups are configured for a particular user. The new option makes it possible to entirely skip configuring quotas via the API if all that one wants is a total size. Signed-off-by: Gergely Nagy <forgejo@gergo.csillger.hu>
This commit is contained in:
parent
190b5a3859
commit
3b70949651
4 changed files with 86 additions and 4 deletions
25
models/quota/default.go
Normal file
25
models/quota/default.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2024 The Forgejo Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package quota
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func EvaluateDefault(used Used, forSubject LimitSubject) bool {
|
||||||
|
groups := GroupList{
|
||||||
|
&Group{
|
||||||
|
Name: "builtin-default-group",
|
||||||
|
Rules: []Rule{
|
||||||
|
{
|
||||||
|
Name: "builtin-default-rule",
|
||||||
|
Limit: setting.Quota.Default.Total,
|
||||||
|
Subjects: LimitSubjects{LimitSubjectSizeAll},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups.Evaluate(used, forSubject)
|
||||||
|
}
|
|
@ -230,9 +230,9 @@ func (g *Group) Evaluate(used Used, forSubject LimitSubject) (bool, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gl *GroupList) Evaluate(used Used, forSubject LimitSubject) bool {
|
func (gl *GroupList) Evaluate(used Used, forSubject LimitSubject) bool {
|
||||||
// If there are no groups, default to success:
|
// If there are no groups, use the configured defaults:
|
||||||
if gl == nil || len(*gl) == 0 {
|
if gl == nil || len(*gl) == 0 {
|
||||||
return true
|
return EvaluateDefault(used, forSubject)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, group := range *gl {
|
for _, group := range *gl {
|
||||||
|
|
|
@ -7,9 +7,18 @@ package setting
|
||||||
var Quota = struct {
|
var Quota = struct {
|
||||||
Enabled bool `ini:"ENABLED"`
|
Enabled bool `ini:"ENABLED"`
|
||||||
DefaultGroups []string `ini:"DEFAULT_GROUPS"`
|
DefaultGroups []string `ini:"DEFAULT_GROUPS"`
|
||||||
|
|
||||||
|
Default struct {
|
||||||
|
Total int64
|
||||||
|
} `ini:"quota.default"`
|
||||||
}{
|
}{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
DefaultGroups: []string{},
|
DefaultGroups: []string{},
|
||||||
|
Default: struct {
|
||||||
|
Total int64
|
||||||
|
}{
|
||||||
|
Total: -1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadQuotaFrom(rootCfg ConfigProvider) {
|
func loadQuotaFrom(rootCfg ConfigProvider) {
|
||||||
|
|
|
@ -548,6 +548,42 @@ func TestGitQuotaEnforcement(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQuotaConfigDefault(t *testing.T) {
|
||||||
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
|
env := createQuotaWebEnv(t)
|
||||||
|
defer env.Cleanup()
|
||||||
|
|
||||||
|
t.Run("with config-based default", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
defer test.MockVariableValue(&setting.Quota.Default.Total, 0)()
|
||||||
|
|
||||||
|
env.As(t, env.Users.Ungrouped).
|
||||||
|
With(Context{
|
||||||
|
Payload: &Payload{
|
||||||
|
"uid": env.Users.Ungrouped.ID().AsString(),
|
||||||
|
"repo_name": "quota-config-default",
|
||||||
|
},
|
||||||
|
}).
|
||||||
|
PostToPage("/repo/create").
|
||||||
|
ExpectStatus(http.StatusRequestEntityTooLarge)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("without config-based default", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
env.As(t, env.Users.Ungrouped).
|
||||||
|
With(Context{
|
||||||
|
Payload: &Payload{
|
||||||
|
"uid": env.Users.Ungrouped.ID().AsString(),
|
||||||
|
"repo_name": "quota-config-default",
|
||||||
|
},
|
||||||
|
}).
|
||||||
|
PostToPage("/repo/create").
|
||||||
|
ExpectStatus(http.StatusSeeOther)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* Here be dragons! *
|
* Here be dragons! *
|
||||||
* *
|
* *
|
||||||
|
@ -568,6 +604,7 @@ type quotaWebEnv struct {
|
||||||
type quotaWebEnvUsers struct {
|
type quotaWebEnvUsers struct {
|
||||||
Limited quotaWebEnvUser
|
Limited quotaWebEnvUser
|
||||||
Contributor quotaWebEnvUser
|
Contributor quotaWebEnvUser
|
||||||
|
Ungrouped quotaWebEnvUser
|
||||||
}
|
}
|
||||||
|
|
||||||
type quotaWebEnvOrgs struct {
|
type quotaWebEnvOrgs struct {
|
||||||
|
@ -1005,8 +1042,7 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
|
||||||
|
|
||||||
// *** helpers ***
|
// *** helpers ***
|
||||||
|
|
||||||
// Create a user, its quota group & rule
|
makeUngroupedUser := func(t *testing.T) quotaWebEnvUser {
|
||||||
makeUser := func(t *testing.T, limit int64) quotaWebEnvUser {
|
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
user := quotaWebEnvUser{}
|
user := quotaWebEnvUser{}
|
||||||
|
@ -1021,6 +1057,16 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
|
||||||
repo, _, _ := tests.CreateDeclarativeRepoWithOptions(t, user.User, tests.DeclarativeRepoOptions{})
|
repo, _, _ := tests.CreateDeclarativeRepoWithOptions(t, user.User, tests.DeclarativeRepoOptions{})
|
||||||
user.Repo = repo
|
user.Repo = repo
|
||||||
|
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a user, its quota group & rule
|
||||||
|
makeUser := func(t *testing.T, limit int64) quotaWebEnvUser {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
user := makeUngroupedUser(t)
|
||||||
|
userName := user.User.Name
|
||||||
|
|
||||||
// Create a quota group for them
|
// Create a quota group for them
|
||||||
group, err := quota_model.CreateGroup(db.DefaultContext, userName)
|
group, err := quota_model.CreateGroup(db.DefaultContext, userName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -1095,5 +1141,7 @@ func createQuotaWebEnv(t *testing.T) *quotaWebEnv {
|
||||||
env.Orgs.Limited = makeOrg(t, env.Users.Limited.User, int64(0))
|
env.Orgs.Limited = makeOrg(t, env.Users.Limited.User, int64(0))
|
||||||
env.Orgs.Unlimited = makeOrg(t, env.Users.Limited.User, int64(-1))
|
env.Orgs.Unlimited = makeOrg(t, env.Users.Limited.User, int64(-1))
|
||||||
|
|
||||||
|
env.Users.Ungrouped = makeUngroupedUser(t)
|
||||||
|
|
||||||
return &env
|
return &env
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue