Review fixes: the longest deletion delay when the location's settings cannot be read, a damaged passphrase slot does not stop the next one
CI / unit (8.2) (push) Has been cancelled
CI / unit (8.3) (push) Has been cancelled
CI / unit (8.4) (push) Has been cancelled
CI / psalm (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / integration (mariadb, 32) (push) Has been cancelled
CI / integration (mariadb, 33) (push) Has been cancelled
CI / integration (mariadb, 34) (push) Has been cancelled
CI / integration (mariadb, 35) (push) Has been cancelled
CI / integration (pgsql, 32) (push) Has been cancelled
CI / integration (pgsql, 33) (push) Has been cancelled
CI / integration (pgsql, 34) (push) Has been cancelled
CI / integration (pgsql, 35) (push) Has been cancelled
CI / integration (sqlite, 32) (push) Has been cancelled
CI / integration (sqlite, 33) (push) Has been cancelled
CI / integration (sqlite, 34) (push) Has been cancelled
CI / integration (sqlite, 35) (push) Has been cancelled
CI / integration-targets (push) Has been cancelled
CI / integration-user (32) (push) Has been cancelled
CI / integration-user (33) (push) Has been cancelled
CI / integration-user (34) (push) Has been cancelled
CI / integration-user (35) (push) Has been cancelled
CI / integration-full-restore (push) Has been cancelled
CI / unit (8.2) (push) Has been cancelled
CI / unit (8.3) (push) Has been cancelled
CI / unit (8.4) (push) Has been cancelled
CI / psalm (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / integration (mariadb, 32) (push) Has been cancelled
CI / integration (mariadb, 33) (push) Has been cancelled
CI / integration (mariadb, 34) (push) Has been cancelled
CI / integration (mariadb, 35) (push) Has been cancelled
CI / integration (pgsql, 32) (push) Has been cancelled
CI / integration (pgsql, 33) (push) Has been cancelled
CI / integration (pgsql, 34) (push) Has been cancelled
CI / integration (pgsql, 35) (push) Has been cancelled
CI / integration (sqlite, 32) (push) Has been cancelled
CI / integration (sqlite, 33) (push) Has been cancelled
CI / integration (sqlite, 34) (push) Has been cancelled
CI / integration (sqlite, 35) (push) Has been cancelled
CI / integration-targets (push) Has been cancelled
CI / integration-user (32) (push) Has been cancelled
CI / integration-user (33) (push) Has been cancelled
CI / integration-user (34) (push) Has been cancelled
CI / integration-user (35) (push) Has been cancelled
CI / integration-full-restore (push) Has been cancelled
- Unreadable settings or an invalid delay on the location: 365 days, so nothing leaves the Bin sooner than on the old server - A passphrase change that still cannot reach a location is logged; removing a location clears its flag - A damaged slot (missing parts, invalid base64) is skipped and the next slot is tried - Tests: damaged settings scenario, damaged slot, upgrade test checks the migration and the time zone
This commit is contained in:
@@ -34,6 +34,20 @@ class KeyRingTest extends TestCase {
|
||||
new KeyRing('short');
|
||||
}
|
||||
|
||||
public function testADamagedSlotDoesNotStopTheNextOne(): void {
|
||||
$keys = KeyRing::generate();
|
||||
$broken = $keys->wrap('passphrase in the safe');
|
||||
$broken['salt'] = '*** not base64 ***';
|
||||
$field = ['slots' => [
|
||||
['slot' => 1, 'label' => 'Safe', 'key' => $broken],
|
||||
['slot' => 2, 'label' => 'Missing parts', 'key' => ['v' => 1]],
|
||||
['slot' => 3, 'label' => 'CTO', 'key' => $keys->wrap('passphrase of the cto')],
|
||||
]];
|
||||
$this->assertSame($keys->blobId('x'), KeyRing::unwrapAny($field, 'passphrase of the cto')->blobId('x'));
|
||||
$this->expectException(CryptoException::class);
|
||||
KeyRing::unwrapAny($field, 'passphrase in the safe');
|
||||
}
|
||||
|
||||
public function testAnySlotOpensTheSameKey(): void {
|
||||
$keys = KeyRing::generate();
|
||||
$field = ['slots' => [
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
# changes nothing; backups wait for a new kit
|
||||
# no-kit-old as no-kit, on a location backed up only before 1.1.0 (no settings file):
|
||||
# the deletion delay is the default, and the admin is told so
|
||||
# no-kit-damaged as no-kit, with a damaged settings file: the longest deletion delay, and why
|
||||
# no-config-no-kit the location's config is gone and there is no kit: told that only the kit helps
|
||||
# no-config-kit config gone, kit there: --repair-config writes it again, the backups open
|
||||
# other-kit the kit of another server: refused, told to use the old server's kit
|
||||
@@ -150,6 +151,15 @@ expect "$OUT" "7 days (the default" "no-kit-old: the default delay and why"
|
||||
docker exec ngb-rs-new test -f /mnt/shared/no-kit-old/repo/settings || fail "no-kit-old: the settings were not written when the location was added"
|
||||
ok "no-kit-old: key from the location, default delay with the reason, settings written now"
|
||||
|
||||
# no-kit-damaged: the settings file is there but damaged: the longest delay, and the admin is told
|
||||
scenario no-kit-damaged
|
||||
docker exec ngb-rs-new sh -c 'rm /tmp/kit.json && printf garbage >> /mnt/shared/no-kit-damaged/repo/settings'
|
||||
# shellcheck disable=SC2046
|
||||
OUT=$(run_on ngb-rs-new backup:target:add offsite $(location no-kit-damaged) --passphrase-file=/tmp/pass 2>&1) || { printf '%s\n' "$OUT"; fail "no-kit-damaged: target add"; }
|
||||
expect "$OUT" "fingerprint $FP" "no-kit-damaged"
|
||||
expect "$OUT" "365 days (the longest" "no-kit-damaged: the longest delay and why"
|
||||
ok "no-kit-damaged: key from the location, the longest delay with the reason"
|
||||
|
||||
# no-config-no-kit
|
||||
scenario no-config-no-kit
|
||||
docker exec ngb-rs-new rm /tmp/kit.json /mnt/shared/no-config-no-kit/repo/config
|
||||
|
||||
@@ -56,6 +56,7 @@ occ backup:key:kit --output=/tmp/kit.json >/dev/null
|
||||
CODE=$(occ backup:key:kit | php -r 'echo json_decode(stream_get_contents(STDIN), true)["confirmation_code"];')
|
||||
occ backup:key:confirm -u admin --code="$CODE" --confirm="Yes, I confirm" >/dev/null || fail "confirm"
|
||||
occ config:app:set ng_backup schedule_time --value=03:15 >/dev/null
|
||||
occ config:app:set ng_backup schedule_timezone --value=America/Toronto >/dev/null
|
||||
occ backup:target:add offsite local -a null::null -o datadir=/mnt/shared/loc --path=repo >/dev/null || fail "target add"
|
||||
docker exec -u www-data $N sh -c 'mkdir -p data/admin/files/Docs && head -c 3000000 /dev/urandom > data/admin/files/Docs/before.bin'
|
||||
occ files:scan admin >/dev/null
|
||||
@@ -76,9 +77,12 @@ OUT=$(occ upgrade 2>&1) || { printf '%s\n' "$OUT"; fail "occ upgrade"; }
|
||||
VER=$(occ app:list --output=json | php -r '$a = json_decode(stream_get_contents(STDIN), true); echo $a["enabled"]["ng_backup"] ?? "";')
|
||||
[ -z "$NEWVER" ] || [ "$VER" = "$NEWVER" ] || fail "after the upgrade the app has version '$VER'"
|
||||
ok "occ upgrade to $VER"
|
||||
# Before anything else touches the key: only the migration can have marked it as used
|
||||
[ "$(occ config:app:get ng_backup master_key_used 2>/dev/null)" = 1 ] || [ "$(occ config:app:get ng_backup master_key_used 2>/dev/null)" = true ] || fail "the migration did not mark the key from before the upgrade as used"
|
||||
ok "the key from before the upgrade counts as used"
|
||||
|
||||
SCHED=$(occ backup:target:schedule offsite)
|
||||
printf '%s\n' "$SCHED" | grep -q "^offsite: 03:15 " || { printf '%s\n' "$SCHED"; fail "the location did not keep 03:15 as its schedule"; }
|
||||
printf '%s\n' "$SCHED" | grep -qx "offsite: 03:15 (America/Toronto)" || { printf '%s\n' "$SCHED"; fail "the location did not keep 03:15 as its schedule"; }
|
||||
occ backup:list offsite | grep -q "$OLDSNAP" || fail "the old restore point is not listed"
|
||||
occ backup:verify offsite "$OLDSNAP" >/dev/null || fail "the old restore point does not verify"
|
||||
occ backup:status >/dev/null || fail "backup:status"
|
||||
|
||||
Reference in New Issue
Block a user