Created
May 26, 2023 23:13
-
-
Save kishu27/65e73aa72534ff3784b845fba0639945 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace UniFi_API; | |
class Client | |
{ | |
const CLASS_VERSION = '1.1.80'; | |
protected $baseurl = 'https://127.0.0.1:8443'; | |
protected $user = ''; | |
protected $password = ''; | |
protected $site = 'default'; | |
protected $version = '6.2.26'; | |
protected $debug = false; | |
protected $is_logged_in = false; | |
protected $is_unifi_os = false; | |
protected $exec_retries = 0; | |
protected $cookies = ''; | |
protected $last_results_raw = null; | |
protected $last_error_message = ''; | |
protected $curl_ssl_verify_peer = false; | |
protected $curl_ssl_verify_host = false; | |
protected $curl_http_version = CURL_HTTP_VERSION_NONE; | |
protected $curl_headers = []; | |
protected $curl_method = 'GET'; | |
protected $curl_methods_allowed = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']; | |
protected $curl_request_timeout = 30; | |
protected $curl_connect_timeout = 10; | |
public function __construct($user, $password, $baseurl = '', $site = '', $version = '', $ssl_verify = false) | |
{ | |
if (!extension_loaded('curl')) { | |
trigger_error('The PHP curl extension is not loaded. Please correct this before proceeding!'); | |
} | |
$this->user = trim($user); | |
$this->password = trim($password); | |
if (!empty($baseurl)) { | |
$this->check_base_url($baseurl); | |
$this->baseurl = trim($baseurl); | |
} | |
if (!empty($site)) { | |
$this->check_site($site); | |
$this->site = trim($site); | |
} | |
if (!empty($version)) { | |
$this->version = trim($version); | |
} | |
if ((bool) $ssl_verify === true) { | |
$this->curl_ssl_verify_peer = true; | |
$this->curl_ssl_verify_host = 2; | |
} | |
} | |
public function __destruct() | |
{ | |
if (isset($_SESSION['unificookie'])) { | |
return; | |
} | |
if ($this->is_logged_in) { | |
$this->logout(); | |
} | |
} | |
public function login() | |
{ | |
if ($this->update_unificookie()) { | |
$this->is_logged_in = true; | |
} | |
if ($this->is_logged_in === true) { | |
return true; | |
} | |
if (!($ch = $this->get_curl_handle())) { | |
return false; | |
} | |
$curl_options = [ | |
CURLOPT_URL => $this->baseurl . '/', | |
]; | |
curl_setopt_array($ch, $curl_options); | |
curl_exec($ch); | |
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
if (curl_errno($ch)) { | |
trigger_error('cURL error: ' . curl_error($ch)); | |
} | |
$curl_options = [ | |
CURLOPT_POST => true, | |
CURLOPT_POSTFIELDS => json_encode(['username' => $this->user, 'password' => $this->password]), | |
CURLOPT_HTTPHEADER => [ | |
'content-type: application/json', | |
'Expect:', | |
], | |
CURLOPT_REFERER => $this->baseurl . '/login', | |
CURLOPT_URL => $this->baseurl . '/api/login', | |
]; | |
if ($http_code === 200) { | |
$this->is_unifi_os = true; | |
$curl_options[CURLOPT_URL] = $this->baseurl . '/api/auth/login'; | |
} | |
curl_setopt_array($ch, $curl_options); | |
$response = curl_exec($ch); | |
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
if (curl_errno($ch)) { | |
trigger_error('cURL error: ' . curl_error($ch)); | |
} | |
if ($this->debug) { | |
print PHP_EOL . '<pre>'; | |
print PHP_EOL . '-----------LOGIN-------------' . PHP_EOL; | |
print_r(curl_getinfo($ch)); | |
print PHP_EOL . '----------RESPONSE-----------' . PHP_EOL; | |
print $response; | |
print PHP_EOL . '-----------------------------' . PHP_EOL; | |
print '</pre>' . PHP_EOL; | |
} | |
if ($http_code === 400 || $http_code === 401) { | |
trigger_error("HTTP response status received: $http_code. Probably a controller login failure"); | |
return $http_code; | |
} | |
curl_close($ch); | |
if ($http_code >= 200 && $http_code < 400) { | |
$this->is_logged_in = true; | |
return $this->is_logged_in; | |
} | |
return false; | |
} | |
public function logout() | |
{ | |
if (!($ch = $this->get_curl_handle())) { | |
return false; | |
} | |
$curl_options = [ | |
CURLOPT_HEADER => true, | |
CURLOPT_POST => true, | |
]; | |
$this->curl_headers = [ | |
'Expect:', | |
]; | |
$logout_path = '/logout'; | |
if ($this->is_unifi_os) { | |
$logout_path = '/api/auth/logout'; | |
$curl_options[CURLOPT_CUSTOMREQUEST] = 'POST'; | |
$this->create_x_csrf_token_header(); | |
} | |
$curl_options[CURLOPT_HTTPHEADER] = $this->curl_headers; | |
$curl_options[CURLOPT_URL] = $this->baseurl . $logout_path; | |
curl_setopt_array($ch, $curl_options); | |
curl_exec($ch); | |
if (curl_errno($ch)) { | |
trigger_error('cURL error: ' . curl_error($ch)); | |
return false; | |
} | |
curl_close($ch); | |
$this->is_logged_in = false; | |
$this->cookies = ''; | |
return true; | |
} | |
public function authorize_guest($mac, $minutes, $up = null, $down = null, $megabytes = null, $ap_mac = null) | |
{ | |
$payload = ['cmd' => 'authorize-guest', 'mac' => strtolower($mac), 'minutes' => intval($minutes)]; | |
if (!empty($up)) { | |
$payload['up'] = intval($up); | |
} | |
if (!empty($down)) { | |
$payload['down'] = intval($down); | |
} | |
if (!empty($megabytes)) { | |
$payload['bytes'] = intval($megabytes); | |
} | |
if (!empty($ap_mac) && filter_var($ap_mac, FILTER_VALIDATE_MAC)) { | |
$payload['ap_mac'] = strtolower($ap_mac); | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); | |
} | |
public function unauthorize_guest($mac) | |
{ | |
$payload = ['cmd' => 'unauthorize-guest', 'mac' => strtolower($mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); | |
} | |
public function reconnect_sta($mac) | |
{ | |
$payload = ['cmd' => 'kick-sta', 'mac' => strtolower($mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); | |
} | |
public function block_sta($mac) | |
{ | |
$payload = ['cmd' => 'block-sta', 'mac' => strtolower($mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); | |
} | |
public function unblock_sta($mac) | |
{ | |
$payload = ['cmd' => 'unblock-sta', 'mac' => strtolower($mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); | |
} | |
public function forget_sta($macs) | |
{ | |
$payload = ['cmd' => 'forget-sta', 'macs' => array_map('strtolower', $macs)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stamgr', $payload); | |
} | |
public function create_user($mac, $user_group_id, $name = null, $note = null, $is_guest = null, $is_wired = null) | |
{ | |
$new_user = ['mac' => strtolower($mac), 'usergroup_id' => $user_group_id]; | |
if (!empty($name)) { | |
$new_user['name'] = $name; | |
} | |
if (!empty($note)) { | |
$new_user['note'] = $note; | |
} | |
if (!empty($is_guest) && is_bool($is_guest)) { | |
$new_user['is_guest'] = $is_guest; | |
} | |
if (!empty($is_wired) && is_bool($is_wired)) { | |
$new_user['is_wired'] = $is_wired; | |
} | |
$payload = ['objects' => [['data' => $new_user]]]; | |
return $this->fetch_results('/api/s/' . $this->site . '/group/user', $payload); | |
} | |
public function set_sta_note($user_id, $note = '') | |
{ | |
$payload = ['note' => $note]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/user/' . trim($user_id), $payload); | |
} | |
public function set_sta_name($user_id, $name = '') | |
{ | |
$payload = ['name' => $name]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/user/' . trim($user_id), $payload); | |
} | |
public function stat_5minutes_site($start = null, $end = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); | |
$attribs = [ | |
'bytes', | |
'wan-tx_bytes', | |
'wan-rx_bytes', | |
'wlan_bytes', | |
'num_sta', | |
'lan-num_sta', | |
'wlan-num_sta', | |
'time', | |
]; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/5minutes.site', $payload); | |
} | |
public function stat_hourly_site($start = null, $end = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = [ | |
'bytes', | |
'wan-tx_bytes', | |
'wan-rx_bytes', | |
'wlan_bytes', | |
'num_sta', | |
'lan-num_sta', | |
'wlan-num_sta', | |
'time', | |
]; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/hourly.site', $payload); | |
} | |
public function stat_daily_site($start = null, $end = null) | |
{ | |
$end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); | |
$start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = [ | |
'bytes', | |
'wan-tx_bytes', | |
'wan-rx_bytes', | |
'wlan_bytes', | |
'num_sta', | |
'lan-num_sta', | |
'wlan-num_sta', | |
'time', | |
]; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/daily.site', $payload); | |
} | |
public function stat_monthly_site($start = null, $end = null) | |
{ | |
$end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); | |
$start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = [ | |
'bytes', | |
'wan-tx_bytes', | |
'wan-rx_bytes', | |
'wlan_bytes', | |
'num_sta', | |
'lan-num_sta', | |
'wlan-num_sta', | |
'time', | |
]; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/monthly.site', $payload); | |
} | |
public function stat_5minutes_aps($start = null, $end = null, $mac = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); | |
$attribs = ['bytes', 'num_sta', 'time']; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
if (!empty($mac)) { | |
$payload['mac'] = strtolower($mac); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/5minutes.ap', $payload); | |
} | |
public function stat_hourly_aps($start = null, $end = null, $mac = null) | |
{ | |
$end = empty($end) ? (time() * 1000) : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = ['bytes', 'num_sta', 'time']; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
if (!empty($mac)) { | |
$payload['mac'] = strtolower($mac); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/hourly.ap', $payload); | |
} | |
public function stat_daily_aps($start = null, $end = null, $mac = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = ['bytes', 'num_sta', 'time']; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
if (!empty($mac)) { | |
$payload['mac'] = strtolower($mac); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/daily.ap', $payload); | |
} | |
public function stat_monthly_aps($start = null, $end = null, $mac = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = ['bytes', 'num_sta', 'time']; | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
if (!empty($mac)) { | |
$payload['mac'] = strtolower($mac); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/monthly.ap', $payload); | |
} | |
public function stat_5minutes_user($mac, $start = null, $end = null, $attribs = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'rx_bytes', 'tx_bytes'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end, 'mac' => strtolower($mac)]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/5minutes.user', $payload); | |
} | |
public function stat_hourly_user($mac, $start = null, $end = null, array $attribs = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'rx_bytes', 'tx_bytes'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end, 'mac' => strtolower($mac)]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/hourly.user', $payload); | |
} | |
public function stat_daily_user($mac, $start = null, $end = null, $attribs = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'rx_bytes', 'tx_bytes'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end, 'mac' => strtolower($mac)]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/daily.user', $payload); | |
} | |
public function stat_monthly_user($mac, $start = null, $end = null, $attribs = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (13 * 7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'rx_bytes', 'tx_bytes'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end, 'mac' => strtolower($mac)]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/monthly.user', $payload); | |
} | |
public function stat_5minutes_gateway($start = null, $end = null, $attribs = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (12 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'mem', 'cpu', 'loadavg_5'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/5minutes.gw', $payload); | |
} | |
public function stat_hourly_gateway($start = null, $end = null, $attribs = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'mem', 'cpu', 'loadavg_5'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/hourly.gw', $payload); | |
} | |
public function stat_daily_gateway($start = null, $end = null, $attribs = null) | |
{ | |
$end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); | |
$start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'mem', 'cpu', 'loadavg_5'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/daily.gw', $payload); | |
} | |
public function stat_monthly_gateway($start = null, $end = null, $attribs = null) | |
{ | |
$end = empty($end) ? (time() - (time() % 3600)) * 1000 : intval($end); | |
$start = empty($start) ? $end - (52 * 7 * 24 * 3600 * 1000) : intval($start); | |
$attribs = empty($attribs) ? ['time', 'mem', 'cpu', 'loadavg_5'] : array_merge(['time'], $attribs); | |
$payload = ['attrs' => $attribs, 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/monthly.gw', $payload); | |
} | |
public function stat_speedtest_results($start = null, $end = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (24 * 3600 * 1000) : intval($start); | |
$payload = ['attrs' => ['xput_download', 'xput_upload', 'latency', 'time'], 'start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/report/archive.speedtest', $payload); | |
} | |
public function stat_ips_events($start = null, $end = null, $limit = null) | |
{ | |
$end = empty($end) ? time() * 1000 : intval($end); | |
$start = empty($start) ? $end - (24 * 3600 * 1000) : intval($start); | |
$limit = empty($limit) ? 10000 : intval($limit); | |
$payload = ['start' => $start, 'end' => $end, '_limit' => $limit]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/ips/event', $payload); | |
} | |
public function stat_sessions($start = null, $end = null, $mac = null, $type = 'all') | |
{ | |
if (!in_array($type, ['all', 'guest', 'user'])) { | |
return false; | |
} | |
$end = empty($end) ? time() : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600) : intval($start); | |
$payload = ['type' => $type, 'start' => $start, 'end' => $end]; | |
if (!empty($mac)) { | |
$payload['mac'] = strtolower($mac); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/session', $payload); | |
} | |
public function stat_sta_sessions_latest($mac, $limit = null) | |
{ | |
$limit = empty($limit) ? 5 : intval($limit); | |
$payload = ['mac' => strtolower($mac), '_limit' => $limit, '_sort' => '-assoc_time']; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/session', $payload); | |
} | |
public function stat_auths($start = null, $end = null) | |
{ | |
$end = empty($end) ? time() : intval($end); | |
$start = empty($start) ? $end - (7 * 24 * 3600) : intval($start); | |
$payload = ['start' => $start, 'end' => $end]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/authorization', $payload); | |
} | |
public function stat_allusers($historyhours = 8760) | |
{ | |
$payload = ['type' => 'all', 'conn' => 'all', 'within' => intval($historyhours)]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/alluser', $payload); | |
} | |
public function list_guests($within = 8760) | |
{ | |
$payload = ['within' => intval($within)]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/guest', $payload); | |
} | |
public function list_clients($client_mac = null) | |
{ | |
if (is_string($client_mac)) { | |
$client_mac = strtolower(trim($client_mac)); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/sta/' . $client_mac); | |
} | |
public function stat_client($client_mac) | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/user/' . strtolower(trim($client_mac))); | |
} | |
public function set_usergroup($client_id, $group_id) | |
{ | |
$payload = ['usergroup_id' => $group_id]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/user/' . trim($client_id), $payload); | |
} | |
public function edit_client_fixedip($client_id, $use_fixedip, $network_id = null, $fixed_ip = null) | |
{ | |
if (!is_bool($use_fixedip)) { | |
return false; | |
} | |
$this->curl_method = 'PUT'; | |
$payload = [ | |
'_id' => $client_id, | |
'use_fixedip' => $use_fixedip, | |
]; | |
if ($use_fixedip) { | |
if ($network_id) { | |
$payload['network_id'] = $network_id; | |
} | |
if ($fixed_ip) { | |
$payload['fixed_ip'] = $fixed_ip; | |
} | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/user/' . trim($client_id), $payload); | |
} | |
public function edit_client_name($client_id, $name) | |
{ | |
if (empty($name)) { | |
return false; | |
} | |
$this->curl_method = 'PUT'; | |
$payload = [ | |
'_id' => $client_id, | |
'name' => $name, | |
]; | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/user/' . trim($client_id), $payload); | |
} | |
public function list_usergroups() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/list/usergroup'); | |
} | |
public function create_usergroup($group_name, $group_dn = -1, $group_up = -1) | |
{ | |
$payload = [ | |
'name' => $group_name, | |
'qos_rate_max_down' => intval($group_dn), | |
'qos_rate_max_up' => intval($group_up), | |
]; | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/usergroup', $payload); | |
} | |
public function edit_usergroup($group_id, $site_id, $group_name, $group_dn = -1, $group_up = -1) | |
{ | |
$this->curl_method = 'PUT'; | |
$payload = [ | |
'_id' => $group_id, | |
'name' => $group_name, | |
'qos_rate_max_down' => intval($group_dn), | |
'qos_rate_max_up' => intval($group_up), | |
'site_id' => $site_id, | |
]; | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/usergroup/' . trim($group_id), $payload); | |
} | |
public function delete_usergroup($group_id) | |
{ | |
$this->curl_method = 'DELETE'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/usergroup/' . trim($group_id)); | |
} | |
public function list_apgroups() | |
{ | |
return $this->fetch_results('/v2/api/site/' . $this->site . '/apgroups'); | |
} | |
public function create_apgroup($group_name, $device_macs = []) | |
{ | |
$payload = ['device_macs' => $device_macs, 'name' => $group_name]; | |
return $this->fetch_results('/v2/api/site/' . $this->site . '/apgroups', $payload); | |
} | |
public function edit_apgroup($group_id, $group_name, $device_macs) | |
{ | |
$this->curl_method = 'PUT'; | |
$payload = [ | |
'_id' => $group_id, | |
'attr_no_delete' => false, | |
'name' => $group_name, | |
'device_macs' => $device_macs, | |
]; | |
return $this->fetch_results('/v2/api/site/' . $this->site . '/apgroups/' . trim($group_id), $payload); | |
} | |
public function delete_apgroup($group_id) | |
{ | |
$this->curl_method = 'DELETE'; | |
return $this->fetch_results_boolean('/v2/api/site/' . $this->site . '/apgroups/' . trim($group_id)); | |
} | |
public function list_firewallgroups($group_id = '') | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id)); | |
} | |
public function create_firewallgroup($group_name, $group_type, $group_members = []) | |
{ | |
if (!in_array($group_type, ['address-group', 'ipv6-address-group', 'port-group'])) { | |
return false; | |
} | |
$payload = ['name' => $group_name, 'group_type' => $group_type, 'group_members' => $group_members]; | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallgroup', $payload); | |
} | |
public function edit_firewallgroup($group_id, $site_id, $group_name, $group_type, $group_members = []) | |
{ | |
if (!in_array($group_type, ['address-group', 'ipv6-address-group', 'port-group'])) { | |
return false; | |
} | |
$this->curl_method = 'PUT'; | |
$payload = [ | |
'_id' => $group_id, | |
'name' => $group_name, | |
'group_type' => $group_type, | |
'group_members' => $group_members, | |
'site_id' => $site_id, | |
]; | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id), $payload); | |
} | |
public function delete_firewallgroup($group_id) | |
{ | |
$this->curl_method = 'DELETE'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/firewallgroup/' . trim($group_id)); | |
} | |
public function list_firewallrules() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/firewallrule'); | |
} | |
public function list_routing($route_id = '') | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/routing/' . trim($route_id)); | |
} | |
public function list_health() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/health'); | |
} | |
public function list_dashboard($five_minutes = false) | |
{ | |
$path_suffix = $five_minutes ? '?scale=5minutes' : null; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/dashboard' . $path_suffix); | |
} | |
public function list_users() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/list/user'); | |
} | |
public function list_devices_basic() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/device-basic'); | |
} | |
public function list_devices($device_mac = null) | |
{ | |
if (is_string($device_mac)) { | |
$device_mac = strtolower(trim($device_mac)); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/device/' . $device_mac); | |
} | |
public function list_tags() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/tag'); | |
} | |
public function list_rogueaps($within = 24) | |
{ | |
$payload = ['within' => intval($within)]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/rogueap', $payload); | |
} | |
public function list_known_rogueaps() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/rogueknown'); | |
} | |
public function generate_backup() | |
{ | |
$payload = ['cmd' => 'backup']; | |
return $this->fetch_results('/api/s/' . $this->site . '/cmd/backup', $payload); | |
} | |
public function list_backups() | |
{ | |
$payload = ['cmd' => 'list-backups']; | |
return $this->fetch_results('/api/s/' . $this->site . '/cmd/backup', $payload); | |
} | |
public function generate_backup_site() | |
{ | |
$payload = ['cmd' => 'export-site']; | |
return $this->fetch_results('/api/s/' . $this->site . '/cmd/backup', $payload); | |
} | |
public function list_sites() | |
{ | |
return $this->fetch_results('/api/self/sites'); | |
} | |
public function stat_sites() | |
{ | |
return $this->fetch_results('/api/stat/sites'); | |
} | |
public function create_site($description) | |
{ | |
$payload = ['desc' => $description, 'cmd' => 'add-site']; | |
return $this->fetch_results('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function delete_site($site_id) | |
{ | |
$payload = ['site' => $site_id, 'cmd' => 'delete-site']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function set_site_name($site_name) | |
{ | |
$payload = ['cmd' => 'update-site', 'desc' => $site_name]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function set_site_country($country_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/country/' . trim($country_id), | |
$payload); | |
} | |
public function set_site_locale($locale_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/locale/' . trim($locale_id), | |
$payload); | |
} | |
public function set_site_snmp($snmp_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/snmp/' . trim($snmp_id), $payload); | |
} | |
public function set_site_mgmt($mgmt_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/mgmt/' . trim($mgmt_id), $payload); | |
} | |
public function set_site_guest_access($guest_access_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/guest_access/' . trim($guest_access_id), | |
$payload); | |
} | |
public function set_site_ntp($ntp_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/ntp/' . trim($ntp_id), $payload); | |
} | |
public function set_site_connectivity($connectivity_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/setting/connectivity/' . trim($connectivity_id), | |
$payload); | |
} | |
public function list_admins() | |
{ | |
$payload = ['cmd' => 'get-admins']; | |
return $this->fetch_results('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function list_all_admins() | |
{ | |
return $this->fetch_results('/api/stat/admin'); | |
} | |
public function invite_admin( | |
$name, | |
$email, | |
$enable_sso = true, | |
$readonly = false, | |
$device_adopt = false, | |
$device_restart = false | |
) { | |
$email = trim($email); | |
$email_valid = filter_var($email, FILTER_VALIDATE_EMAIL); | |
if (!$email_valid) { | |
trigger_error('The email address provided is invalid!'); | |
return false; | |
} | |
$payload = [ | |
'name' => trim($name), | |
'email' => $email, | |
'for_sso' => $enable_sso, | |
'cmd' => 'invite-admin', | |
'role' => 'admin', | |
'permissions' => [], | |
]; | |
if ($readonly) { | |
$payload['role'] = 'readonly'; | |
} | |
if ($device_adopt) { | |
$payload['permissions'][] = 'API_DEVICE_ADOPT'; | |
} | |
if ($device_restart) { | |
$payload['permissions'][] = 'API_DEVICE_RESTART'; | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function assign_existing_admin($admin_id, $readonly = false, $device_adopt = false, $device_restart = false) | |
{ | |
$payload = [ | |
'cmd' => 'grant-admin', | |
'admin' => trim($admin_id), | |
'role' => 'admin', | |
'permissions' => [], | |
]; | |
if ($readonly) { | |
$payload['role'] = 'readonly'; | |
} | |
if ($device_adopt) { | |
$payload['permissions'][] = 'API_DEVICE_ADOPT'; | |
} | |
if ($device_restart) { | |
$payload['permissions'][] = 'API_DEVICE_RESTART'; | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function revoke_admin($admin_id) | |
{ | |
$payload = ['cmd' => 'revoke-admin', 'admin' => $admin_id]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function list_wlan_groups() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/list/wlangroup'); | |
} | |
public function stat_sysinfo() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/sysinfo'); | |
} | |
public function stat_status() | |
{ | |
return $this->fetch_results_boolean('/status', null, false); | |
} | |
public function stat_full_status() | |
{ | |
$this->fetch_results_boolean('/status', null, false); | |
return json_decode($this->get_last_results_raw()); | |
} | |
public function list_device_name_mappings() | |
{ | |
$this->fetch_results_boolean('/dl/firmware/bundles.json', null, false); | |
return json_decode($this->get_last_results_raw()); | |
} | |
public function list_self() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/self'); | |
} | |
public function stat_voucher($create_time = null) | |
{ | |
$payload = isset($create_time) ? ['create_time' => intval($create_time)] : []; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/voucher', $payload); | |
} | |
public function stat_payment($within = null) | |
{ | |
$path_suffix = isset($within) ? '?within=' . intval($within) : ''; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/payment' . $path_suffix); | |
} | |
public function create_hotspotop($name, $x_password, $note = '') | |
{ | |
$payload = ['name' => $name, 'x_password' => $x_password]; | |
if (!empty($note)) { | |
$payload['note'] = trim($note); | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/hotspotop', $payload); | |
} | |
public function list_hotspotop() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/hotspotop'); | |
} | |
public function create_voucher( | |
$minutes, | |
$count = 1, | |
$quota = 0, | |
$note = '', | |
$up = null, | |
$down = null, | |
$megabytes = null | |
) { | |
$payload = [ | |
'cmd' => 'create-voucher', | |
'expire' => intval($minutes), | |
'n' => intval($count), | |
'quota' => intval($quota), | |
]; | |
if (!empty($note)) { | |
$payload['note'] = trim($note); | |
} | |
if (!is_null($up)) { | |
$payload['up'] = intval($up); | |
} | |
if (!is_null($down)) { | |
$payload['down'] = intval($down); | |
} | |
if (!is_null($megabytes)) { | |
$payload['bytes'] = intval($megabytes); | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/cmd/hotspot', $payload); | |
} | |
public function revoke_voucher($voucher_id) | |
{ | |
$payload = ['_id' => $voucher_id, 'cmd' => 'delete-voucher']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/hotspot', $payload); | |
} | |
public function extend_guest_validity($guest_id) | |
{ | |
$payload = ['_id' => $guest_id, 'cmd' => 'extend']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/hotspot', $payload); | |
} | |
public function list_portforward_stats() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/portforward'); | |
} | |
public function list_dpi_stats() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/dpi'); | |
} | |
public function list_dpi_stats_filtered($type = 'by_cat', array $cat_filter = null) | |
{ | |
if (!in_array($type, ['by_cat', 'by_app'])) { | |
return false; | |
} | |
$payload = ['type' => $type]; | |
if (is_array($cat_filter) && $type === 'by_app') { | |
$payload['cats'] = $cat_filter; | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/sitedpi', $payload); | |
} | |
public function list_current_channels() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/current-channel'); | |
} | |
public function list_country_codes() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/ccode'); | |
} | |
public function list_portforwarding() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/list/portforward'); | |
} | |
public function list_portconf() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/list/portconf'); | |
} | |
public function list_extension() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/list/extension'); | |
} | |
public function list_settings() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/get/setting'); | |
} | |
public function adopt_device($mac) | |
{ | |
$payload = ['mac' => strtolower($mac), 'cmd' => 'adopt']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function advanced_adopt_device($mac, $ip, $username, $password, $url, $port = 22, $ssh_key_verify = true) | |
{ | |
$payload = [ | |
'cmd' => 'adv-adopt', | |
'mac' => strtolower($mac), | |
'ip' => $ip, | |
'username' => $username, | |
'password' => $password, | |
'url' => $url, | |
'port' => $port, | |
'sshKeyVerify' => $ssh_key_verify, | |
]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function restart_device($mac, $reboot_type = 'soft') | |
{ | |
$payload = ['cmd' => 'restart', 'mac' => strtolower($mac)]; | |
if (!empty($reboot_type) && in_array($reboot_type, ['soft', 'hard'])) { | |
$payload['reboot_type'] = strtolower($reboot_type); | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function force_provision($mac) | |
{ | |
$payload = ['mac' => strtolower($mac), 'cmd' => 'force-provision']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function reboot_cloudkey() | |
{ | |
$payload = ['cmd' => 'reboot']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/system', $payload); | |
} | |
public function disable_ap($ap_id, $disable) | |
{ | |
if (!is_bool($disable)) { | |
return false; | |
} | |
$this->curl_method = 'PUT'; | |
$payload = ['disabled' => $disable]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($ap_id), $payload); | |
} | |
public function led_override($device_id, $override_mode) | |
{ | |
if (!in_array($override_mode, ['off', 'on', 'default'])) { | |
return false; | |
} | |
$this->curl_method = 'PUT'; | |
$payload = ['led_override' => $override_mode]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload); | |
} | |
public function locate_ap($mac, $enable) | |
{ | |
if (!is_bool($enable)) { | |
return false; | |
} | |
$cmd = $enable ? 'set-locate' : 'unset-locate'; | |
$payload = ['cmd' => $cmd, 'mac' => strtolower($mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function site_leds($enable) | |
{ | |
if (!is_bool($enable)) { | |
return false; | |
} | |
$payload = ['led_enabled' => $enable]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/mgmt', $payload); | |
} | |
public function set_ap_radiosettings($ap_id, $radio, $channel, $ht, $tx_power_mode, $tx_power) | |
{ | |
$payload = [ | |
'radio_table' => [ | |
'radio' => $radio, | |
'channel' => $channel, | |
'ht' => $ht, | |
'tx_power_mode' => $tx_power_mode, | |
'tx_power' => $tx_power, | |
], | |
]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/device/' . trim($ap_id), $payload); | |
} | |
public function set_ap_wlangroup($type_id, $device_id, $group_id) | |
{ | |
if (!in_array($type_id, ['ng', 'na'])) { | |
return false; | |
} | |
$payload = [ | |
'wlan_overrides' => [], | |
'wlangroup_id_' . $type_id => $group_id, | |
]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/device/' . trim($device_id), $payload); | |
} | |
public function set_guestlogin_settings( | |
$portal_enabled, | |
$portal_customized, | |
$redirect_enabled, | |
$redirect_url, | |
$x_password, | |
$expire_number, | |
$expire_unit, | |
$section_id | |
) { | |
$payload = [ | |
'portal_enabled' => $portal_enabled, | |
'portal_customized' => $portal_customized, | |
'redirect_enabled' => $redirect_enabled, | |
'redirect_url' => $redirect_url, | |
'x_password' => $x_password, | |
'expire_number' => $expire_number, | |
'expire_unit' => $expire_unit, | |
'_id' => $section_id, | |
]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/guest_access/' . $section_id, | |
$payload); | |
} | |
public function set_guestlogin_settings_base($payload, $section_id = '') | |
{ | |
if (!empty($section_id)) { | |
$section_id = '/' . $section_id; | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/guest_access' . $section_id, | |
$payload); | |
} | |
public function set_ips_settings_base($payload) | |
{ | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/ips', $payload); | |
} | |
public function set_super_mgmt_settings_base($settings_id, $payload) | |
{ | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/super_mgmt/' . trim($settings_id), | |
$payload); | |
} | |
public function set_super_smtp_settings_base($settings_id, $payload) | |
{ | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/super_smtp/' . trim($settings_id), | |
$payload); | |
} | |
public function set_super_identity_settings_base($settings_id, $payload) | |
{ | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/super_identity/' . trim($settings_id), | |
$payload); | |
} | |
public function rename_ap($ap_id, $apname) | |
{ | |
$payload = ['name' => $apname]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/upd/device/' . trim($ap_id), $payload); | |
} | |
public function move_device($mac, $site_id) | |
{ | |
$payload = ['site' => $site_id, 'mac' => strtolower($mac), 'cmd' => 'move-device']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function delete_device($mac) | |
{ | |
$payload = ['mac' => strtolower($mac), 'cmd' => 'delete-device']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/sitemgr', $payload); | |
} | |
public function list_dynamicdns() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/dynamicdns'); | |
} | |
public function create_dynamicdns($payload) | |
{ | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/dynamicdns', $payload); | |
} | |
public function set_dynamicdns($dynamicdns_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/dynamicdns/' . trim($dynamicdns_id), | |
$payload); | |
} | |
public function list_networkconf($network_id = '') | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id)); | |
} | |
public function create_network($payload) | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/networkconf', $payload); | |
} | |
public function set_networksettings_base($network_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id), | |
$payload); | |
} | |
public function delete_network($network_id) | |
{ | |
$this->curl_method = 'DELETE'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/networkconf/' . trim($network_id)); | |
} | |
public function list_wlanconf($wlan_id = '') | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id)); | |
} | |
public function create_wlan( | |
$name, | |
$x_passphrase, | |
$usergroup_id, | |
$wlangroup_id, | |
$enabled = true, | |
$hide_ssid = false, | |
$is_guest = false, | |
$security = 'open', | |
$wpa_mode = 'wpa2', | |
$wpa_enc = 'ccmp', | |
$vlan_enabled = null, | |
$vlan_id = null, | |
$uapsd_enabled = false, | |
$schedule_enabled = false, | |
$schedule = [], | |
$ap_group_ids = null | |
) { | |
$payload = [ | |
'name' => trim($name), | |
'usergroup_id' => trim($usergroup_id), | |
'wlangroup_id' => trim($wlangroup_id), | |
'enabled' => $enabled, | |
'hide_ssid' => $hide_ssid, | |
'is_guest' => $is_guest, | |
'security' => trim($security), | |
'wpa_mode' => trim($wpa_mode), | |
'wpa_enc' => trim($wpa_enc), | |
'uapsd_enabled' => $uapsd_enabled, | |
'schedule_enabled' => $schedule_enabled, | |
'schedule' => $schedule, | |
]; | |
if (!empty($vlan_id)) { | |
$payload['networkconf_id'] = $vlan_id; | |
} | |
if (!empty($x_passphrase) && $security !== 'open') { | |
$payload['x_passphrase'] = trim($x_passphrase); | |
} | |
if (!empty($ap_group_ids) && is_array($ap_group_ids)) { | |
$payload['ap_group_ids'] = $ap_group_ids; | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/add/wlanconf', $payload); | |
} | |
public function set_wlansettings_base($wlan_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id), $payload); | |
} | |
public function set_wlansettings($wlan_id, $x_passphrase, $name = '') | |
{ | |
$payload = []; | |
$payload['x_passphrase'] = trim($x_passphrase); | |
if (!empty($name)) { | |
$payload['name'] = trim($name); | |
} | |
return $this->set_wlansettings_base($wlan_id, $payload); | |
} | |
public function disable_wlan($wlan_id, $disable) | |
{ | |
if (!is_bool($disable)) { | |
return false; | |
} | |
$action = !$disable; | |
$payload = ['enabled' => $action]; | |
return $this->set_wlansettings_base($wlan_id, $payload); | |
} | |
public function delete_wlan($wlan_id) | |
{ | |
$this->curl_method = 'DELETE'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/wlanconf/' . trim($wlan_id)); | |
} | |
public function set_wlan_mac_filter($wlan_id, $mac_filter_policy, $mac_filter_enabled, array $macs) | |
{ | |
if (!is_bool($mac_filter_enabled)) { | |
return false; | |
} | |
if (!in_array($mac_filter_policy, ['allow', 'deny'])) { | |
return false; | |
} | |
$macs = array_map('strtolower', $macs); | |
$payload = [ | |
'mac_filter_enabled' => (bool) $mac_filter_enabled, | |
'mac_filter_policy' => $mac_filter_policy, | |
'mac_filter_list' => $macs, | |
]; | |
return $this->set_wlansettings_base($wlan_id, $payload); | |
} | |
public function list_events($historyhours = 720, $start = 0, $limit = 3000) | |
{ | |
$payload = [ | |
'_sort' => '-time', | |
'within' => intval($historyhours), | |
'type' => null, | |
'_start' => intval($start), | |
'_limit' => intval($limit), | |
]; | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/event', $payload); | |
} | |
public function list_alarms($payload = []) | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/list/alarm', $payload); | |
} | |
public function count_alarms($archived = null) | |
{ | |
$path_suffix = $archived === false ? '?archived=false' : null; | |
return $this->fetch_results('/api/s/' . $this->site . '/cnt/alarm' . $path_suffix); | |
} | |
public function archive_alarm($alarm_id = '') | |
{ | |
$payload = ['cmd' => 'archive-all-alarms']; | |
if (!empty($alarm_id)) { | |
$payload = ['_id' => $alarm_id, 'cmd' => 'archive-alarm']; | |
} | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/evtmgr', $payload); | |
} | |
public function check_controller_update() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/fwupdate/latest-version'); | |
} | |
public function check_firmware_update() | |
{ | |
$payload = ['cmd' => 'check-firmware-update']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/productinfo', $payload); | |
} | |
public function upgrade_device($device_mac) | |
{ | |
$payload = ['mac' => strtolower($device_mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr/upgrade', $payload); | |
} | |
public function upgrade_device_external($firmware_url, $device_mac) | |
{ | |
$payload = ['url' => filter_var($firmware_url, FILTER_SANITIZE_URL), 'mac' => strtolower($device_mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr/upgrade-external', $payload); | |
} | |
public function start_rolling_upgrade() | |
{ | |
$payload = ['cmd' => 'set-rollupgrade']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function cancel_rolling_upgrade() | |
{ | |
$payload = ['cmd' => 'unset-rollupgrade']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function list_firmware($type = 'available') | |
{ | |
if (!in_array($type, ['available', 'cached'])) { | |
return false; | |
} | |
$payload = ['cmd' => 'list-' . $type]; | |
return $this->fetch_results('/api/s/' . $this->site . '/cmd/firmware', $payload); | |
} | |
public function power_cycle_switch_port($switch_mac, $port_idx) | |
{ | |
$payload = ['mac' => strtolower($switch_mac), 'port_idx' => intval($port_idx), 'cmd' => 'power-cycle']; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function spectrum_scan($ap_mac) | |
{ | |
$payload = ['cmd' => 'spectrum-scan', 'mac' => strtolower($ap_mac)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/devmgr', $payload); | |
} | |
public function spectrum_scan_state($ap_mac) | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/stat/spectrum-scan/' . strtolower(trim($ap_mac))); | |
} | |
public function set_device_settings_base($device_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/device/' . trim($device_id), $payload); | |
} | |
public function list_radius_profiles() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/radiusprofile'); | |
} | |
public function list_radius_accounts() | |
{ | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/account'); | |
} | |
public function create_radius_account($name, $x_password, $tunnel_type = null, $tunnel_medium_type = null, $vlan = null) | |
{ | |
$tunnel_type_values = [null, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; | |
$tunnel_medium_type_values = [null, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; | |
if (!in_array($tunnel_type, $tunnel_type_values) || !in_array($tunnel_medium_type, $tunnel_medium_type_values) || ($tunnel_type xor $tunnel_medium_type)) { | |
return false; | |
} | |
$payload = [ | |
'name' => $name, | |
'x_password' => $x_password, | |
]; | |
if (!is_null($tunnel_type)) { | |
$payload['tunnel_type'] = (int) $tunnel_type; | |
} | |
if (!is_null($tunnel_medium_type)) { | |
$payload['tunnel_medium_type'] = (int) $tunnel_medium_type; | |
} | |
if (!is_null($vlan)) { | |
$payload['vlan'] = (string) $vlan; | |
} | |
return $this->fetch_results('/api/s/' . $this->site . '/rest/account', $payload); | |
} | |
public function set_radius_account_base($account_id, $payload) | |
{ | |
$this->curl_method = 'PUT'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id), $payload); | |
} | |
public function delete_radius_account($account_id) | |
{ | |
$this->curl_method = 'DELETE'; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/rest/account/' . trim($account_id)); | |
} | |
public function cmd_stat($command) | |
{ | |
if ($command != 'reset-dpi') { | |
return false; | |
} | |
$payload = ['cmd' => trim($command)]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/cmd/stat', $payload); | |
} | |
public function set_element_adoption($enable) | |
{ | |
if (!is_bool($enable)) { | |
return false; | |
} | |
$payload = ['enabled' => $enable]; | |
return $this->fetch_results_boolean('/api/s/' . $this->site . '/set/setting/element_adopt', $payload); | |
} | |
public function list_device_states() | |
{ | |
return [ | |
0 => 'offline', | |
1 => 'connected', | |
2 => 'pending adoption', | |
4 => 'updating', | |
5 => 'provisioning', | |
6 => 'unreachable', | |
7 => 'adopting', | |
9 => 'adoption error', | |
10 => 'adoption failed', | |
11 => 'isolated', | |
]; | |
} | |
public function custom_api_request($path, $method = 'GET', $payload = null, $return = 'array') | |
{ | |
if (!in_array($method, $this->curl_methods_allowed)) { | |
return false; | |
} | |
if (strpos($path, '/') !== 0) { | |
return false; | |
} | |
$this->curl_method = $method; | |
if ($return === 'array') { | |
return $this->fetch_results($path, $payload); | |
} elseif ($return === 'boolean') { | |
return $this->fetch_results_boolean($path, $payload); | |
} | |
return false; | |
} | |
public function list_aps($device_mac = null) | |
{ | |
trigger_error( | |
'Function list_aps() has been deprecated, use list_devices() instead.', | |
E_USER_DEPRECATED | |
); | |
return $this->list_devices($device_mac); | |
} | |
public function set_locate_ap($mac) | |
{ | |
trigger_error( | |
'Function set_locate_ap() has been deprecated, use locate_ap() instead.', | |
E_USER_DEPRECATED | |
); | |
return $this->locate_ap($mac, true); | |
} | |
public function unset_locate_ap($mac) | |
{ | |
trigger_error( | |
'Function unset_locate_ap() has been deprecated, use locate_ap() instead.', | |
E_USER_DEPRECATED | |
); | |
return $this->locate_ap($mac, false); | |
} | |
public function site_ledson() | |
{ | |
trigger_error( | |
'Function site_ledson() has been deprecated, use site_leds() instead.', | |
E_USER_DEPRECATED | |
); | |
return $this->site_leds(true); | |
} | |
public function site_ledsoff() | |
{ | |
trigger_error( | |
'Function site_ledsoff() has been deprecated, use site_leds() instead.', | |
E_USER_DEPRECATED | |
); | |
return $this->site_leds(false); | |
} | |
public function restart_ap($mac) | |
{ | |
trigger_error( | |
'Function restart_ap() has been deprecated, use restart_device() instead.', | |
E_USER_DEPRECATED | |
); | |
return $this->restart_device($mac); | |
} | |
public function set_site($site) | |
{ | |
$this->check_site($site); | |
$this->site = trim($site); | |
return $this->site; | |
} | |
public function get_site() | |
{ | |
return $this->site; | |
} | |
public function set_debug($enable) | |
{ | |
if ($enable === true || $enable === false) { | |
$this->debug = $enable; | |
return true; | |
} | |
trigger_error('Error: the parameter for set_debug() must be boolean'); | |
return false; | |
} | |
public function get_debug() | |
{ | |
return $this->debug; | |
} | |
public function get_last_results_raw($return_json = false) | |
{ | |
if (!is_null($this->last_results_raw)) { | |
if ($return_json) { | |
return json_encode($this->last_results_raw, JSON_PRETTY_PRINT); | |
} | |
return $this->last_results_raw; | |
} | |
return false; | |
} | |
public function get_last_error_message() | |
{ | |
return $this->last_error_message; | |
} | |
public function get_cookie() | |
{ | |
return $this->cookies; | |
} | |
public function get_cookies() | |
{ | |
return $this->cookies; | |
} | |
public function get_class_version() | |
{ | |
return self::CLASS_VERSION; | |
} | |
public function set_cookies($cookies_value) | |
{ | |
$this->cookies = $cookies_value; | |
} | |
public function get_curl_method() | |
{ | |
return $this->curl_method; | |
} | |
public function set_curl_method($curl_method) | |
{ | |
if (!in_array($curl_method, $this->curl_methods_allowed)) { | |
return false; | |
} | |
$this->curl_method = $curl_method; | |
return true; | |
} | |
public function get_curl_ssl_verify_peer() | |
{ | |
return $this->curl_ssl_verify_peer; | |
} | |
public function set_curl_ssl_verify_peer($curl_ssl_verify_peer) | |
{ | |
if (!in_array($curl_ssl_verify_peer, [0, false, 1, true])) { | |
return false; | |
} | |
$this->curl_ssl_verify_peer = $curl_ssl_verify_peer; | |
return true; | |
} | |
public function get_curl_ssl_verify_host() | |
{ | |
return $this->curl_ssl_verify_host; | |
} | |
public function set_curl_ssl_verify_host($curl_ssl_verify_host) | |
{ | |
if (!in_array($curl_ssl_verify_host, [0, false, 2])) { | |
return false; | |
} | |
$this->curl_ssl_verify_host = $curl_ssl_verify_host; | |
return true; | |
} | |
public function get_is_unifi_os() | |
{ | |
return $this->is_unifi_os; | |
} | |
public function set_is_unifi_os($is_unifi_os) | |
{ | |
if (!in_array($is_unifi_os, [0, false, 1, true])) { | |
return false; | |
} | |
$this->is_unifi_os = $is_unifi_os; | |
return true; | |
} | |
public function set_connection_timeout($timeout) | |
{ | |
$this->curl_connect_timeout = $timeout; | |
} | |
public function get_connection_timeout() | |
{ | |
return $this->curl_connect_timeout; | |
} | |
public function set_curl_request_timeout($timeout) | |
{ | |
$this->curl_request_timeout = $timeout; | |
} | |
public function get_curl_request_timeout() | |
{ | |
return $this->curl_request_timeout; | |
} | |
public function set_curl_http_version($http_version) | |
{ | |
$this->curl_http_version = $http_version; | |
} | |
public function get_curl_http_version() | |
{ | |
return $this->curl_http_version; | |
} | |
protected function fetch_results($path, $payload = null, $boolean = false, $login_required = true) | |
{ | |
if ($login_required && !$this->is_logged_in) { | |
return false; | |
} | |
$this->last_results_raw = $this->exec_curl($path, $payload); | |
if (is_string($this->last_results_raw)) { | |
$response = json_decode($this->last_results_raw); | |
$this->catch_json_last_error(); | |
if (isset($response->meta->rc)) { | |
if ($response->meta->rc === 'ok') { | |
$this->last_error_message = ''; | |
if (is_array($response->data) && !$boolean) { | |
return $response->data; | |
} | |
return true; | |
} elseif ($response->meta->rc === 'error') { | |
if (isset($response->meta->msg)) { | |
$this->last_error_message = $response->meta->msg; | |
if ($this->debug) { | |
trigger_error('Debug: Last error message: ' . $this->last_error_message); | |
} | |
} | |
} | |
} | |
if (strpos($path, '/v2/api/') === 0) { | |
if (isset($response->errorCode)) { | |
if (isset($response->message)) { | |
$this->last_error_message = $response->message; | |
if ($this->debug) { | |
trigger_error('Debug: Last error message: ' . $this->last_error_message); | |
} | |
} | |
return false; | |
} | |
return $response; | |
} | |
} | |
return false; | |
} | |
protected function fetch_results_boolean($path, $payload = null, $login_required = true) | |
{ | |
return $this->fetch_results($path, $payload, true, $login_required); | |
} | |
protected function catch_json_last_error() | |
{ | |
if ($this->debug) { | |
$error = 'Unknown JSON error occurred'; | |
switch (json_last_error()) { | |
case JSON_ERROR_NONE: | |
// JSON is valid, no error has occurred and return true early | |
return true; | |
case JSON_ERROR_DEPTH: | |
$error = 'The maximum stack depth has been exceeded'; | |
break; | |
case JSON_ERROR_STATE_MISMATCH: | |
$error = 'Invalid or malformed JSON'; | |
break; | |
case JSON_ERROR_CTRL_CHAR: | |
$error = 'Control character error, possibly incorrectly encoded'; | |
break; | |
case JSON_ERROR_SYNTAX: | |
$error = 'Syntax error, malformed JSON'; | |
break; | |
case JSON_ERROR_UTF8: | |
// PHP >= 5.3.3 | |
$error = 'Malformed UTF-8 characters, possibly incorrectly encoded'; | |
break; | |
case JSON_ERROR_RECURSION: | |
// PHP >= 5.5.0 | |
$error = 'One or more recursive references in the value to be encoded'; | |
break; | |
case JSON_ERROR_INF_OR_NAN: | |
// PHP >= 5.5.0 | |
$error = 'One or more NAN or INF values in the value to be encoded'; | |
break; | |
case JSON_ERROR_UNSUPPORTED_TYPE: | |
$error = 'A value of a type that cannot be encoded was given'; | |
break; | |
} | |
if (defined('JSON_ERROR_INVALID_PROPERTY_NAME') && defined('JSON_ERROR_UTF16')) { | |
switch (json_last_error()) { | |
case JSON_ERROR_INVALID_PROPERTY_NAME: | |
$error = 'A property name that cannot be encoded was given'; | |
break; | |
case JSON_ERROR_UTF16: | |
$error = 'Malformed UTF-16 characters, possibly incorrectly encoded'; | |
break; | |
} | |
} | |
trigger_error('JSON decode error: ' . $error); | |
return false; | |
} | |
return true; | |
} | |
protected function check_base_url($baseurl) | |
{ | |
if (!filter_var($baseurl, FILTER_VALIDATE_URL) || substr($baseurl, -1) === '/') { | |
trigger_error('The URL provided is incomplete, invalid or ends with a / character!'); | |
return false; | |
} | |
return true; | |
} | |
protected function check_site($site) | |
{ | |
if ($this->debug && preg_match("/\s/", $site)) { | |
trigger_error('The provided (short) site name may not contain any spaces'); | |
return false; | |
} | |
return true; | |
} | |
protected function update_unificookie() | |
{ | |
if (session_status() === PHP_SESSION_ACTIVE && isset($_SESSION['unificookie']) && !empty($_SESSION['unificookie'])) { | |
$this->cookies = $_SESSION['unificookie']; | |
if (strpos($this->cookies, 'TOKEN') !== false) { | |
$this->is_unifi_os = true; | |
} | |
return true; | |
} | |
return false; | |
} | |
protected function create_x_csrf_token_header() | |
{ | |
if (!empty($this->cookies) && strpos($this->cookies, 'TOKEN') !== false) { | |
$cookie_bits = explode('=', $this->cookies); | |
if (empty($cookie_bits) || !array_key_exists(1, $cookie_bits)) { | |
return; | |
} | |
$jwt_components = explode('.', $cookie_bits[1]); | |
if (empty($jwt_components) || !array_key_exists(1, $jwt_components)) { | |
return; | |
} | |
$this->curl_headers[] = 'x-csrf-token: ' . json_decode(base64_decode($jwt_components[1]))->csrfToken; | |
} | |
} | |
protected function response_header_callback($ch, $header_line) | |
{ | |
if (strpos($header_line, 'unifises') !== false || strpos($header_line, 'TOKEN') !== false) { | |
$cookie = trim(str_replace(['set-cookie: ', 'Set-Cookie: '], '', $header_line)); | |
if (!empty($cookie)) { | |
$cookie_crumbs = explode(';', $cookie); | |
foreach ($cookie_crumbs as $cookie_crumb) { | |
if (strpos($cookie_crumb, 'unifises') !== false) { | |
$this->cookies = $cookie_crumb; | |
$this->is_logged_in = true; | |
$this->is_unifi_os = false; | |
break; | |
} | |
if (strpos($cookie_crumb, 'TOKEN') !== false) { | |
$this->cookies = $cookie_crumb; | |
$this->is_logged_in = true; | |
$this->is_unifi_os = true; | |
break; | |
} | |
} | |
} | |
} | |
return strlen($header_line); | |
} | |
protected function exec_curl($path, $payload = null) | |
{ | |
if (!in_array($this->curl_method, $this->curl_methods_allowed)) { | |
trigger_error('an invalid HTTP request type was used: ' . $this->curl_method); | |
return false; | |
} | |
if (!($ch = $this->get_curl_handle())) { | |
trigger_error('get_curl_handle() did not return a resource'); | |
return false; | |
} | |
$this->curl_headers = []; | |
$url = $this->baseurl . $path; | |
if ($this->is_unifi_os) { | |
$url = $this->baseurl . '/proxy/network' . $path; | |
} | |
$curl_options = [ | |
CURLOPT_URL => $url, | |
]; | |
$json_payload = ''; | |
if (!empty($payload)) { | |
$json_payload = json_encode($payload, JSON_UNESCAPED_SLASHES); | |
$curl_options[CURLOPT_POSTFIELDS] = $json_payload; | |
$this->curl_headers = [ | |
'content-type: application/json', | |
'Expect:', | |
]; | |
if ($this->curl_method === 'GET' || $this->curl_method === 'DELETE') { | |
$this->curl_method = 'POST'; | |
} | |
} | |
switch ($this->curl_method) { | |
case 'POST': | |
$curl_options[CURLOPT_POST] = true; | |
break; | |
case 'DELETE': | |
$curl_options[CURLOPT_CUSTOMREQUEST] = 'DELETE'; | |
break; | |
case 'PUT': | |
$curl_options[CURLOPT_CUSTOMREQUEST] = 'PUT'; | |
break; | |
case 'PATCH': | |
$curl_options[CURLOPT_CUSTOMREQUEST] = 'PATCH'; | |
break; | |
} | |
if ($this->is_unifi_os && $this->curl_method !== 'GET') { | |
$this->create_x_csrf_token_header(); | |
} | |
if (count($this->curl_headers) > 0) { | |
$curl_options[CURLOPT_HTTPHEADER] = $this->curl_headers; | |
} | |
curl_setopt_array($ch, $curl_options); | |
$response = curl_exec($ch); | |
if (curl_errno($ch)) { | |
trigger_error('cURL error: ' . curl_error($ch)); | |
} | |
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); | |
if ($http_code === 401) { | |
if ($this->debug) { | |
error_log(__FUNCTION__ . ': needed to reconnect to UniFi controller'); | |
} | |
if ($this->exec_retries === 0) { | |
if (isset($_SESSION['unificookie'])) { | |
$_SESSION['unificookie'] = ''; | |
} | |
$this->is_logged_in = false; | |
$this->cookies = ''; | |
$this->exec_retries++; | |
curl_close($ch); | |
$this->login(); | |
if ($this->is_logged_in) { | |
if ($this->debug) { | |
error_log(__FUNCTION__ . ': re-logged in, calling exec_curl again'); | |
} | |
return $this->exec_curl($path, $payload); | |
} | |
if ($this->debug) { | |
error_log(__FUNCTION__ . ': re-login failed'); | |
} | |
} | |
return false; | |
} | |
if ($this->debug) { | |
print PHP_EOL . '<pre>'; | |
print PHP_EOL . '---------cURL INFO-----------' . PHP_EOL; | |
print_r(curl_getinfo($ch)); | |
print PHP_EOL . '-------URL & PAYLOAD---------' . PHP_EOL; | |
print $url . PHP_EOL; | |
if (empty($json_payload)) { | |
print 'empty payload'; | |
} | |
print $json_payload; | |
print PHP_EOL . '----------RESPONSE-----------' . PHP_EOL; | |
print $response; | |
print PHP_EOL . '-----------------------------' . PHP_EOL; | |
print '</pre>' . PHP_EOL; | |
} | |
curl_close($ch); | |
$this->curl_method = 'GET'; | |
return $response; | |
} | |
protected function get_curl_handle() | |
{ | |
$ch = curl_init(); | |
if (is_object($ch) || is_resource($ch)) { | |
$curl_options = [ | |
CURLOPT_PROTOCOLS => CURLPROTO_HTTPS, | |
CURLOPT_HTTP_VERSION => $this->curl_http_version, | |
CURLOPT_SSL_VERIFYPEER => $this->curl_ssl_verify_peer, | |
CURLOPT_SSL_VERIFYHOST => $this->curl_ssl_verify_host, | |
CURLOPT_CONNECTTIMEOUT => $this->curl_connect_timeout, | |
CURLOPT_TIMEOUT => $this->curl_request_timeout, | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_ENCODING => '', | |
CURLOPT_HEADERFUNCTION => [$this, 'response_header_callback'], | |
]; | |
if ($this->debug) { | |
$curl_options[CURLOPT_VERBOSE] = true; | |
} | |
if (!empty($this->cookies)) { | |
$curl_options[CURLOPT_COOKIESESSION] = true; | |
$curl_options[CURLOPT_COOKIE] = $this->cookies; | |
} | |
curl_setopt_array($ch, $curl_options); | |
return $ch; | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment