M4: admin settings page and JSON API
- AdminApiController (admin only, CSRF-protected): status, create key, download recovery kit, confirm (statement accepted + exact phrase), backends with their usable auth mechanisms, add/test/remove locations, start backups, schedule, snapshots, browse, queue restores - RestoreJob runs web-initiated restores in the background; backup and restore runs are kept apart in the run table - admin section 'NG Backup' with a Vue 3 / @nextcloud/vue 9 page: key and recovery-kit flow (download, tick statement, 'Yes, I confirm'), location form built from files_external's parameter definitions, schedule, run list with polling, snapshot browser and restore with the three modes - auth mechanisms that depend on a user session or on files_external's own stored credentials are not offered API tested with curl on NC34 (status, backends, schedule validation, confirmation refusal, browse, queued restore and backup completed by cron); non-admins get 403, anonymous 401.
This commit is contained in:
@@ -26,16 +26,32 @@ final class ExternalStorageFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{id:string, name:string, auth:list<string>, parameters:array<string, mixed>}>
|
||||
* @return list<array{id:string, name:string, auth:list<array{id:string, name:string, parameters:array}>, parameters:array<string, mixed>}>
|
||||
* available backends, to build the settings form from
|
||||
*/
|
||||
public function describeBackends(): array {
|
||||
$result = [];
|
||||
foreach ($this->backends->getAvailableBackends() as $backend) {
|
||||
$auth = [];
|
||||
foreach ($this->backends->getAuthMechanismsByScheme(array_keys($backend->getAuthSchemes())) as $mech) {
|
||||
// Mechanisms that need the logged-in user's session cannot work for unattended backups.
|
||||
if (in_array($mech->getScheme(), ['builtin', 'null'], true) && $mech->getIdentifier() !== 'null::null') {
|
||||
continue;
|
||||
}
|
||||
if (str_starts_with($mech->getIdentifier(), 'password::session') || str_starts_with($mech->getIdentifier(), 'password::logincredentials')
|
||||
|| str_starts_with($mech->getIdentifier(), 'password::userprovided') || str_starts_with($mech->getIdentifier(), 'password::global')) {
|
||||
continue;
|
||||
}
|
||||
$auth[] = [
|
||||
'id' => $mech->getIdentifier(),
|
||||
'name' => $mech->getText(),
|
||||
'parameters' => array_map(fn ($p) => $p->jsonSerialize(), $mech->getParameters()),
|
||||
];
|
||||
}
|
||||
$result[] = [
|
||||
'id' => $backend->getIdentifier(),
|
||||
'name' => $backend->getText(),
|
||||
'auth' => array_keys($backend->getAuthSchemes()),
|
||||
'auth' => $auth,
|
||||
'parameters' => array_map(fn ($p) => $p->jsonSerialize(), $backend->getParameters()),
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user