#!/usr/bin/env php * php custom/tools/set-publiser-password.php (interactive) * php custom/tools/set-publiser-password.php --remove * php custom/tools/set-publiser-password.php --list */ $htpasswdPath = dirname(__DIR__, 2) . '/content/publiser/.htpasswd'; function prompt(string $question): string { echo $question; return trim(fgets(STDIN)); } function promptHidden(string $question): string { $isWindows = stripos(PHP_OS, 'WIN') === 0; if (!$isWindows) { system('stty -echo'); } $value = prompt($question); if (!$isWindows) { system('stty echo'); echo "\n"; } return $value; } function readUsers(string $path): array { if (!is_file($path)) return []; $users = []; foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [] as $line) { [$user, $hash] = array_pad(explode(':', $line, 2), 2, ''); if ($user !== '') $users[$user] = $hash; } return $users; } function writeUsers(string $path, array $users): void { $lines = []; foreach ($users as $user => $hash) { $lines[] = "$user:$hash"; } file_put_contents($path, $lines ? implode("\n", $lines) . "\n" : ''); // World-readable: the web server user (www-data, varies by host/container) // needs read access. This is safe - Apache denies direct HTTP access to // this exact filename (content/publiser/.htaccess), and reaching it any // other way already requires shell/filesystem access to the server. chmod($path, 0644); } $args = array_slice($argv, 1); if (($args[0] ?? '') === '--list') { $users = array_keys(readUsers($htpasswdPath)); echo $users ? implode("\n", $users) . "\n" : "No users configured yet.\n"; exit(0); } if (($args[0] ?? '') === '--remove') { $username = $args[1] ?? prompt('Username to remove: '); $users = readUsers($htpasswdPath); if (!isset($users[$username])) { fwrite(STDERR, "No such user: $username\n"); exit(1); } unset($users[$username]); writeUsers($htpasswdPath, $users); echo "Removed \"$username\". " . count($users) . " user(s) remain.\n"; exit(0); } $username = $args[0] ?? prompt('Username: '); $password = $args[1] ?? promptHidden('Password: '); if ($username === '' || $password === '') { fwrite(STDERR, "Username and password are required.\n"); exit(1); } if (str_contains($username, ':')) { fwrite(STDERR, "Username cannot contain ':'.\n"); exit(1); } $users = readUsers($htpasswdPath); $isNew = !isset($users[$username]); $users[$username] = password_hash($password, PASSWORD_BCRYPT); writeUsers($htpasswdPath, $users); echo ($isNew ? 'Added' : 'Updated') . " \"$username\". " . count($users) . " user(s) total in $htpasswdPath.\n";