feat: add upload policies, daily limits, and storage quotas
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m8s

- Add environment variables to configure anonymous uploads, daily upload caps, and default user storage limits.
- Update config loader to parse and validate the new settings.
- Implement backend logic to track daily usage and active storage per user.
- Update README and `.env.example` to document the new settings and admin panels.
This commit is contained in:
2026-05-30 17:23:20 +03:00
parent 9a3cb90b17
commit d77f164900
29 changed files with 1432 additions and 120 deletions

View File

@@ -28,6 +28,16 @@ type Config struct {
ThumbnailEnabled bool
ThumbnailEvery time.Duration
MaxUploadSize int64
DefaultSettings SettingsDefaults
}
type SettingsDefaults struct {
AnonymousUploadsEnabled bool
AnonymousMaxUploadMB float64
AnonymousDailyUploadMB float64
UserDailyUploadMB float64
DefaultUserStorageMB float64
UsageRetentionDays int
}
func Load() (Config, error) {
@@ -49,6 +59,14 @@ func Load() (Config, error) {
ThumbnailEnabled: envBool("WARPBOX_THUMBNAIL_ENABLED", true),
ThumbnailEvery: envDuration("WARPBOX_THUMBNAIL_EVERY", time.Minute),
MaxUploadSize: envMegabytes("WARPBOX_MAX_UPLOAD_SIZE_MB", 2048), // 2 GiB default.
DefaultSettings: SettingsDefaults{
AnonymousUploadsEnabled: envBool("WARPBOX_ANONYMOUS_UPLOADS_ENABLED", true),
AnonymousMaxUploadMB: envMegabytesFloat("WARPBOX_ANONYMOUS_MAX_UPLOAD_MB", 512),
AnonymousDailyUploadMB: envMegabytesFloat("WARPBOX_ANONYMOUS_DAILY_UPLOAD_MB", 2048),
UserDailyUploadMB: envMegabytesFloat("WARPBOX_USER_DAILY_UPLOAD_MB", 8192),
DefaultUserStorageMB: envMegabytesFloat("WARPBOX_DEFAULT_USER_STORAGE_MB", 51200),
UsageRetentionDays: envInt("WARPBOX_USAGE_RETENTION_DAYS", 30),
},
}
if cfg.BaseURL == "" {
@@ -57,6 +75,13 @@ func Load() (Config, error) {
if cfg.MaxUploadSize <= 0 {
return Config{}, fmt.Errorf("WARPBOX_MAX_UPLOAD_SIZE_MB must be positive")
}
if cfg.DefaultSettings.AnonymousMaxUploadMB <= 0 ||
cfg.DefaultSettings.AnonymousDailyUploadMB <= 0 ||
cfg.DefaultSettings.UserDailyUploadMB <= 0 ||
cfg.DefaultSettings.DefaultUserStorageMB <= 0 ||
cfg.DefaultSettings.UsageRetentionDays <= 0 {
return Config{}, fmt.Errorf("upload policy settings must be positive")
}
return cfg, nil
}
@@ -109,6 +134,19 @@ func envBool(key string, fallback bool) bool {
return parsed
}
func envInt(key string, fallback int) int {
value := strings.TrimSpace(os.Getenv(key))
if value == "" {
return fallback
}
parsed, err := strconv.Atoi(value)
if err != nil {
return fallback
}
return parsed
}
func envMegabytes(key string, fallback float64) int64 {
value := strings.TrimSpace(os.Getenv(key))
if value == "" {
@@ -122,7 +160,27 @@ func envMegabytes(key string, fallback float64) int64 {
return parsed
}
func envMegabytesFloat(key string, fallback float64) float64 {
value := strings.TrimSpace(os.Getenv(key))
if value == "" {
return fallback
}
parsed, err := parseMegabytesFloat(value)
if err != nil {
return fallback
}
return parsed
}
func parseMegabytes(value string) (int64, error) {
sizeMB, err := parseMegabytesFloat(value)
if err != nil {
return 0, err
}
return megabytesToBytes(sizeMB), nil
}
func parseMegabytesFloat(value string) (float64, error) {
normalized := strings.TrimSpace(value)
normalized = strings.TrimSuffix(normalized, "MB")
normalized = strings.TrimSuffix(normalized, "Mb")
@@ -137,7 +195,7 @@ func parseMegabytes(value string) (int64, error) {
return 0, fmt.Errorf("megabyte value must be positive")
}
return megabytesToBytes(sizeMB), nil
return sizeMB, nil
}
func megabytesToBytes(sizeMB float64) int64 {