Initial commit device-management
tests / ci (push) Has been cancelled

This commit is contained in:
Wian Drs
2026-08-25 09:42:00 +07:00
commit 1e80be180e
1159 changed files with 149545 additions and 0 deletions
@@ -0,0 +1,112 @@
<?php
namespace App\Network\Clients\Hisfocus;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use RuntimeException;
class HisfocusWebClient
{
public function __construct(private readonly string $host, private readonly int $port = 80, private readonly int $timeout = 10) {}
/** @return array<string, string> */
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}";
}
}