summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2025-02-10 15:46:36 +0100
committerLibravatar GitHub <noreply@github.com>2025-02-10 15:46:36 +0100
commit787bdc1488da476e54fb0daded061cf36ecf9010 (patch)
tree892cf4b9d42887ac703d8ee565be884c89b2d903 /internal
parent[bugfix] Fix POST to create account endpoint (#3767) (diff)
downloadgotosocial-787bdc1488da476e54fb0daded061cf36ecf9010.tar.xz
[feature] make account sign-up / backlog limits configurable (#3768)
Diffstat (limited to 'internal')
-rw-r--r--internal/config/config.go10
-rw-r--r--internal/config/defaults.go10
-rw-r--r--internal/config/helpers.gen.go50
-rw-r--r--internal/processing/user/create.go51
4 files changed, 92 insertions, 29 deletions
diff --git a/internal/config/config.go b/internal/config/config.go
index 5c59c47cc..33003d0f9 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -92,10 +92,12 @@ type Configuration struct {
InstanceSubscriptionsProcessEvery time.Duration `name:"instance-subscriptions-process-every" usage:"Period to elapse between instance subscriptions processing jobs, starting from instance-subscriptions-process-from."`
InstanceStatsMode string `name:"instance-stats-mode" usage:"Allows you to customize the way stats are served to crawlers: one of '', 'serve', 'zero', 'baffle'. Home page stats remain unchanged."`
- AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."`
- AccountsReasonRequired bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"`
- AccountsAllowCustomCSS bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."`
- AccountsCustomCSSLength int `name:"accounts-custom-css-length" usage:"Maximum permitted length (characters) of custom CSS for accounts."`
+ AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."`
+ AccountsReasonRequired bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"`
+ AccountsRegistrationDailyLimit int `name:"accounts-registration-daily-limit" usage:"Limit amount of approved account sign-ups allowed per 24hrs before registration is closed. 0 or less = no limit."`
+ AccountsRegistrationBacklogLimit int `name:"accounts-registration-backlog-limit" usage:"Limit how big the 'accounts pending approval' queue can grow before registration is closed. 0 or less = no limit."`
+ AccountsAllowCustomCSS bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."`
+ AccountsCustomCSSLength int `name:"accounts-custom-css-length" usage:"Maximum permitted length (characters) of custom CSS for accounts."`
MediaDescriptionMinChars int `name:"media-description-min-chars" usage:"Min required chars for an image description"`
MediaDescriptionMaxChars int `name:"media-description-max-chars" usage:"Max permitted chars for an image description"`
diff --git a/internal/config/defaults.go b/internal/config/defaults.go
index 157dfde0a..7f66e4209 100644
--- a/internal/config/defaults.go
+++ b/internal/config/defaults.go
@@ -68,10 +68,12 @@ var Defaults = Configuration{
InstanceSubscriptionsProcessFrom: "23:00", // 11pm,
InstanceSubscriptionsProcessEvery: 24 * time.Hour, // 1/day.
- AccountsRegistrationOpen: false,
- AccountsReasonRequired: true,
- AccountsAllowCustomCSS: false,
- AccountsCustomCSSLength: 10000,
+ AccountsRegistrationOpen: false,
+ AccountsReasonRequired: true,
+ AccountsRegistrationDailyLimit: 10,
+ AccountsRegistrationBacklogLimit: 20,
+ AccountsAllowCustomCSS: false,
+ AccountsCustomCSSLength: 10000,
MediaDescriptionMinChars: 0,
MediaDescriptionMaxChars: 1500,
diff --git a/internal/config/helpers.gen.go b/internal/config/helpers.gen.go
index 54d1b62d9..d3ccf16ea 100644
--- a/internal/config/helpers.gen.go
+++ b/internal/config/helpers.gen.go
@@ -1132,6 +1132,56 @@ func GetAccountsReasonRequired() bool { return global.GetAccountsReasonRequired(
// SetAccountsReasonRequired safely sets the value for global configuration 'AccountsReasonRequired' field
func SetAccountsReasonRequired(v bool) { global.SetAccountsReasonRequired(v) }
+// GetAccountsRegistrationDailyLimit safely fetches the Configuration value for state's 'AccountsRegistrationDailyLimit' field
+func (st *ConfigState) GetAccountsRegistrationDailyLimit() (v int) {
+ st.mutex.RLock()
+ v = st.config.AccountsRegistrationDailyLimit
+ st.mutex.RUnlock()
+ return
+}
+
+// SetAccountsRegistrationDailyLimit safely sets the Configuration value for state's 'AccountsRegistrationDailyLimit' field
+func (st *ConfigState) SetAccountsRegistrationDailyLimit(v int) {
+ st.mutex.Lock()
+ defer st.mutex.Unlock()
+ st.config.AccountsRegistrationDailyLimit = v
+ st.reloadToViper()
+}
+
+// AccountsRegistrationDailyLimitFlag returns the flag name for the 'AccountsRegistrationDailyLimit' field
+func AccountsRegistrationDailyLimitFlag() string { return "accounts-registration-daily-limit" }
+
+// GetAccountsRegistrationDailyLimit safely fetches the value for global configuration 'AccountsRegistrationDailyLimit' field
+func GetAccountsRegistrationDailyLimit() int { return global.GetAccountsRegistrationDailyLimit() }
+
+// SetAccountsRegistrationDailyLimit safely sets the value for global configuration 'AccountsRegistrationDailyLimit' field
+func SetAccountsRegistrationDailyLimit(v int) { global.SetAccountsRegistrationDailyLimit(v) }
+
+// GetAccountsRegistrationBacklogLimit safely fetches the Configuration value for state's 'AccountsRegistrationBacklogLimit' field
+func (st *ConfigState) GetAccountsRegistrationBacklogLimit() (v int) {
+ st.mutex.RLock()
+ v = st.config.AccountsRegistrationBacklogLimit
+ st.mutex.RUnlock()
+ return
+}
+
+// SetAccountsRegistrationBacklogLimit safely sets the Configuration value for state's 'AccountsRegistrationBacklogLimit' field
+func (st *ConfigState) SetAccountsRegistrationBacklogLimit(v int) {
+ st.mutex.Lock()
+ defer st.mutex.Unlock()
+ st.config.AccountsRegistrationBacklogLimit = v
+ st.reloadToViper()
+}
+
+// AccountsRegistrationBacklogLimitFlag returns the flag name for the 'AccountsRegistrationBacklogLimit' field
+func AccountsRegistrationBacklogLimitFlag() string { return "accounts-registration-backlog-limit" }
+
+// GetAccountsRegistrationBacklogLimit safely fetches the value for global configuration 'AccountsRegistrationBacklogLimit' field
+func GetAccountsRegistrationBacklogLimit() int { return global.GetAccountsRegistrationBacklogLimit() }
+
+// SetAccountsRegistrationBacklogLimit safely sets the value for global configuration 'AccountsRegistrationBacklogLimit' field
+func SetAccountsRegistrationBacklogLimit(v int) { global.SetAccountsRegistrationBacklogLimit(v) }
+
// GetAccountsAllowCustomCSS safely fetches the Configuration value for state's 'AccountsAllowCustomCSS' field
func (st *ConfigState) GetAccountsAllowCustomCSS() (v bool) {
st.mutex.RLock()
diff --git a/internal/processing/user/create.go b/internal/processing/user/create.go
index 0d848583e..f878d8320 100644
--- a/internal/processing/user/create.go
+++ b/internal/processing/user/create.go
@@ -44,34 +44,43 @@ func (p *Processor) Create(
app *gtsmodel.Application,
form *apimodel.AccountCreateRequest,
) (*gtsmodel.User, gtserror.WithCode) {
- const (
- usersPerDay = 10
- regBacklog = 20
+ var (
+ usersPerDay = config.GetAccountsRegistrationDailyLimit()
+ regBacklog = config.GetAccountsRegistrationBacklogLimit()
)
- // Ensure no more than usersPerDay
+ // If usersPerDay limit is in place,
+ // ensure no more than usersPerDay
// have registered in the last 24h.
- newUsersCount, err := p.state.DB.CountApprovedSignupsSince(ctx, time.Now().Add(-24*time.Hour))
- if err != nil {
- err := fmt.Errorf("db error counting new users: %w", err)
- return nil, gtserror.NewErrorInternalError(err)
- }
+ if usersPerDay > 0 {
+ newUsersCount, err := p.state.DB.CountApprovedSignupsSince(ctx, time.Now().Add(-24*time.Hour))
+ if err != nil {
+ err := fmt.Errorf("db error counting new users: %w", err)
+ return nil, gtserror.NewErrorInternalError(err)
+ }
- if newUsersCount >= usersPerDay {
- err := fmt.Errorf("this instance has hit its limit of new sign-ups for today; you can try again tomorrow")
- return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
+ if newUsersCount >= usersPerDay {
+ err := fmt.Errorf("this instance has hit its limit of new sign-ups for today (%d); you can try again tomorrow", usersPerDay)
+ return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
+ }
}
- // Ensure the new users backlog isn't full.
- backlogLen, err := p.state.DB.CountUnhandledSignups(ctx)
- if err != nil {
- err := fmt.Errorf("db error counting registration backlog length: %w", err)
- return nil, gtserror.NewErrorInternalError(err)
- }
+ // If registration backlog limit is
+ // in place, ensure backlog isn't full.
+ if regBacklog > 0 {
+ backlogLen, err := p.state.DB.CountUnhandledSignups(ctx)
+ if err != nil {
+ err := fmt.Errorf("db error counting registration backlog length: %w", err)
+ return nil, gtserror.NewErrorInternalError(err)
+ }
- if backlogLen >= regBacklog {
- err := fmt.Errorf("this instance's sign-up backlog is currently full; you must wait until pending sign-ups are handled by the admin(s)")
- return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
+ if backlogLen >= regBacklog {
+ err := fmt.Errorf(
+ "this instance's sign-up backlog is currently full (%d sign-ups pending approval); "+
+ "you must wait until some pending sign-ups are handled by the admin(s)", regBacklog,
+ )
+ return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
+ }
}
emailAvailable, err := p.state.DB.IsEmailAvailable(ctx, form.Email)