feat(repo): split repository creation limit into user and org scopes (#37872)

## Background

`MAX_CREATION_LIMIT` applies to whoever owns a new repository, with no
distinction between individual users and organizations. Admins who want
different limits for the two - most commonly "block personal repos but
let orgs create freely" - currently have to set per-user / per-org
overrides on every entity.

## Changes

Adds two new `[repository]` settings:

- `USER_MAX_CREATION_LIMIT`: global limit for individual users
- `ORG_MAX_CREATION_LIMIT`: global limit for organizations

`MAX_CREATION_LIMIT` is kept as a shortcut: when set, it becomes the
default value for both new keys. When the new keys are explicitly
configured, they take precedence. Deployments that only set
`MAX_CREATION_LIMIT` see behavior identical to now.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
Zettat123
2026-05-28 11:29:32 -06:00
committed by GitHub
parent 52fef74291
commit 49f88a4b9e
7 changed files with 137 additions and 18 deletions
+11 -10
View File
@@ -244,12 +244,15 @@ func (u *User) IsOAuth2() bool {
return u.LoginType == auth.OAuth2
}
// MaxCreationLimit returns the number of repositories a user is allowed to create
// MaxCreationLimit returns the number of repositories a user or an organization is allowed to create
func (u *User) MaxCreationLimit() int {
if u.MaxRepoCreation <= -1 {
return setting.Repository.MaxCreationLimit
if u.MaxRepoCreation > -1 {
return u.MaxRepoCreation
}
return u.MaxRepoCreation
if u.IsOrganization() {
return setting.Repository.OrgMaxCreationLimit
}
return setting.Repository.UserMaxCreationLimit
}
// CanCreateRepoIn checks whether the doer(u) can create a repository in the owner
@@ -264,13 +267,11 @@ func (u *User) CanCreateRepoIn(owner *User) bool {
return true
}
const noLimit = -1
if owner.MaxRepoCreation == noLimit {
if setting.Repository.MaxCreationLimit == noLimit {
return true
}
return owner.NumRepos < setting.Repository.MaxCreationLimit
limit := owner.MaxCreationLimit()
if limit == noLimit {
return true
}
return owner.NumRepos < owner.MaxRepoCreation
return owner.NumRepos < limit
}
// CanCreateOrganization returns true if user can create organisation.