baseUrl = rtrim($baseUrl, '/'); $this->appToken = $appToken; $this->httpClient = new Client([ 'base_uri' => $this->baseUrl . '/apirest.php/', 'timeout' => 30.0, 'headers' => [ 'App-Token' => $this->appToken, 'Content-Type' => 'application/json', ], ]); if ($userToken) { $this->loginWithUserToken($userToken); } } /** * Login con credenziali utente (username + password) */ public function login(string $username, string $password): bool { try { $response = $this->httpClient->post('initSession', [ 'auth' => [$username, $password], ]); $data = json_decode($response->getBody(), true); $this->sessionToken = $data['session_token'] ?? null; return $this->sessionToken !== null; } catch (RequestException $e) { error_log("GLPI API login failed: " . $e->getMessage()); return false; } } /** * Login con user token (più sicuro, generato in Profilo > API) */ public function loginWithUserToken(string $userToken): bool { try { $response = $this->httpClient->post('initSession', [ 'headers' => ['User-Token' => $userToken], ]); $data = json_decode($response->getBody(), true); $this->sessionToken = $data['session_token'] ?? null; return $this->sessionToken !== null; } catch (RequestException $e) { error_log("GLPI API user-token login failed: " . $e->getMessage()); return false; } } /** * Logout e distruzione sessione */ public function logout(): void { if ($this->sessionToken) { try { $this->httpClient->delete('killSession', [ 'headers' => ['Session-Token' => $this->sessionToken], ]); } catch (\Throwable $e) { // Ignora errori in logout } $this->sessionToken = null; } } /** * Esegue una chiamata API con retry automatico su token scaduto */ private function request(string $method, string $endpoint, array $data = []): ?array { $headers = $this->sessionToken ? ['Session-Token' => $this->sessionToken] : []; try { $response = $this->httpClient->request($method, $endpoint, [ 'headers' => $headers, 'json' => $data, ]); return json_decode($response->getBody(), true); } catch (RequestException $e) { // Se token scaduto (401), tenta refresh e riprova UNA volta if ($e->getResponse()?->getStatusCode() === 401 && $this->sessionToken) { $this->logout(); // Qui potresti ricaricare le credenziali da config/vault e fare re-login // Per semplicità, lanciamo eccezione throw new \RuntimeException("GLPI API session expired. Re-authentication required."); } throw $e; } } /** * Ottieni dispositivo di rete per ID */ public function getNetworkEquipment(int $id): ?array { $result = $this->request('GET', "NetworkEquipment/$id"); return $result && !isset($result[0]['error']) ? $result : null; } /** * Cerca dispositivi per nome/IP (per mapping agent -> GLPI ID) */ public function searchNetworkEquipment(string $nameOrIp): array { $query = [ 'criteria' => [ ['field' => 1, 'searchtype' => 'contains', 'value' => $nameOrIp], // name ['OR' => [ ['field' => 2, 'searchtype' => 'contains', 'value' => $nameOrIp], // ip ]], ], 'forcedisplay' => [1, 2, 3], // id, name, ip ]; $result = $this->request('GET', 'search/NetworkEquipment', ['criteria' => $query]); return $result['data'] ?? []; } /** * Invia configurazione al plugin (endpoint personalizzato) */ public function sendConfig(int $deviceId, string $config, string $agentToken): bool { $payload = [ 'device_id' => $deviceId, 'config' => $config, 'token' => $agentToken, 'timestamp' => date('c'), ]; $result = $this->request('POST', 'plugin/netconfig/agent', $payload); return ($result['status'] ?? '') === 'ok'; } public function __destruct() { $this->logout(); } }