feat(one-time-downloads): add expiry and retry configuration
Introduce new environment variables to control the behavior of one-time download boxes: - `WARPBOX_ONE_TIME_DOWNLOAD_EXPIRY_SECONDS`: Sets the lifetime of a one-time box after uploads are complete. - `WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE`: Determines whether a box remains available if the ZIP creation or transfer fails. To support these settings, the ZIP delivery process was refactored to use a temporary file. This ensures that a one-time box is only marked as consumed after the file has been successfully transferred to the client, preventing data loss on network interruptions. Additionally, added a `DecorateFiles` helper in the box store to reduce code duplication.
This commit is contained in:
@@ -31,6 +31,7 @@ const (
|
||||
SettingZipDownloadsEnabled = "zip_downloads_enabled"
|
||||
SettingOneTimeDownloadsEnabled = "one_time_downloads_enabled"
|
||||
SettingOneTimeDownloadExpirySecs = "one_time_download_expiry_seconds"
|
||||
SettingOneTimeDownloadRetryFail = "one_time_download_retry_on_failure"
|
||||
SettingRenewOnAccessEnabled = "renew_on_access_enabled"
|
||||
SettingRenewOnDownloadEnabled = "renew_on_download_enabled"
|
||||
SettingDefaultGuestExpirySecs = "default_guest_expiry_seconds"
|
||||
@@ -83,13 +84,14 @@ type Config struct {
|
||||
AdminCookieSecure bool
|
||||
AllowAdminSettingsOverride bool
|
||||
|
||||
GuestUploadsEnabled bool
|
||||
APIEnabled bool
|
||||
ZipDownloadsEnabled bool
|
||||
OneTimeDownloadsEnabled bool
|
||||
OneTimeDownloadExpirySeconds int64
|
||||
RenewOnAccessEnabled bool
|
||||
RenewOnDownloadEnabled bool
|
||||
GuestUploadsEnabled bool
|
||||
APIEnabled bool
|
||||
ZipDownloadsEnabled bool
|
||||
OneTimeDownloadsEnabled bool
|
||||
OneTimeDownloadExpirySeconds int64
|
||||
OneTimeDownloadRetryOnFailure bool
|
||||
RenewOnAccessEnabled bool
|
||||
RenewOnDownloadEnabled bool
|
||||
|
||||
DefaultGuestExpirySeconds int64
|
||||
MaxGuestExpirySeconds int64
|
||||
@@ -113,6 +115,7 @@ var Definitions = []SettingDefinition{
|
||||
{Key: SettingZipDownloadsEnabled, EnvName: "WARPBOX_ZIP_DOWNLOADS_ENABLED", Label: "ZIP downloads enabled", Type: SettingTypeBool, Editable: true},
|
||||
{Key: SettingOneTimeDownloadsEnabled, EnvName: "WARPBOX_ONE_TIME_DOWNLOADS_ENABLED", Label: "One-time downloads enabled", Type: SettingTypeBool, Editable: true},
|
||||
{Key: SettingOneTimeDownloadExpirySecs, EnvName: "WARPBOX_ONE_TIME_DOWNLOAD_EXPIRY_SECONDS", Label: "One-time download expiry seconds", Type: SettingTypeInt64, Editable: true, Minimum: 0},
|
||||
{Key: SettingOneTimeDownloadRetryFail, EnvName: "WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE", Label: "One-time download retry on failure", Type: SettingTypeBool, Editable: false},
|
||||
{Key: SettingRenewOnAccessEnabled, EnvName: "WARPBOX_RENEW_ON_ACCESS_ENABLED", Label: "Renew on access enabled", Type: SettingTypeBool, Editable: true},
|
||||
{Key: SettingRenewOnDownloadEnabled, EnvName: "WARPBOX_RENEW_ON_DOWNLOAD_ENABLED", Label: "Renew on download enabled", Type: SettingTypeBool, Editable: true},
|
||||
{Key: SettingDefaultGuestExpirySecs, EnvName: "WARPBOX_DEFAULT_GUEST_EXPIRY_SECONDS", Label: "Default guest expiry seconds", Type: SettingTypeInt64, Editable: true, Minimum: 0},
|
||||
@@ -129,23 +132,24 @@ var Definitions = []SettingDefinition{
|
||||
|
||||
func Load() (*Config, error) {
|
||||
cfg := &Config{
|
||||
DataDir: "./data",
|
||||
AdminUsername: "admin",
|
||||
AdminEnabled: AdminEnabledAuto,
|
||||
AllowAdminSettingsOverride: true,
|
||||
GuestUploadsEnabled: true,
|
||||
APIEnabled: true,
|
||||
ZipDownloadsEnabled: true,
|
||||
OneTimeDownloadsEnabled: true,
|
||||
OneTimeDownloadExpirySeconds: 7 * 24 * 60 * 60,
|
||||
DefaultGuestExpirySeconds: 10,
|
||||
MaxGuestExpirySeconds: 48 * 60 * 60,
|
||||
SessionTTLSeconds: 24 * 60 * 60,
|
||||
BoxPollIntervalMS: 5000,
|
||||
ThumbnailBatchSize: 10,
|
||||
ThumbnailIntervalSeconds: 30,
|
||||
sources: make(map[string]Source),
|
||||
values: make(map[string]string),
|
||||
DataDir: "./data",
|
||||
AdminUsername: "admin",
|
||||
AdminEnabled: AdminEnabledAuto,
|
||||
AllowAdminSettingsOverride: true,
|
||||
GuestUploadsEnabled: true,
|
||||
APIEnabled: true,
|
||||
ZipDownloadsEnabled: true,
|
||||
OneTimeDownloadsEnabled: true,
|
||||
OneTimeDownloadExpirySeconds: 7 * 24 * 60 * 60,
|
||||
OneTimeDownloadRetryOnFailure: false,
|
||||
DefaultGuestExpirySeconds: 10,
|
||||
MaxGuestExpirySeconds: 48 * 60 * 60,
|
||||
SessionTTLSeconds: 24 * 60 * 60,
|
||||
BoxPollIntervalMS: 5000,
|
||||
ThumbnailBatchSize: 10,
|
||||
ThumbnailIntervalSeconds: 30,
|
||||
sources: make(map[string]Source),
|
||||
values: make(map[string]string),
|
||||
}
|
||||
|
||||
cfg.captureDefaults()
|
||||
@@ -185,6 +189,7 @@ func Load() (*Config, error) {
|
||||
{SettingAPIEnabled, "WARPBOX_API_ENABLED", &cfg.APIEnabled},
|
||||
{SettingZipDownloadsEnabled, "WARPBOX_ZIP_DOWNLOADS_ENABLED", &cfg.ZipDownloadsEnabled},
|
||||
{SettingOneTimeDownloadsEnabled, "WARPBOX_ONE_TIME_DOWNLOADS_ENABLED", &cfg.OneTimeDownloadsEnabled},
|
||||
{SettingOneTimeDownloadRetryFail, "WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE", &cfg.OneTimeDownloadRetryOnFailure},
|
||||
{SettingRenewOnAccessEnabled, "WARPBOX_RENEW_ON_ACCESS_ENABLED", &cfg.RenewOnAccessEnabled},
|
||||
{SettingRenewOnDownloadEnabled, "WARPBOX_RENEW_ON_DOWNLOAD_ENABLED", &cfg.RenewOnDownloadEnabled},
|
||||
}
|
||||
@@ -365,6 +370,7 @@ func (cfg *Config) captureDefaults() {
|
||||
cfg.setValue(SettingZipDownloadsEnabled, formatBool(cfg.ZipDownloadsEnabled), SourceDefault)
|
||||
cfg.setValue(SettingOneTimeDownloadsEnabled, formatBool(cfg.OneTimeDownloadsEnabled), SourceDefault)
|
||||
cfg.setValue(SettingOneTimeDownloadExpirySecs, strconv.FormatInt(cfg.OneTimeDownloadExpirySeconds, 10), SourceDefault)
|
||||
cfg.setValue(SettingOneTimeDownloadRetryFail, formatBool(cfg.OneTimeDownloadRetryOnFailure), SourceDefault)
|
||||
cfg.setValue(SettingRenewOnAccessEnabled, formatBool(cfg.RenewOnAccessEnabled), SourceDefault)
|
||||
cfg.setValue(SettingRenewOnDownloadEnabled, formatBool(cfg.RenewOnDownloadEnabled), SourceDefault)
|
||||
cfg.setValue(SettingDefaultGuestExpirySecs, strconv.FormatInt(cfg.DefaultGuestExpirySeconds, 10), SourceDefault)
|
||||
|
||||
@@ -38,6 +38,7 @@ func TestEnvironmentOverrides(t *testing.T) {
|
||||
t.Setenv("WARPBOX_GLOBAL_MAX_FILE_SIZE_BYTES", "100")
|
||||
t.Setenv("WARPBOX_BOX_POLL_INTERVAL_MS", "2000")
|
||||
t.Setenv("WARPBOX_ADMIN_USERNAME", "root")
|
||||
t.Setenv("WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE", "true")
|
||||
|
||||
cfg, err := Load()
|
||||
if err != nil {
|
||||
@@ -59,6 +60,9 @@ func TestEnvironmentOverrides(t *testing.T) {
|
||||
if cfg.AdminUsername != "root" {
|
||||
t.Fatalf("unexpected admin username: %s", cfg.AdminUsername)
|
||||
}
|
||||
if !cfg.OneTimeDownloadRetryOnFailure {
|
||||
t.Fatal("expected one-time retry-on-failure env override to be applied")
|
||||
}
|
||||
if cfg.Source(SettingAPIEnabled) != SourceEnv {
|
||||
t.Fatalf("expected API setting source to be env, got %s", cfg.Source(SettingAPIEnabled))
|
||||
}
|
||||
@@ -160,6 +164,7 @@ func clearConfigEnv(t *testing.T) {
|
||||
"WARPBOX_API_ENABLED",
|
||||
"WARPBOX_ZIP_DOWNLOADS_ENABLED",
|
||||
"WARPBOX_ONE_TIME_DOWNLOADS_ENABLED",
|
||||
"WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE",
|
||||
"WARPBOX_RENEW_ON_ACCESS_ENABLED",
|
||||
"WARPBOX_RENEW_ON_DOWNLOAD_ENABLED",
|
||||
"WARPBOX_DEFAULT_GUEST_EXPIRY_SECONDS",
|
||||
|
||||
Reference in New Issue
Block a user