Implements a master toggle for security features across config, CLI, and application logic. This allows granular control over whether the advanced security middleware and protections are active globally.
194 lines
5.3 KiB
Go
194 lines
5.3 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"warpbox/lib/security"
|
|
)
|
|
|
|
func (cfg *Config) ApplyOverrides(overrides map[string]string) error {
|
|
if !cfg.AllowAdminSettingsOverride {
|
|
return nil
|
|
}
|
|
for key, value := range overrides {
|
|
if err := cfg.ApplyOverride(key, value); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (cfg *Config) ApplyOverride(key string, value string) error {
|
|
def, ok := Definition(key)
|
|
if !ok {
|
|
return fmt.Errorf("unknown setting %q", key)
|
|
}
|
|
if !def.Editable || def.HardLimit {
|
|
return fmt.Errorf("setting %q cannot be changed from the admin UI", key)
|
|
}
|
|
|
|
value = strings.TrimSpace(value)
|
|
if err := validateSecurityTextSetting(key, value); err != nil {
|
|
return err
|
|
}
|
|
|
|
switch def.Type {
|
|
case SettingTypeBool:
|
|
parsed, err := parseBool(value)
|
|
if err != nil {
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
}
|
|
cfg.assignBool(key, parsed, SourceDB)
|
|
case SettingTypeInt64:
|
|
parsed, err := parseInt64(value, def.Minimum)
|
|
if err != nil {
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
}
|
|
cfg.assignInt64(key, parsed, SourceDB)
|
|
case SettingTypeSizeGB:
|
|
parsed, err := parseGigabytes(value, float64(def.Minimum))
|
|
if err != nil {
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
}
|
|
cfg.assignInt64(key, parsed, SourceDB)
|
|
case SettingTypeInt:
|
|
parsed64, err := parseInt64(value, def.Minimum)
|
|
if err != nil {
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
}
|
|
cfg.assignInt(key, int(parsed64), SourceDB)
|
|
case SettingTypeText:
|
|
cfg.assignText(key, value, SourceDB)
|
|
default:
|
|
return fmt.Errorf("setting %q is not runtime editable", key)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateSecurityTextSetting(key string, value string) error {
|
|
switch key {
|
|
case SettingSecurityIPWhitelist, SettingSecurityAdminIPWhitelist:
|
|
if _, err := security.ParseIPMatchers(value, true); err != nil {
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
}
|
|
case SettingTrustedProxyCIDRs:
|
|
if _, err := security.ParseCIDRList(value); err != nil {
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (cfg *Config) assignBool(key string, value bool, source Source) {
|
|
switch key {
|
|
case SettingGuestUploadsEnabled:
|
|
cfg.GuestUploadsEnabled = value
|
|
case SettingAPIEnabled:
|
|
cfg.APIEnabled = value
|
|
case SettingZipDownloadsEnabled:
|
|
cfg.ZipDownloadsEnabled = value
|
|
case SettingOneTimeDownloadsEnabled:
|
|
cfg.OneTimeDownloadsEnabled = value
|
|
case SettingRenewOnAccessEnabled:
|
|
cfg.RenewOnAccessEnabled = value
|
|
case SettingRenewOnDownloadEnabled:
|
|
cfg.RenewOnDownloadEnabled = value
|
|
case SettingSecurityEnabled:
|
|
cfg.SecurityEnabled = value
|
|
}
|
|
cfg.setValue(key, formatBool(value), source)
|
|
}
|
|
|
|
func (cfg *Config) assignInt64(key string, value int64, source Source) {
|
|
switch key {
|
|
case SettingDefaultGuestExpirySecs:
|
|
cfg.DefaultGuestExpirySeconds = value
|
|
case SettingMaxGuestExpirySecs:
|
|
cfg.MaxGuestExpirySeconds = value
|
|
case SettingOneTimeDownloadExpirySecs:
|
|
cfg.OneTimeDownloadExpirySeconds = value
|
|
case SettingGlobalMaxFileSizeBytes:
|
|
cfg.GlobalMaxFileSizeBytes = value
|
|
case SettingGlobalMaxBoxSizeBytes:
|
|
cfg.GlobalMaxBoxSizeBytes = value
|
|
case SettingDefaultUserMaxFileBytes:
|
|
cfg.DefaultUserMaxFileSizeBytes = value
|
|
case SettingDefaultUserMaxBoxBytes:
|
|
cfg.DefaultUserMaxBoxSizeBytes = value
|
|
case SettingSessionTTLSeconds:
|
|
cfg.SessionTTLSeconds = value
|
|
case SettingActivityRetentionSeconds:
|
|
cfg.ActivityRetentionSeconds = value
|
|
case SettingSecurityLoginWindowSecs:
|
|
cfg.SecurityLoginWindowSeconds = value
|
|
case SettingSecurityBanSeconds:
|
|
cfg.SecurityBanSeconds = value
|
|
case SettingSecurityScanWindowSecs:
|
|
cfg.SecurityScanWindowSeconds = value
|
|
case SettingSecurityUploadWindowSecs:
|
|
cfg.SecurityUploadWindowSeconds = value
|
|
case SettingSecurityUploadMaxGB:
|
|
cfg.SecurityUploadMaxBytes = value
|
|
}
|
|
if key == SettingGlobalMaxFileSizeBytes || key == SettingGlobalMaxBoxSizeBytes || key == SettingDefaultUserMaxFileBytes || key == SettingDefaultUserMaxBoxBytes || key == SettingSecurityUploadMaxGB {
|
|
cfg.setValue(key, formatGigabytesFromBytes(value), source)
|
|
return
|
|
}
|
|
cfg.setValue(key, strconv.FormatInt(value, 10), source)
|
|
}
|
|
|
|
func (cfg *Config) assignInt(key string, value int, source Source) {
|
|
switch key {
|
|
case SettingBoxPollIntervalMS:
|
|
cfg.BoxPollIntervalMS = value
|
|
case SettingThumbnailBatchSize:
|
|
cfg.ThumbnailBatchSize = value
|
|
case SettingThumbnailIntervalSeconds:
|
|
cfg.ThumbnailIntervalSeconds = value
|
|
case SettingSecurityLoginMaxAttempts:
|
|
cfg.SecurityLoginMaxAttempts = value
|
|
case SettingSecurityScanMaxAttempts:
|
|
cfg.SecurityScanMaxAttempts = value
|
|
case SettingSecurityUploadMaxRequests:
|
|
cfg.SecurityUploadMaxRequests = value
|
|
}
|
|
cfg.setValue(key, strconv.Itoa(value), source)
|
|
}
|
|
|
|
func (cfg *Config) assignText(key string, value string, source Source) {
|
|
switch key {
|
|
case SettingSecurityIPWhitelist:
|
|
cfg.SecurityIPWhitelist = value
|
|
case SettingSecurityAdminIPWhitelist:
|
|
cfg.SecurityAdminIPWhitelist = value
|
|
case SettingTrustedProxyCIDRs:
|
|
cfg.TrustedProxyCIDRs = value
|
|
}
|
|
cfg.setValue(key, value, source)
|
|
}
|
|
|
|
func (cfg *Config) setValue(key string, value string, source Source) {
|
|
if key == "" {
|
|
return
|
|
}
|
|
cfg.values[key] = value
|
|
cfg.sources[key] = source
|
|
}
|
|
|
|
func (cfg *Config) sourceFor(key string) Source {
|
|
source, ok := cfg.sources[key]
|
|
if !ok {
|
|
return SourceDefault
|
|
}
|
|
return source
|
|
}
|
|
|
|
func (cfg *Config) DefaultValue(key string) string {
|
|
if cfg.defaults == nil {
|
|
return ""
|
|
}
|
|
return cfg.defaults[key]
|
|
}
|