baseUrl = rtrim($baseUrl, '/'); $this->adminUsername = $adminUsername; $this->adminPassword = $adminPassword; } /** * Create a new REST API user/credential * * @param string $username * @param string $password * @param array $options Optional: description, scopes, etc. * @return array Created credential with user, password, and other metadata * @throws \Exception */ public function createRestUser(string $username, string $password, array $options = []): array { $payload = [ 'user' => $username, 'password' => $password, ]; // Add optional fields if (isset($options['description'])) { $payload['description'] = $options['description']; } if (isset($options['scopes'])) { $payload['scopes'] = $options['scopes']; } $url = $this->baseUrl . '/admin/api/api/rest_users'; try { $response = Http::timeout($this->timeout) ->withBasicAuth($this->adminUsername, $this->adminPassword) ->withHeaders([ 'Accept' => 'application/json', 'Content-Type' => 'application/json', 'X-Requested-With' => 'XMLHttpRequest', ]) ->post($url, $payload); if (!$response->successful()) { $error = $response->json(); throw new \Exception( 'Failed to create REST user: ' . ($error['message'] ?? $error['error'] ?? 'Unknown error'), $response->status() ); } $data = $response->json(); // Check if response indicates success if (isset($data['status']) && $data['status'] === 'success') { return $data['data'] ?? [ 'user' => $username, 'password' => $password, ]; } return $data; } catch (\Illuminate\Http\Client\RequestException $e) { Log::error('PBX Admin API request failed', [ 'endpoint' => '/admin/api/api/rest_users', 'status' => $e->response?->status(), 'message' => $e->getMessage(), ]); throw new \Exception( 'Failed to create REST API credential: ' . $e->getMessage(), 0, $e ); } } /** * List all REST API users * * @return array * @throws \Exception */ public function listRestUsers(): array { $url = $this->baseUrl . '/admin/api/api/rest_users'; try { $response = Http::timeout($this->timeout) ->withBasicAuth($this->adminUsername, $this->adminPassword) ->withHeaders([ 'Accept' => 'application/json', 'X-Requested-With' => 'XMLHttpRequest', ]) ->get($url); if (!$response->successful()) { throw new \Exception( 'Failed to list REST users: ' . $response->body(), $response->status() ); } $data = $response->json(); if (isset($data['status']) && $data['status'] === 'success') { return $data['data'] ?? []; } return $data; } catch (\Exception $e) { Log::error('Failed to list REST users via admin API', [ 'error' => $e->getMessage(), ]); throw $e; } } /** * Grant scopes/permissions to a REST API user * * @param string $username * @param array $scopes Array of scope names (e.g., ['extensions', 'users', 'devices']) * @return bool * @throws \Exception */ public function grantScopes(string $username, array $scopes): bool { $url = $this->baseUrl . '/admin/api/api/rest_users/' . urlencode($username) . '/scopes'; try { $response = Http::timeout($this->timeout) ->withBasicAuth($this->adminUsername, $this->adminPassword) ->withHeaders([ 'Accept' => 'application/json', 'Content-Type' => 'application/json', 'X-Requested-With' => 'XMLHttpRequest', ]) ->post($url, ['scopes' => $scopes]); if (!$response->successful()) { throw new \Exception( 'Failed to grant scopes: ' . $response->body(), $response->status() ); } return true; } catch (\Exception $e) { Log::warning('Could not grant scopes to REST user', [ 'username' => $username, 'error' => $e->getMessage(), ]); // Don't fail the entire operation if scopes can't be set // The user was still created return false; } } }