Open
Description
Proposal sollution about limit org's repo number.
Add a new identity named as main owner
in a org, which is the creater of org, and can be changed but should be only one in a org, The orgs repo will be calculate as main owner
's repo to limit repo number. Only when the main owner
can create repo can this org create repo. and we can also limit the number of org one user can main owned
to limit org create.
main logic:
diff --git a/models/user.go b/models/user.go
index c7b44bdb7..efedcc38b 100644
--- a/models/user.go
+++ b/models/user.go
@@ -161,6 +161,8 @@ type User struct {
MembersIsPublic map[int64]bool `xorm:"-"`
Visibility structs.VisibleType `xorm:"NOT NULL DEFAULT 0"`
RepoAdminChangeTeamAccess bool `xorm:"NOT NULL DEFAULT false"`
+ MainOwnerID int64 `xorm:"INDEX"`
+ MainOwner *User `xorm:"-"`
// Preferences
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
@@ -264,19 +266,51 @@ func (u *User) MaxCreationLimit() int {
return u.MaxRepoCreation
}
+// LoadMainOwner load main owner of a org
+func (u *User) LoadMainOwner() (err error) {
+ if !u.IsOrganization() || u.MainOwner != nil {
+ return nil
+ }
+
+ u.MainOwner, err = GetUserByID(u.MainOwnerID)
+ return err
+}
+
// CanCreateRepo returns if user login can create a repository
// NOTE: functions calling this assume a failure due to repository count limit; if new checks are added, those functions should be revised
func (u *User) CanCreateRepo() bool {
if u.IsAdmin {
return true
}
+
+ total := 0
+ var err error
+ if u.IsOrganization() {
+ err = u.LoadMainOwner()
+ if err != nil {
+ log.Error("LoadMainOwner(): %v", err)
+ return false
+ }
+ if !u.MainOwner.CanCreateRepo() {
+ return false
+ }
+ } else {
+ total, err = u.TotalRepoNumInMainOwnedOrgs()
+ if err != nil {
+ log.Error("TotalRepoNumInMainOwnedOrgs(): %v", err)
+ return false
+ }
+ }
+
+ total += u.NumRepos
+
if u.MaxRepoCreation <= -1 {
if setting.Repository.MaxCreationLimit <= -1 {
return true
}
- return u.NumRepos < setting.Repository.MaxCreationLimit
+ return total < setting.Repository.MaxCreationLimit
}
- return u.NumRepos < u.MaxRepoCreation
+ return total < u.MaxRepoCreation
}
// CanCreateOrganization returns true if user can create organisation.
@@ -2035,3 +2069,10 @@ func IterateUser(f func(user *User) error) error {
}
}
}
+
+// TotalRepoNumInMainOwnedOrgs calculate all repo number in org that
+// user main owned
+func (u *User) TotalRepoNumInMainOwnedOrgs() (int, error) {
+ total, err := x.Where("main_owner_id").SumInt(new(User), "num_repos")
+ return int(total), err
+}
Originally posted by @a1012112796 in #15924 (comment)
- test issue todo list item