Add permission update jobs
This commit is contained in:
@@ -211,6 +211,33 @@ function unav_guard_destination(string $source, string $destination): void {
|
||||
}
|
||||
}
|
||||
|
||||
function unav_permission_options(array $data): array {
|
||||
$mode = trim((string)($data['mode'] ?? ''));
|
||||
$owner = trim((string)($data['owner'] ?? ''));
|
||||
$group = trim((string)($data['group'] ?? ''));
|
||||
$recursive = filter_var($data['recursive'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if ($mode === '' && $owner === '' && $group === '') {
|
||||
unav_error(400, 'No permission changes requested');
|
||||
}
|
||||
if ($mode !== '' && !preg_match('/^[0-7]{3,4}$/', $mode)) {
|
||||
unav_error(400, 'Invalid permission mode');
|
||||
}
|
||||
if ($owner !== '' && !preg_match('/^[A-Za-z0-9._-]+$/', $owner)) {
|
||||
unav_error(400, 'Invalid owner');
|
||||
}
|
||||
if ($group !== '' && !preg_match('/^[A-Za-z0-9._-]+$/', $group)) {
|
||||
unav_error(400, 'Invalid group');
|
||||
}
|
||||
|
||||
return [
|
||||
'mode' => $mode === '' ? null : $mode,
|
||||
'owner' => $owner === '' ? null : $owner,
|
||||
'group' => $group === '' ? null : $group,
|
||||
'recursive' => $recursive,
|
||||
];
|
||||
}
|
||||
|
||||
function unav_job_dir(): string {
|
||||
if (!is_dir(UNAV_JOB_DIR) && !mkdir(UNAV_JOB_DIR, 0777, true) && !is_dir(UNAV_JOB_DIR)) {
|
||||
unav_error(500, 'Could not create job directory');
|
||||
|
||||
@@ -6,17 +6,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
|
||||
$action = $_GET['action'] ?? '';
|
||||
if (!in_array($action, ['move', 'copy', 'size'], true)) {
|
||||
if (!in_array($action, ['move', 'copy', 'size', 'permissions'], true)) {
|
||||
unav_error(404, 'Unknown job action');
|
||||
}
|
||||
|
||||
$data = unav_request_data();
|
||||
$source = unav_existing_path($data['source'] ?? null);
|
||||
$destination = null;
|
||||
$permissions = null;
|
||||
if (in_array($action, ['move', 'copy'], true)) {
|
||||
unav_assert_writable();
|
||||
$destination = unav_destination_path($data['destination'] ?? null);
|
||||
unav_guard_destination($source['path'], $destination['path']);
|
||||
} elseif ($action === 'permissions') {
|
||||
unav_assert_writable();
|
||||
$permissions = unav_permission_options($data);
|
||||
}
|
||||
|
||||
$id = str_replace('.', '', uniqid($action . '-', true));
|
||||
@@ -30,6 +34,7 @@ $job = [
|
||||
'error' => null,
|
||||
'source' => $source['path'],
|
||||
'destination' => $destination['path'] ?? null,
|
||||
'permissions' => $permissions,
|
||||
'createdAt' => $now,
|
||||
'updatedAt' => $now,
|
||||
];
|
||||
|
||||
@@ -19,6 +19,8 @@ function unav_run_job(string $id): void {
|
||||
} elseif ($job['type'] === 'size') {
|
||||
$result = unav_worker_size($job['source'], $job);
|
||||
$job['result'] = $result;
|
||||
} elseif ($job['type'] === 'permissions') {
|
||||
unav_worker_permissions($job['source'], $job['permissions'] ?? [], $job);
|
||||
} else {
|
||||
throw new RuntimeException('Unknown job action');
|
||||
}
|
||||
@@ -120,6 +122,57 @@ function unav_worker_size_recursive(string $path): array {
|
||||
return $total;
|
||||
}
|
||||
|
||||
function unav_worker_permissions(string $source, array $options, array &$job): void {
|
||||
$sourceReal = unav_worker_guard_source($source);
|
||||
$mode = $options['mode'] ?? null;
|
||||
$owner = $options['owner'] ?? null;
|
||||
$group = $options['group'] ?? null;
|
||||
$recursive = filter_var($options['recursive'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if ($mode === null && $owner === null && $group === null) {
|
||||
throw new RuntimeException('No permission changes requested');
|
||||
}
|
||||
|
||||
unav_worker_update($job, 'running', 10, 'Updating permissions');
|
||||
$count = 0;
|
||||
unav_worker_permissions_apply($sourceReal, $mode, $owner, $group, $recursive, $job, $count);
|
||||
$job['result'] = ['changed' => $count];
|
||||
unav_worker_update($job, 'running', 95, 'Permissions updated');
|
||||
}
|
||||
|
||||
function unav_worker_permissions_apply(string $path, ?string $mode, ?string $owner, ?string $group, bool $recursive, array &$job, int &$count): void {
|
||||
if (is_link($path)) {
|
||||
return;
|
||||
}
|
||||
if (!file_exists($path)) {
|
||||
throw new RuntimeException('Path not found');
|
||||
}
|
||||
|
||||
if ($mode !== null && !chmod($path, intval($mode, 8))) {
|
||||
throw new RuntimeException('Could not change permissions');
|
||||
}
|
||||
if ($owner !== null && !chown($path, $owner)) {
|
||||
throw new RuntimeException('Could not change owner');
|
||||
}
|
||||
if ($group !== null && !chgrp($path, $group)) {
|
||||
throw new RuntimeException('Could not change group');
|
||||
}
|
||||
$count++;
|
||||
if ($count % 100 === 0) {
|
||||
unav_worker_update($job, 'running', 50, 'Updating permissions');
|
||||
}
|
||||
|
||||
if (!$recursive || !is_dir($path)) {
|
||||
return;
|
||||
}
|
||||
foreach (scandir($path) ?: [] as $entry) {
|
||||
if ($entry === '.' || $entry === '..') {
|
||||
continue;
|
||||
}
|
||||
unav_worker_permissions_apply($path . '/' . $entry, $mode, $owner, $group, true, $job, $count);
|
||||
}
|
||||
}
|
||||
|
||||
function unav_worker_copy(string $source, string $destination, array &$job): void {
|
||||
if (is_link($source)) {
|
||||
throw new RuntimeException('Copying symlinks is not allowed');
|
||||
|
||||
Reference in New Issue
Block a user