feat(config): allow -1 to represent unlimited upload limits

Introduce support for configuring unlimited upload limits by allowing -1
as a valid value for anonymous and user upload MB limits.

Changes include:
- Added `envMegabytesLimitFloat` and helper functions to parse and validate limits where -1 is allowed.
- Updated validation logic to accept -1 for `AnonymousMaxUploadMB`, `AnonymousDailyUploadMB`, and `UserDailyUploadMB`.
- Added a test case to verify unlimited upload policy behavior.
This commit is contained in:
2026-05-31 14:01:38 +03:00
parent 61b7c283a4
commit f1c67c455b
12 changed files with 194 additions and 34 deletions

View File

@@ -170,13 +170,13 @@ func (s *SettingsService) UploadPolicy() (UploadPolicySettings, error) {
}
func (s *SettingsService) withDefaultGaps(settings UploadPolicySettings) UploadPolicySettings {
if settings.AnonymousMaxUploadMB <= 0 {
if settings.AnonymousMaxUploadMB == 0 {
settings.AnonymousMaxUploadMB = s.defaults.AnonymousMaxUploadMB
}
if settings.AnonymousDailyUploadMB <= 0 {
if settings.AnonymousDailyUploadMB == 0 {
settings.AnonymousDailyUploadMB = s.defaults.AnonymousDailyUploadMB
}
if settings.UserDailyUploadMB <= 0 {
if settings.UserDailyUploadMB == 0 {
settings.UserDailyUploadMB = s.defaults.UserDailyUploadMB
}
if settings.DefaultUserStorageMB <= 0 {
@@ -370,14 +370,14 @@ func (s *SettingsService) UsageForIP(ip string, now time.Time) (UsageRecord, err
}
func (s *SettingsService) validate(settings UploadPolicySettings) error {
if settings.AnonymousMaxUploadMB <= 0 {
return fmt.Errorf("anonymous max upload must be positive")
if settings.AnonymousMaxUploadMB < 0 && settings.AnonymousMaxUploadMB != -1 || settings.AnonymousMaxUploadMB == 0 {
return fmt.Errorf("anonymous max upload must be positive or -1 for unlimited")
}
if settings.AnonymousDailyUploadMB <= 0 {
return fmt.Errorf("anonymous daily upload must be positive")
if settings.AnonymousDailyUploadMB < 0 && settings.AnonymousDailyUploadMB != -1 || settings.AnonymousDailyUploadMB == 0 {
return fmt.Errorf("anonymous daily upload must be positive or -1 for unlimited")
}
if settings.UserDailyUploadMB <= 0 {
return fmt.Errorf("user daily upload must be positive")
if settings.UserDailyUploadMB < 0 && settings.UserDailyUploadMB != -1 || settings.UserDailyUploadMB == 0 {
return fmt.Errorf("user daily upload must be positive or -1 for unlimited")
}
if settings.DefaultUserStorageMB <= 0 {
return fmt.Errorf("default user storage must be positive")
@@ -422,6 +422,32 @@ func ParseMegabytesValue(value string) (float64, error) {
return parsed, nil
}
func ParseMegabytesLimitValue(value string) (float64, error) {
parsed, err := parseMegabytesNumber(value)
if err != nil {
return 0, err
}
if parsed == -1 {
return -1, nil
}
if parsed <= 0 {
return 0, fmt.Errorf("megabyte value must be positive or -1 for unlimited")
}
return parsed, nil
}
func parseMegabytesNumber(value string) (float64, error) {
value = strings.TrimSpace(value)
if value == "" {
return 0, fmt.Errorf("megabyte value is required")
}
value = strings.TrimSuffix(value, "MB")
value = strings.TrimSuffix(value, "Mb")
value = strings.TrimSuffix(value, "mb")
value = strings.TrimSpace(value)
return strconv.ParseFloat(value, 64)
}
func MegabytesToBytes(value float64) int64 {
return int64(value * 1024 * 1024)
}
@@ -437,6 +463,9 @@ func FormatMegabytesFromBytes(value int64) string {
}
func FormatMegabytesLabel(value float64) string {
if value < 0 {
return "unlimited"
}
return strconv.FormatFloat(value, 'f', -1, 64) + " MB"
}