From 21ded9aad73b22e4e4e7167bd0bcfb0309d614f4 Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 1 Apr 2024 17:59:08 -0400 Subject: [PATCH 1/2] Limit the number of users on an instace Fix #29975 --- custom/conf/app.example.ini | 4 ++++ .../administration/config-cheat-sheet.en-us.md | 1 + models/user/user.go | 14 ++++++++++++++ modules/setting/service.go | 3 +++ routers/web/auth/auth.go | 7 +++++++ 5 files changed, 29 insertions(+) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index b4b4f3a8a2bea..133e9e0768b50 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -896,6 +896,10 @@ LEVEL = Info ;USER_DELETE_WITH_COMMENTS_MAX_TIME = 0 ;; Valid site url schemes for user profiles ;VALID_SITE_URL_SCHEMES=http,https +;; The maximum number of users allowed to exist before creation is disabled. +;; This is not a security prevention measure. +;; Note, Admins will also be unable to create new users via the dashboard +;MAX_USER_CREATE_LIMIT=-1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 2309021f94937..127a4a1a582d7 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -686,6 +686,7 @@ And the following unique queues: The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS. - `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted. - `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles +- `MAX_USER_CREATE_LIMIT`: **-1**: The maximum number of users allowed to exist before creation is disabled. Note: This also prevents admins from creating new users. `-1` means no, limit. ### Service - Explore (`service.explore`) diff --git a/models/user/user.go b/models/user/user.go index 22a30996438cf..a6fedab8250df 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -600,6 +600,11 @@ func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefa return err } + // Check the number of users already in the system, and if there are too many forbid any new ones. + if HitCreationLimit(ctx) { + return fmt.Errorf("The system has exceeded the user creation limit") + } + // set system defaults u.KeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate u.Visibility = setting.Service.DefaultUserVisibilityMode @@ -729,6 +734,15 @@ func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefa return committer.Commit() } +func HitCreationLimit(ctx context.Context) bool { + // don't bother calling DB if limit not set + if setting.Service.MaxUserCreationLimit == -1 || + int64(setting.Service.MaxUserCreationLimit) < CountUsers(ctx, &CountUserFilter{}) { + return false + } + return true +} + // IsLastAdminUser check whether user is the last admin func IsLastAdminUser(ctx context.Context, user *User) bool { if user.IsAdmin && CountUsers(ctx, &CountUserFilter{IsAdmin: optional.Some(true)}) <= 1 { diff --git a/modules/setting/service.go b/modules/setting/service.go index 3ea1501236dfd..e73c5a08c0354 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -81,6 +81,7 @@ var Service = struct { DefaultOrgMemberVisible bool UserDeleteWithCommentsMaxTime time.Duration ValidSiteURLSchemes []string + MaxUserCreationLimit int // OpenID settings EnableOpenIDSignIn bool @@ -234,6 +235,8 @@ func loadServiceFrom(rootCfg ConfigProvider) { } Service.ValidSiteURLSchemes = schemes + Service.MaxUserCreationLimit = sec.Key("MAX_USER_CREATE_LIMIT").MustInt(-1) + mustMapSetting(rootCfg, "service.explore", &Service.Explore) loadOpenIDSetting(rootCfg) diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 8b5cd986b81a6..4cde1ea03995b 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -717,6 +717,13 @@ func ActivatePost(ctx *context.Context) { return } + // Check the number of users already in the system, and if there are too many forbid any new ones. + if user_model.HitCreationLimit(ctx) { + ctx.Flash.Error("The system has exceeded the user creation limit", true) + renderActivationChangeEmail(ctx) + return + } + if code == "" { newEmail := strings.TrimSpace(ctx.FormString("change_email")) if ctx.Doer != nil && newEmail != "" && !strings.EqualFold(ctx.Doer.Email, newEmail) { From 189fd9ea1e5fa6871b12b3cefb50a87ce57c0f6f Mon Sep 17 00:00:00 2001 From: techknowlogick Date: Mon, 1 Apr 2024 23:09:19 -0400 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: delvh --- custom/conf/app.example.ini | 3 ++- docs/content/administration/config-cheat-sheet.en-us.md | 2 +- models/user/user.go | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 133e9e0768b50..473a233947e9e 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -898,7 +898,8 @@ LEVEL = Info ;VALID_SITE_URL_SCHEMES=http,https ;; The maximum number of users allowed to exist before creation is disabled. ;; This is not a security prevention measure. -;; Note, Admins will also be unable to create new users via the dashboard +;; Note, Admins will also be unable to create new users via the dashboard when the limit has been reached +;; `-1` means no limit ;MAX_USER_CREATE_LIMIT=-1 diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 127a4a1a582d7..9249380e6d3b7 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -686,7 +686,7 @@ And the following unique queues: The user's email will be replaced with a concatenation of the user name in lower case, "@" and NO_REPLY_ADDRESS. - `USER_DELETE_WITH_COMMENTS_MAX_TIME`: **0** Minimum amount of time a user must exist before comments are kept when the user is deleted. - `VALID_SITE_URL_SCHEMES`: **http, https**: Valid site url schemes for user profiles -- `MAX_USER_CREATE_LIMIT`: **-1**: The maximum number of users allowed to exist before creation is disabled. Note: This also prevents admins from creating new users. `-1` means no, limit. +- `MAX_USER_CREATE_LIMIT`: **-1**: The maximum number of users allowed to exist before creation is disabled. Note: This also prevents admins from creating new users. `-1` means no limit. ### Service - Explore (`service.explore`) diff --git a/models/user/user.go b/models/user/user.go index a6fedab8250df..77176417cfa3e 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -736,7 +736,7 @@ func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefa func HitCreationLimit(ctx context.Context) bool { // don't bother calling DB if limit not set - if setting.Service.MaxUserCreationLimit == -1 || + if setting.Service.MaxUserCreationLimit < 0 || int64(setting.Service.MaxUserCreationLimit) < CountUsers(ctx, &CountUserFilter{}) { return false }