mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-20 09:03:43 +02:00
fix(backup): say when a restored archive lands without an owner (#2656)
`created_by_id` is not attribution, it is the column the access check runs on: `_ensure_archive_visible` fails closed on NULL, so an ownerless archive is a 404 for every caller without `archives:read_all` and never appears in the ownership-scoped list queries. On the overwrite path an absent key correctly leaves the local owner alone — that rule is deliberate and unchanged. On the insert path there is no local row to fall back on, so the archive lands ownerless, and nothing said so. The restore reported N archives restored while the user who asked for them saw none. Two ways in, both silent: a commit taken before the collector recorded the column (every pre-#2656 backup), and an archive that genuinely had no owner on the source instance. Adds `archivesOwnerUnknown`, emitted on insert only, and suppressed when the stale-id branch has already spoken for that row so one cause does not produce two notes. Wording mirrors `archivesOwnerCleared` because the consequence and the remedy are the same; the cause is not, so it is a separate code rather than a reuse. Five tests, plus the existing `test_a_backup_without_the_key_still_restores` renamed and tightened — it asserted the silence this fixes. 13 locales back in parity at 5772 leaves. No modal change: notes render through `translateCoded`, which resolves by code.
This commit is contained in:
@@ -1017,6 +1017,7 @@ class GitHubRestoreService:
|
||||
# column was added to fix) and silently un-delete a row the user
|
||||
# deleted. So only carry a column the backup actually knows about;
|
||||
# on insert, an absent key just takes the model default.
|
||||
owner_cleared = False
|
||||
if "created_by_id" in entry:
|
||||
created_by_id = entry.get("created_by_id")
|
||||
if created_by_id is not None and created_by_id not in valid_users:
|
||||
@@ -1030,6 +1031,7 @@ class GitHubRestoreService:
|
||||
"visible only to users with the archives:read_all permission until an admin reassigns them",
|
||||
)
|
||||
created_by_id = None
|
||||
owner_cleared = True
|
||||
fields["created_by_id"] = created_by_id
|
||||
if "deleted_at" in entry:
|
||||
# A soft-deleted archive is still in the backup (its row is kept
|
||||
@@ -1065,6 +1067,24 @@ class GitHubRestoreService:
|
||||
)
|
||||
warned_files = True
|
||||
|
||||
# Insert-only, and the mirror of the "absent is not null" rule above:
|
||||
# on overwrite an unknown owner correctly leaves the local one alone,
|
||||
# but there is no local row here to fall back on, so the archive
|
||||
# lands ownerless — a 404 for everyone without archives:read_all.
|
||||
# Two ways to get here: a commit taken before the collector recorded
|
||||
# the column (every pre-#2656 backup), or an archive that genuinely
|
||||
# had no owner on the source instance. Both restore fine and both
|
||||
# were silent, so the tally said "N archives restored" while the user
|
||||
# who asked for them saw none. The stale-id case above already said
|
||||
# its piece; don't say it twice for the same row.
|
||||
if fields.get("created_by_id") is None and not owner_cleared:
|
||||
tally.note(
|
||||
"archivesOwnerUnknown",
|
||||
"Some archives were restored without an owner — this backup does not record one, so they "
|
||||
"are visible only to users with the archives:read_all permission until an admin reassigns "
|
||||
"them",
|
||||
)
|
||||
|
||||
row = PrintArchive(
|
||||
filename=entry.get("filename") or "restored-from-backup",
|
||||
file_path="",
|
||||
|
||||
Reference in New Issue
Block a user