Ethsim2
(Ethan )
31. August 2026 um 14:28
3
Ich habe nun einen PR dafür erstellt:
main ← Ethsim12:fix-backup-download-resume
opened 12:34PM - 31 Aug 26 UTC
## Summary
Allows interrupted **local** backup downloads to resume with an HT… TP `Range` request after the one-use emailed backup token has been consumed.
This addresses the case reported on Meta where a multi-GB local backup download was interrupted and the browser retried with `Range`, but the retry received `422` because `EmailBackupToken.del` had already consumed the token:
https://meta.discourse.org/t/backup-download-cannot-resume-after-interruption-because-email-token-has-already-been-consumed/411277
## Approach
The existing emailed token remains the only way to initiate a backup download. When resumable local downloads are enabled, the first authorized **local** download creates a narrower resume grant which is scoped to:
* the same authenticated administrator
* the same backup
* the same original emailed token value
* requests carrying a `Range` header
* a bounded expiry window
The original `EmailBackupToken` is still consumed after the initial request. Ordinary reuse of that token for another full download remains rejected, and the resume grant cannot be used for a different backup or user.
Remote/S3 backup downloads keep their existing presigned-URL redirect behavior and do not receive a local resume grant.
A resumed request is treated as a continuation of the same authorized download, so it does not create a second `backup_download` staff action entry.
## Resume window setting
Adds `backup_download_resume_window` as an enum rather than an unrestricted numeric duration, to avoid an administrator accidentally configuring an excessively long authorization window.
Options are:
* `disabled`
* `1_hour`
* `6_hours` — shown as **6 hours (recommended)** in the admin UI
* `12_hours`
* `until_email_token_expires`
The effective resume TTL is capped to the remaining lifetime of the original emailed token when the initial download begins.
The setting integrates with the existing backup settings and is only applicable to local storage:
<img width="960" height="850" alt="Backup download resume window shown beneath the local backup location setting" src="https://github.com/user-attachments/assets/abbbdf04-e2f5-4d7d-b66a-1c73caddd583" />
The available values are deliberately bounded, with the compatibility-preserving default disabled and 6 hours identified as the recommended enabled option:
<img width="341" height="426" alt="Backup download resume window enum showing Disabled, 1 hour, 6 hours recommended, 12 hours, and until the original email token expires" src="https://github.com/user-attachments/assets/4dd3dd5c-50e0-4df3-ac6e-9732b7878227" />
### Default vs recommended value
This PR intentionally distinguishes the **default** from the **recommended enabled option**.
The current Discourse behavior is equivalent to `disabled`: once the emailed token is consumed by the initial request, a subsequent `Range` retry is rejected. To preserve existing behavior for current sites, this PR therefore keeps `disabled` as the default.
For admins who choose to enable resumable local downloads, `6_hours` is labelled as the recommended enum option.
There is precedent for preserving existing behavior when introducing an enum setting in #36014: the previously hard-coded calendar view remained the default value of the new enum setting.
**Maintainer question:** given the concrete interrupted-download case in the linked Meta topic, would you prefer the default to remain `disabled` for backwards compatibility, or should the recommended `6_hours` option become the default as part of fixing the issue?
By “recommended” here I mean the admin-facing recommendation attached to one enum option, not a separate setting or an unrestricted duration value.
## Tests
Added coverage for:
* default/disabled behavior remaining unchanged
* successful same-backup `Range` resume when enabled
* rejection of ordinary token reuse
* rejection of cross-backup resume
* immediate revocation when the setting is disabled
* no local resume grant for S3 backups
* one audit entry across the initial download and resume
* resume-token user/backup scoping and Redis expiry
* enum validation and TTL capping
Local focused test run:
`94 examples, 0 failures`
Ruby, YAML, and i18n linters also pass.
Die Implementierung behält den bestehenden Einmal-Token per E-Mail bei, der zum Starten des Downloads verwendet wird, und ermöglicht lokalen Backups, eine separate, begrenzte Fortsetzungsautorisierung zu erstellen, die auf Folgendes beschränkt ist:
denselben authentifizierten Administrator;
dasselbe Backup;
denselben ursprünglichen Token-Wert; und
eine nachfolgende Anfrage mit einem Range-Header.
Eine gewöhnliche zweite vollständige GET-Anfrage mit dem verbrauchten Token wird weiterhin abgelehnt, ebenso wie eine Range-Anfrage für ein anderes Backup. Remote-/S3-Backups behalten ihr bestehendes Verhalten bei.
Ich habe die Fortsetzungszeit als Enum statt als unbegrenzte Dauer definiert:
Die effektive Fortsetzungszeit wird zudem auf die verbleibende Lebensdauer des ursprünglichen E-Mail-Tokens begrenzt, wenn der anfängliche Download beginnt.
Das aktuelle Discourse-Verhalten bleibt aus Gründen der Abwärtskompatibilität der Standardwert (Disabled), während 6 hours als empfohlene Option dargestellt wird, wenn herunterladbare Fortsetzungen aktiviert sind.
Der PR fragt, ob die Maintainer diesen die Kompatibilität erhaltenden Standardwert beibehalten oder den empfohlenen Fortsetzungswert als Standardwert festlegen möchten, um dieses Problem zu beheben.
Ich habe auch Regressionsabdeckung für den erfolgreichen Fortsetzungspfad und die wichtigsten Autorisierungsgrenzen hinzugefügt, einschließlich:
gewöhnliche Token-Wiederverwendung bleibt abgelehnt;
Cross-Backup-Fortsetzung bleibt abgelehnt;
Deaktivieren der Einstellung verhindert sofort weitere Fortsetzungen;
S3 erhält keine lokale Fortsetzungsautorisierung; und
der anfängliche Download und seine Fortsetzung erzeugen nur einen einzigen Backup-Download-Audit-Eintrag.
Die vollständige CI-Suite ist bestanden und der PR ist bereit zur Überprüfung.
Feedback zum Sicherheitsmodell, insbesondere zur Empfehlung von 6 Stunden und zur Standardeinstellung, wäre willkommen.