b9e8858d76
- notifications to administrators for failed backup/restore runs and locations without a successful backup for two days (once a day) - setup check in the admin overview: error when the key/kit is not set up, warning for missing, old or failed backups - security events (recovery kit downloaded, location removed, append-only turned off, retention changed, snapshots forgotten) go to the audit log and are announced to all administrators, from the web and from occ; the scheduled weekly cleanup is logged only - fix: the recovery-kit download link failed the CSRF check (412); it now requires a recent password confirmation instead, like creating the key, removing a location and restoring
69 lines
2.3 KiB
PHP
69 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
// SPDX-FileCopyrightText: 2026 Dillard Blom
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
namespace OCA\NgBackup\SetupCheck;
|
|
|
|
use OCA\NgBackup\Db\Run;
|
|
use OCA\NgBackup\Db\RunMapper;
|
|
use OCA\NgBackup\Service\AlertService;
|
|
use OCA\NgBackup\Service\BackupService;
|
|
use OCA\NgBackup\Service\KeyService;
|
|
use OCA\NgBackup\Service\TargetService;
|
|
use OCP\IL10N;
|
|
use OCP\IURLGenerator;
|
|
use OCP\SetupCheck\ISetupCheck;
|
|
use OCP\SetupCheck\SetupResult;
|
|
|
|
/** Shows the backup state in the admin overview (Security & setup warnings). */
|
|
class BackupStatusCheck implements ISetupCheck {
|
|
public function __construct(
|
|
private IL10N $l,
|
|
private IURLGenerator $url,
|
|
private KeyService $keys,
|
|
private TargetService $targets,
|
|
private RunMapper $runs,
|
|
) {
|
|
}
|
|
|
|
public function getCategory(): string {
|
|
return 'system';
|
|
}
|
|
|
|
public function getName(): string {
|
|
return $this->l->t('NG Backup');
|
|
}
|
|
|
|
public function run(): SetupResult {
|
|
$link = $this->url->linkToRouteAbsolute('settings.AdminSettings.index', ['section' => 'ng_backup']);
|
|
if (!$this->keys->isInitialized() || $this->keys->recoveryKitConfirmation() === null) {
|
|
return SetupResult::error($this->l->t('Backups are not set up: create the backup key and confirm the recovery kit.'), $link);
|
|
}
|
|
$targets = $this->targets->list();
|
|
if ($targets === []) {
|
|
return SetupResult::warning($this->l->t('No backup location is configured.'), $link);
|
|
}
|
|
$problems = [];
|
|
foreach ($targets as $t) {
|
|
$last = $this->runs->lastFinished($t->getId(), BackupService::KIND_FULL);
|
|
if ($last === null) {
|
|
$problems[] = $this->l->t('%s: no successful backup yet', [$t->getName()]);
|
|
} elseif (time() - (int)$last->getFinishedAt() > AlertService::STALE_AFTER) {
|
|
$problems[] = $this->l->t('%1$s: last successful backup %2$s', [$t->getName(), date('Y-m-d H:i', (int)$last->getFinishedAt())]);
|
|
}
|
|
}
|
|
foreach ($this->runs->findRecent(10) as $r) {
|
|
if ($r->getStatus() === Run::FAILED && $r->getStartedAt() > time() - AlertService::STALE_AFTER) {
|
|
$problems[] = $this->l->t('A %1$s run failed: %2$s', [$r->getKind(), mb_strimwidth((string)$r->getError(), 0, 120, '…')]);
|
|
break;
|
|
}
|
|
}
|
|
return $problems === []
|
|
? SetupResult::success($this->l->t('Recent backups to all locations succeeded.'))
|
|
: SetupResult::warning(implode("\n", $problems), $link);
|
|
}
|
|
}
|