diff --git a/integrations/org_count_test.go b/integrations/org_count_test.go index 755ee3cee59f0..f37ccbab0c054 100644 --- a/integrations/org_count_test.go +++ b/integrations/org_count_test.go @@ -119,12 +119,12 @@ func doCheckOrgCounts(username string, orgCounts map[string]int, strict bool, ca calcOrgCounts := map[string]int{} for _, org := range user.Orgs { - calcOrgCounts[org.LowerName] = org.NumRepos + calcOrgCounts[org.LowerName] = org.NumPublicRepos + org.NumPrivateRepos count, ok := canonicalCounts[org.LowerName] if ok { - assert.True(t, count == org.NumRepos, "Number of Repos in %s is %d when we expected %d", org.Name, org.NumRepos, count) + assert.True(t, count == org.NumPublicRepos+org.NumPrivateRepos, "Number of Repos in %s is %d when we expected %d", org.Name, org.NumPublicRepos+org.NumPrivateRepos, count) } else { - assert.False(t, strict, "Did not expect to see %s with count %d", org.Name, org.NumRepos) + assert.False(t, strict, "Did not expect to see %s with count %d", org.Name, org.NumPublicRepos+org.NumPrivateRepos) } } diff --git a/models/action.go b/models/action.go index f4d163afa3f53..37390ca9549f6 100644 --- a/models/action.go +++ b/models/action.go @@ -311,7 +311,7 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) { if err != nil { return nil, fmt.Errorf("AccessibleReposEnv: %v", err) } - if repoIDs, err = env.RepoIDs(1, opts.RequestedUser.NumRepos); err != nil { + if repoIDs, err = env.RepoIDs(1, opts.RequestedUser.NumPublicRepos+opts.RequestedUser.NumPrivateRepos); err != nil { return nil, fmt.Errorf("GetUserRepositories: %v", err) } diff --git a/models/consistency.go b/models/consistency.go index fbb99ca80c883..3c58bae80125f 100644 --- a/models/consistency.go +++ b/models/consistency.go @@ -70,7 +70,8 @@ func assertCount(t *testing.T, bean interface{}, expected int) { } func (user *User) checkForConsistency(t *testing.T) { - assertCount(t, &Repository{OwnerID: user.ID}, user.NumRepos) + assertCount(t, &Repository{OwnerID: user.ID, IsPrivate: false}, user.NumPublicRepos) + assertCount(t, &Repository{OwnerID: user.ID, IsPrivate: true}, user.NumPrivateRepos) assertCount(t, &Star{UID: user.ID}, user.NumStars) assertCount(t, &OrgUser{OrgID: user.ID}, user.NumMembers) assertCount(t, &Team{OrgID: user.ID}, user.NumTeams) diff --git a/models/org.go b/models/org.go index 31e5cf81c99a3..243f1391c5f53 100644 --- a/models/org.go +++ b/models/org.go @@ -160,7 +160,8 @@ func CreateOrganization(org, owner *User) (err error) { return err } org.UseCustomAvatar = true - org.MaxRepoCreation = -1 + org.MaxPublicRepoCreation = -1 + org.MaxPrivateRepoCreation = -1 org.NumTeams = 1 org.NumMembers = 1 org.Type = UserTypeOrganization @@ -622,7 +623,7 @@ func removeOrgUser(sess *xorm.Session, orgID, userID int64) error { if err != nil { return fmt.Errorf("AccessibleReposEnv: %v", err) } - repoIDs, err := env.RepoIDs(1, org.NumRepos) + repoIDs, err := env.RepoIDs(1, org.NumPublicRepos+org.NumPrivateRepos) if err != nil { return fmt.Errorf("GetUserRepositories [%d]: %v", userID, err) } diff --git a/models/repo.go b/models/repo.go index d9b65769763fa..1d4abf0d9b820 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1010,7 +1010,7 @@ func (repo *Repository) CloneLink() (cl *CloneLink) { // CheckCreateRepository check if could created a repository func CheckCreateRepository(doer, u *User, name string) error { if !doer.CanCreateRepo() { - return ErrReachLimitOfRepo{u.MaxRepoCreation} + return ErrReachLimitOfRepo{u.MaxCreationLimit()} } if err := IsUsableRepoName(name); err != nil { @@ -1135,10 +1135,17 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository) (err error return fmt.Errorf("updateUser: %v", err) } - if _, err = ctx.e.Incr("num_repos").ID(u.ID).Update(new(User)); err != nil { - return fmt.Errorf("increment user total_repos: %v", err) + if !repo.IsPrivate { + if _, err = ctx.e.Incr("num_public_repos").ID(u.ID).Update(new(User)); err != nil { + return fmt.Errorf("increment user num_public_repos: %v", err) + } + u.NumPublicRepos++ + } else { + if _, err = ctx.e.Incr("num_private_repos").ID(u.ID).Update(new(User)); err != nil { + return fmt.Errorf("increment user num_private_repos: %v", err) + } + u.NumPrivateRepos++ } - u.NumRepos++ // Give access to all members in teams with access to all repositories. if u.IsOrganization() { @@ -1415,6 +1422,14 @@ func GetRepositoriesByForkID(forkID int64) ([]*Repository, error) { } func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err error) { + if visibilityChanged { + if repo.IsPrivate && !repo.Owner.CanCreatePrivateRepo() { + return ErrReachLimitOfRepo{repo.Owner.MaxPrivateCreationLimit()} + } else if !repo.Owner.CanCreatePublicRepo() { + return ErrReachLimitOfRepo{repo.Owner.MaxPublicCreationLimit()} + } + } + repo.LowerName = strings.ToLower(repo.Name) if utf8.RuneCountInString(repo.Description) > 255 { diff --git a/models/user.go b/models/user.go index c7b3f0981e0e3..605e1c8e99357 100644 --- a/models/user.go +++ b/models/user.go @@ -131,8 +131,9 @@ type User struct { // Remember visibility choice for convenience, true for private LastRepoVisibility bool - // Maximum repository creation limit, -1 means use global default - MaxRepoCreation int `xorm:"NOT NULL DEFAULT -1"` + // Maximum repository creation limits, -1 means use global default + MaxPublicRepoCreation int `xorm:"NOT NULL DEFAULT -1"` + MaxPrivateRepoCreation int `xorm:"NOT NULL DEFAULT -1"` // Permissions IsActive bool `xorm:"INDEX"` // Activate primary email @@ -149,10 +150,11 @@ type User struct { UseCustomAvatar bool // Counters - NumFollowers int - NumFollowing int `xorm:"NOT NULL DEFAULT 0"` - NumStars int - NumRepos int + NumFollowers int + NumFollowing int `xorm:"NOT NULL DEFAULT 0"` + NumStars int + NumPublicRepos int + NumPrivateRepos int // For organization NumTeams int @@ -184,8 +186,12 @@ func (u *User) ColorFormat(s fmt.State) { // BeforeUpdate is invoked from XORM before updating this object. func (u *User) BeforeUpdate() { - if u.MaxRepoCreation < -1 { - u.MaxRepoCreation = -1 + if u.MaxPublicRepoCreation < -1 { + u.MaxPublicRepoCreation = -1 + } + + if u.MaxPrivateRepoCreation < -1 { + u.MaxPrivateRepoCreation = -1 } // Organization does not need email @@ -272,27 +278,61 @@ func (u *User) HasForkedRepo(repoID int64) bool { return has } -// MaxCreationLimit returns the number of repositories a user is allowed to create +// MaxCreationLimit returns the total number of repositories a user is allowed to create, public and private func (u *User) MaxCreationLimit() int { - if u.MaxRepoCreation <= -1 { - return setting.Repository.MaxCreationLimit + return u.MaxPublicCreationLimit() + u.MaxPrivateCreationLimit() +} + +// MaxPublicCreationLimit returns the number of public repositories a user is allowed to create +func (u *User) MaxPublicCreationLimit() int { + if u.MaxPublicRepoCreation <= -1 { + return setting.Repository.MaxPublicCreationLimit + } + return u.MaxPublicRepoCreation +} + +// MaxPrivateCreationLimit returns the number of private repositories a user is allowed to create +func (u *User) MaxPrivateCreationLimit() int { + if u.MaxPrivateRepoCreation <= -1 { + return setting.Repository.MaxPrivateCreationLimit } - return u.MaxRepoCreation + return u.MaxPrivateRepoCreation } -// CanCreateRepo returns if user login can create a repository +// CanCreateRepo returns if user login can create any type of 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 { + return u.CanCreatePublicRepo() || u.CanCreatePrivateRepo() +} + +// CanCreatePublicRepo returns if user login can create a public 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) CanCreatePublicRepo() bool { + if u.IsAdmin { + return true + } + if u.MaxPublicRepoCreation <= -1 { + if setting.Repository.MaxPublicCreationLimit <= -1 { + return true + } + return u.NumPublicRepos < setting.Repository.MaxPublicCreationLimit + } + return u.NumPublicRepos < u.MaxPublicRepoCreation +} + +// CanCreatePrivateRepo returns if user login can create a private 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) CanCreatePrivateRepo() bool { if u.IsAdmin { return true } - if u.MaxRepoCreation <= -1 { - if setting.Repository.MaxCreationLimit <= -1 { + if u.MaxPrivateRepoCreation <= -1 { + if setting.Repository.MaxPrivateCreationLimit <= -1 { return true } - return u.NumRepos < setting.Repository.MaxCreationLimit + return u.NumPrivateRepos < setting.Repository.MaxPrivateCreationLimit } - return u.NumRepos < u.MaxRepoCreation + return u.NumPrivateRepos < u.MaxPrivateRepoCreation } // CanCreateOrganization returns true if user can create organisation. @@ -754,7 +794,7 @@ func (u *User) GetOrganizations(opts *SearchOrganizationsOptions) error { orgs := make([]*User, len(orgCounts)) for i, orgCount := range orgCounts { - orgCount.User.NumRepos = orgCount.OrgCount + orgCount.User.NumPublicRepos = orgCount.OrgCount orgs[i] = &orgCount.User } @@ -1004,7 +1044,8 @@ func CreateUser(u *User) (err error) { u.HashPassword(u.Passwd) u.AllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization && !setting.Admin.DisableRegularOrgCreation u.EmailNotificationsPreference = setting.Admin.DefaultEmailNotification - u.MaxRepoCreation = -1 + u.MaxPublicRepoCreation = -1 + u.MaxPrivateRepoCreation = -1 u.Theme = setting.UI.DefaultTheme if _, err = sess.Insert(u); err != nil { diff --git a/modules/auth/admin.go b/modules/auth/admin.go index 9caf81e07ffb3..a75c0f67e5dbb 100644 --- a/modules/auth/admin.go +++ b/modules/auth/admin.go @@ -34,7 +34,8 @@ type AdminEditUserForm struct { Password string `binding:"MaxSize(255)"` Website string `binding:"ValidUrl;MaxSize(255)"` Location string `binding:"MaxSize(50)"` - MaxRepoCreation int + MaxPublicRepoCreation int + MaxPrivateRepoCreation int Active bool Admin bool Restricted bool diff --git a/modules/auth/org.go b/modules/auth/org.go index 20e2b09997e20..69fdbcf40e7d4 100644 --- a/modules/auth/org.go +++ b/modules/auth/org.go @@ -40,7 +40,8 @@ type UpdateOrgSettingForm struct { Website string `binding:"ValidUrl;MaxSize(255)"` Location string `binding:"MaxSize(50)"` Visibility structs.VisibleType - MaxRepoCreation int + MaxPublicRepoCreation int + MaxPrivateRepoCreation int RepoAdminChangeTeamAccess bool } diff --git a/modules/repository/create.go b/modules/repository/create.go index abbec05a37b0f..59f2f4ba12cf8 100644 --- a/modules/repository/create.go +++ b/modules/repository/create.go @@ -17,9 +17,16 @@ import ( // CreateRepository creates a repository for the user/organization. func CreateRepository(doer, u *models.User, opts models.CreateRepoOptions) (_ *models.Repository, err error) { - if !doer.IsAdmin && !u.CanCreateRepo() { - return nil, models.ErrReachLimitOfRepo{ - Limit: u.MaxRepoCreation, + if !doer.IsAdmin { + if opts.IsPrivate && !u.CanCreatePrivateRepo() { + return nil, models.ErrReachLimitOfRepo{ + Limit: u.MaxPrivateRepoCreation, + } + } + if !opts.IsPrivate && !u.CanCreatePublicRepo() { + return nil, models.ErrReachLimitOfRepo{ + Limit: u.MaxPublicRepoCreation, + } } } diff --git a/modules/setting/repository.go b/modules/setting/repository.go index eb1501d7b86eb..9c655797c8b0c 100644 --- a/modules/setting/repository.go +++ b/modules/setting/repository.go @@ -29,7 +29,8 @@ var ( AnsiCharset string ForcePrivate bool DefaultPrivate string - MaxCreationLimit int + MaxPublicCreationLimit int + MaxPrivateCreationLimit int MirrorQueueLength int PullRequestQueueLength int PreferredLicenses []string @@ -131,7 +132,8 @@ var ( AnsiCharset: "", ForcePrivate: false, DefaultPrivate: RepoCreatingLastUserVisibility, - MaxCreationLimit: -1, + MaxPublicCreationLimit: -1, + MaxPrivateCreationLimit: -1, MirrorQueueLength: 1000, PullRequestQueueLength: 1000, PreferredLicenses: []string{"Apache License 2.0,MIT License"}, @@ -241,7 +243,8 @@ func newRepository() { sec := Cfg.Section("repository") Repository.DisableHTTPGit = sec.Key("DISABLE_HTTP_GIT").MustBool() Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool() - Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1) + Repository.MaxPublicCreationLimit = sec.Key("MAX_PUBLIC_CREATION_LIMIT").MustInt(-1) + Repository.MaxPrivateCreationLimit = sec.Key("MAX_PRIVATE_CREATION_LIMIT").MustInt(-1) Repository.DefaultBranch = sec.Key("DEFAULT_BRANCH").MustString("master") RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gitea-repositories")) forcePathSeparator(RepoRootPath) diff --git a/modules/structs/admin_user.go b/modules/structs/admin_user.go index 7a447e44f5bdb..411b3ded596f6 100644 --- a/modules/structs/admin_user.go +++ b/modules/structs/admin_user.go @@ -37,7 +37,8 @@ type EditUserOption struct { Admin *bool `json:"admin"` AllowGitHook *bool `json:"allow_git_hook"` AllowImportLocal *bool `json:"allow_import_local"` - MaxRepoCreation *int `json:"max_repo_creation"` + MaxPublicRepoCreation *int `json:"max_public_repo_creation"` + MaxPrivateRepoCreation *int `json:"max_private_repo_creation"` ProhibitLogin *bool `json:"prohibit_login"` AllowCreateOrganization *bool `json:"allow_create_organization"` } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 80308214ddec9..9269046a9f9f4 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1999,7 +1999,8 @@ users.activated = Activated users.admin = Admin users.restricted = Restricted users.2fa = 2FA -users.repos = Repos +users.publicrepos = Public Repos +users.privaterepos = Private Repos users.created = Created users.last_login = Last Sign-In users.never_login = Never Signed-In @@ -2012,8 +2013,10 @@ users.auth_login_name = Authentication Sign-In Name users.password_helper = Leave the password empty to keep it unchanged. users.update_profile_success = The user account has been updated. users.edit_account = Edit User Account -users.max_repo_creation = Maximum Number of Repositories -users.max_repo_creation_desc = (Enter -1 to use the global default limit.) +users.max_public_repo_creation = Maximum Number of Public Repositories +users.max_public_repo_creation_desc = (Enter -1 to use the global default limit.) +users.max_private_repo_creation = Maximum Number of Private Repositories +users.max_private_repo_creation_desc = (Enter -1 to use the global default limit.) users.is_activated = User Account Is Activated users.prohibit_login = Disable Sign-In users.is_admin = Is Administrator diff --git a/routers/admin/users.go b/routers/admin/users.go index 531f81b8b51e4..87878eae98e06 100644 --- a/routers/admin/users.go +++ b/routers/admin/users.go @@ -258,7 +258,8 @@ func EditUserPost(ctx *context.Context, form auth.AdminEditUserForm) { u.Email = form.Email u.Website = form.Website u.Location = form.Location - u.MaxRepoCreation = form.MaxRepoCreation + u.MaxPublicRepoCreation = form.MaxPublicRepoCreation + u.MaxPrivateRepoCreation = form.MaxPrivateRepoCreation u.IsActive = form.Active u.IsAdmin = form.Admin u.IsRestricted = form.Restricted diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index dc095f3a1351a..7413706b82b4b 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -197,8 +197,11 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) { if form.AllowImportLocal != nil { u.AllowImportLocal = *form.AllowImportLocal } - if form.MaxRepoCreation != nil { - u.MaxRepoCreation = *form.MaxRepoCreation + if form.MaxPublicRepoCreation != nil { + u.MaxPublicRepoCreation = *form.MaxPublicRepoCreation + } + if form.MaxPrivateRepoCreation != nil { + u.MaxPrivateRepoCreation = *form.MaxPrivateRepoCreation } if form.AllowCreateOrganization != nil { u.AllowCreateOrganization = *form.AllowCreateOrganization diff --git a/routers/org/setting.go b/routers/org/setting.go index 454714c7eb8eb..507b54610fc14 100644 --- a/routers/org/setting.go +++ b/routers/org/setting.go @@ -78,7 +78,8 @@ func SettingsPost(ctx *context.Context, form auth.UpdateOrgSettingForm) { org.LowerName = strings.ToLower(form.Name) if ctx.User.IsAdmin { - org.MaxRepoCreation = form.MaxRepoCreation + org.MaxPublicRepoCreation = form.MaxPublicRepoCreation + org.MaxPrivateRepoCreation = form.MaxPrivateRepoCreation } org.FullName = form.FullName @@ -97,7 +98,7 @@ func SettingsPost(ctx *context.Context, form auth.UpdateOrgSettingForm) { // update forks visibility if visibilityChanged { - if err := org.GetRepositories(models.ListOptions{Page: 1, PageSize: org.NumRepos}); err != nil { + if err := org.GetRepositories(models.ListOptions{Page: 1, PageSize: org.NumPublicRepos + org.NumPrivateRepos}); err != nil { ctx.ServerError("GetRepositories", err) return } diff --git a/routers/repo/migrate.go b/routers/repo/migrate.go index 497f2ce36f840..db7b33814c800 100644 --- a/routers/repo/migrate.go +++ b/routers/repo/migrate.go @@ -63,7 +63,7 @@ func handleMigrateError(ctx *context.Context, owner *models.User, err error, nam case migrations.IsTwoFactorAuthError(err): ctx.RenderWithErr(ctx.Tr("form.2fa_auth_required"), tpl, form) case models.IsErrReachLimitOfRepo(err): - ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.MaxCreationLimit()), tpl, form) + ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", err.(models.ErrReachLimitOfRepo).Limit), tpl, form) case models.IsErrRepoAlreadyExist(err): ctx.Data["Err_RepoName"] = true ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tpl, form) diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 9a4fbfa130cce..4002c51f3f6fa 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -146,8 +146,10 @@ func Create(ctx *context.Context) { } } - if !ctx.User.CanCreateRepo() { - ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxCreationLimit()), tplCreate, nil) + if !getRepoPrivate(ctx) && !ctx.User.CanCreatePublicRepo() { + ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxPublicCreationLimit()), tplCreate, nil) + } else if getRepoPrivate(ctx) && !ctx.User.CanCreatePrivateRepo() { + ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxPrivateCreationLimit()), tplCreate, nil) } else { ctx.HTML(200, tplCreate) } @@ -156,7 +158,7 @@ func Create(ctx *context.Context) { func handleCreateError(ctx *context.Context, owner *models.User, err error, name string, tpl base.TplName, form interface{}) { switch { case models.IsErrReachLimitOfRepo(err): - ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", owner.MaxCreationLimit()), tpl, form) + ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", err.(models.ErrReachLimitOfRepo).Limit), tpl, form) case models.IsErrRepoAlreadyExist(err): ctx.Data["Err_RepoName"] = true ctx.RenderWithErr(ctx.Tr("form.repo_name_been_taken"), tpl, form) diff --git a/routers/repo/setting.go b/routers/repo/setting.go index 8d07bf09a4f3a..f17f3b35e0f30 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -112,6 +112,14 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { return } + if visibilityChanged { + if !form.Private && !repo.Owner.CanCreatePublicRepo() { + ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", repo.Owner.MaxPublicCreationLimit()), tplSettingsOptions, &form) + } else if form.Private && !repo.Owner.CanCreatePrivateRepo() { + ctx.RenderWithErr(ctx.Tr("repo.form.reach_limit_of_creation", repo.Owner.MaxPrivateCreationLimit()), tplSettingsOptions, &form) + } + } + repo.IsPrivate = form.Private if err := models.UpdateRepository(repo, visibilityChanged); err != nil { ctx.ServerError("UpdateRepository", err) @@ -388,8 +396,14 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { return } - if !ctx.Repo.Owner.CanCreateRepo() { - ctx.Flash.Error(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxCreationLimit())) + if !repo.IsPrivate && !ctx.Repo.Owner.CanCreatePublicRepo() { + ctx.Flash.Error(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxPublicCreationLimit())) + ctx.Redirect(repo.Link() + "/settings") + return + } + + if repo.IsPrivate && !ctx.Repo.Owner.CanCreatePrivateRepo() { + ctx.Flash.Error(ctx.Tr("repo.form.reach_limit_of_creation", ctx.User.MaxPrivateCreationLimit())) ctx.Redirect(repo.Link() + "/settings") return } diff --git a/routers/user/home.go b/routers/user/home.go index f7f1786b3302b..2dc7f7501520b 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -411,7 +411,7 @@ func Issues(ctx *context.Context) { ctx.ServerError("AccessibleReposEnv", err) return } - userRepoIDs, err = env.RepoIDs(1, ctxUser.NumRepos) + userRepoIDs, err = env.RepoIDs(1, ctxUser.NumPublicRepos+ctxUser.NumPrivateRepos) if err != nil { ctx.ServerError("env.RepoIDs", err) return diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl index 4f6bc50342ba9..b83e146881a7e 100644 --- a/templates/admin/org/list.tmpl +++ b/templates/admin/org/list.tmpl @@ -23,7 +23,8 @@ {{.i18n.Tr "admin.orgs.teams"}} {{.i18n.Tr "admin.orgs.members"}} - {{.i18n.Tr "admin.users.repos"}} + {{.i18n.Tr "admin.users.publicrepos"}} + {{.i18n.Tr "admin.users.privaterepos"}} {{.i18n.Tr "admin.users.created"}} {{SortArrow "recentupdate" "leastupdate" $.SortType false}} @@ -43,7 +44,8 @@ {{.NumTeams}} {{.NumMembers}} - {{.NumRepos}} + {{.NumPublicRepos}} + {{.NumPrivateRepos}} {{.CreatedUnix.FormatShort}} diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl index 042c09954a2c3..a8e9c676b455e 100644 --- a/templates/admin/user/edit.tmpl +++ b/templates/admin/user/edit.tmpl @@ -57,10 +57,15 @@
-
- - -

{{.i18n.Tr "admin.users.max_repo_creation_desc"}}

+
+ + +

{{.i18n.Tr "admin.users.max_public_repo_creation_desc"}}

+
+
+ + +

{{.i18n.Tr "admin.users.max_private_repo_creation_desc"}}

diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl index d6dd7d5c03969..a169c8116ba94 100644 --- a/templates/admin/user/list.tmpl +++ b/templates/admin/user/list.tmpl @@ -26,7 +26,8 @@ {{.i18n.Tr "admin.users.admin"}} {{.i18n.Tr "admin.users.restricted"}} {{.i18n.Tr "admin.users.2fa"}} - {{.i18n.Tr "admin.users.repos"}} + {{.i18n.Tr "admin.users.publicrepos"}} + {{.i18n.Tr "admin.users.privaterepos"}} {{.i18n.Tr "admin.users.created"}} {{.i18n.Tr "admin.users.last_login"}} @@ -45,7 +46,8 @@ - {{.NumRepos}} + {{.NumPublicRepos}} + {{.NumPrivateRepos}} {{.CreatedUnix.FormatShort}} {{if .LastLoginUnix}} {{.LastLoginUnix.FormatShort}} diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl index d58c77ad10a2e..975aa80d9cd58 100644 --- a/templates/org/settings/options.tmpl +++ b/templates/org/settings/options.tmpl @@ -69,10 +69,15 @@ {{if .SignedUser.IsAdmin}}
-
- - -

{{.i18n.Tr "admin.users.max_repo_creation_desc"}}

+
+ + +

{{.i18n.Tr "admin.users.max_public_repo_creation_desc"}}

+
+
+ + +

{{.i18n.Tr "admin.users.max_private_repo_creation_desc"}}

{{end}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 661005be245d0..9cc966b5af991 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -12758,10 +12758,15 @@ "type": "string", "x-go-name": "LoginName" }, - "max_repo_creation": { + "max_private_repo_creation": { "type": "integer", "format": "int64", - "x-go-name": "MaxRepoCreation" + "x-go-name": "MaxPrivateRepoCreation" + }, + "max_public_repo_creation": { + "type": "integer", + "format": "int64", + "x-go-name": "MaxPublicRepoCreation" }, "must_change_password": { "type": "boolean",