1, 'RADIQ-WRITE' => 10, 'RADIQ-NOC' => 15, ]; public function __construct(private readonly ZteSshClient $client) {} public function provisionBaseAccess(string $loginUsername, string $loginPassword, ?string $enablePassword, string $newUsername, string $newPassword): array { $this->validateAccount($newUsername, $newPassword); $this->client->connect($loginUsername, $loginPassword); try { $this->client->enterEnable($enablePassword); $this->client->command('configure terminal'); $this->setUser($newUsername, $newPassword, 15); $this->client->command('username '.$newUsername.' enable'); $this->client->command('end'); $this->client->command('write'); return ['username' => $newUsername, 'privilege' => 15]; } finally { $this->client->disconnect(); } } public function testLogin(string $username, string $password, ?string $enablePassword): void { $this->client->connect($username, $password); try { $this->client->enterEnable($enablePassword); $this->client->command('show privilege'); } finally { $this->client->disconnect(); } } public function deleteUser(string $loginUsername, string $loginPassword, ?string $enablePassword, string $username): void { $this->client->connect($loginUsername, $loginPassword); try { $this->client->enterEnable($enablePassword); $this->client->command('configure terminal'); $this->client->command('no username '.$username); $this->client->command('end'); $this->client->command('write'); } finally { $this->client->disconnect(); } } public function syncUser(string $loginUsername, string $loginPassword, ?string $enablePassword, string $username, string $password, string $group, bool $enabled): array { $this->validateAccount($username, $password); $privilege = self::PRIVILEGES[$group] ?? throw new InvalidArgumentException('ZTE_PRIVILEGE_INVALID: group RADIQ tidak didukung untuk ZTE.'); $this->client->connect($loginUsername, $loginPassword); try { $this->client->enterEnable($enablePassword); $this->client->command('configure terminal'); $this->setUser($username, $password, $privilege); $this->client->command('username '.$username.' '.($enabled ? 'enable' : 'disable')); $this->client->command('end'); $this->client->command('write'); return ['remote_id' => $username, 'privilege' => $privilege]; } finally { $this->client->disconnect(); } } public function deleteAccessUser(string $loginUsername, string $loginPassword, ?string $enablePassword, string $username): void { $this->validateUsername($username); $this->deleteUser($loginUsername, $loginPassword, $enablePassword, $username); } private function validateAccount(string $username, string $password): void { $this->validateUsername($username); if (strlen($password) < 8 || strlen($password) > 32 || preg_match('/\s/', $password)) { throw new InvalidArgumentException('ZTE_PASSWORD_INVALID: password ZTE harus 8-32 karakter tanpa spasi.'); } } private function validateUsername(string $username): void { if (! preg_match('/^[A-Za-z0-9_]{1,16}$/', $username)) { throw new InvalidArgumentException('ZTE_USERNAME_INVALID: username ZTE harus 1-16 karakter alfanumerik/underscore.'); } } private function setUser(string $username, string $password, int $privilege): void { try { $this->client->command("username {$username} password 0 {$password} privilege {$privilege}"); } catch (RuntimeException $exception) { if (! str_starts_with($exception->getMessage(), 'COMMAND_REJECTED')) { throw $exception; } // Older C300/C320 firmware omits the explicit clear-text type 0. $this->client->command("username {$username} password {$password} privilege {$privilege}"); } } }