*/ public function users(string $loginUsername, string $loginPassword): array { $match = null; for ($attempt = 1; $attempt <= 3; $attempt++) { $body = $this->request($loginUsername, $loginPassword)->get($this->url('/userOverview.asp'))->body(); if (preg_match('/var\s+userList\s*=\s*new\s+Array\((.*?)\);/s', $body, $found)) { $match = $found; break; } if ($attempt < 3) { usleep(250_000); } } if (! $match) { throw new RuntimeException('HISFOCUS_WEB_PARSE_FAILED: daftar user WebGUI tidak dikenali setelah tiga percobaan.'); } preg_match_all('/"([^"]*)"/', $match[1], $values); $users = []; foreach (array_chunk($values[1], 2) as $user) { if (count($user) === 2) { $users[$user[0]] = $user[1]; } } return $users; } public function addUser(string $loginUsername, string $loginPassword, string $username, string $password, string $group): void { $response = $this->request($loginUsername, $loginPassword)->asForm()->post($this->url('/goform/setAddUser'), [ 'addUserHiddenId' => 0, 'UserName' => $username, 'UserGroup' => $group, 'UserPassword' => $password, 'ComfirmPassword' => $password, ]); $this->assertAccepted($response->status(), $response->body()); $this->assertUserState($loginUsername, $loginPassword, $username, $group); } public function changePassword(string $loginUsername, string $loginPassword, string $username, string $oldPassword, string $newPassword): void { $response = $this->request($loginUsername, $loginPassword)->asForm()->post($this->url('/goform/setUserPassword'), [ 'HiddenUserName' => $username, 'LYS' => $oldPassword, 'PBT' => $newPassword, ]); $this->assertAccepted($response->status(), $response->body()); } public function deleteUser(string $loginUsername, string $loginPassword, string $username): void { $response = $this->request($loginUsername, $loginPassword)->asForm()->post($this->url('/goform/setDeleteUser'), [ 'user'.$username.'DeleteCheck' => 'on', ]); $this->assertAccepted($response->status(), $response->body()); $this->assertUserState($loginUsername, $loginPassword, $username, null); } public function canLogin(string $username, string $password): bool { return $this->request($username, $password)->get($this->url('/'))->successful(); } private function request(string $username, string $password): PendingRequest { return Http::withBasicAuth($username, $password)->timeout($this->timeout)->connectTimeout($this->timeout); } private function assertAccepted(int $status, string $body): void { if ($status >= 400 || stripos($body, 'Access Denied') !== false) { throw new RuntimeException('HISFOCUS_WEB_REJECTED: WebGUI menolak operasi user.'); } } private function assertUserState(string $loginUsername, string $loginPassword, string $username, ?string $expectedGroup): void { for ($attempt = 1; $attempt <= 4; $attempt++) { $users = $this->users($loginUsername, $loginPassword); $exists = array_key_exists($username, $users); if ($expectedGroup === null ? ! $exists : ($exists && strcasecmp($users[$username], $expectedGroup) === 0)) { return; } if ($attempt < 4) { usleep(250_000); } } throw new RuntimeException($expectedGroup === null ? 'HISFOCUS_WEB_DELETE_FAILED: user masih tercatat di WebGUI.' : 'HISFOCUS_WEB_ADD_FAILED: user atau role belum tercatat di WebGUI.'); } private function url(string $path): string { return "http://{$this->host}:{$this->port}{$path}"; } }