Files
ladill-hosting/app/Console/Commands/HardenHostingAccountIsolationCommand.php
T
isaaccladandCursor e251a4cf60
Deploy Ladill Hosting / deploy (push) Failing after 17s
Initial Ladill Hosting app with Gitea deploy pipeline.
Shared web hosting extracted from the platform monolith, with CI deploy
to /var/www/ladill-hosting matching Bird/Domains/Email.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 16:24:20 +00:00

53 lines
1.7 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\HostingAccount;
use App\Services\Hosting\Providers\SharedNodeProvider;
use Illuminate\Console\Command;
class HardenHostingAccountIsolationCommand extends Command
{
protected $signature = 'hosting:harden-account-isolation {--account= : Limit to one hosting account id} {--dry-run : Show affected accounts without applying changes}';
protected $description = 'Apply filesystem isolation permissions to shared hosting accounts.';
public function handle(SharedNodeProvider $provider): int
{
$accounts = HostingAccount::query()
->with(['node', 'sites'])
->where('type', HostingAccount::TYPE_SHARED)
->when($this->option('account'), fn ($query, $accountId) => $query->whereKey($accountId))
->orderBy('id')
->get();
if ($accounts->isEmpty()) {
$this->info('No hosting accounts matched.');
return self::SUCCESS;
}
foreach ($accounts as $account) {
$this->line(sprintf('[%d] %s (%s)', $account->id, $account->username, $account->primary_domain ?: 'no-domain'));
}
if ($this->option('dry-run')) {
$this->warn('Dry run mode: no changes applied.');
return self::SUCCESS;
}
$failures = 0;
foreach ($accounts as $account) {
try {
$provider->hardenAccountFilesystem($account);
$this->info("Hardened {$account->username}");
} catch (\Throwable $e) {
$failures++;
$this->error("Failed {$account->username}: {$e->getMessage()}");
}
}
return $failures === 0 ? self::SUCCESS : self::FAILURE;
}
}