PluginProbe
WebTotem Security / 2.4.36
WebTotem Security v2.4.36
3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 2.2.4 All 109 releases
wt-security / lib / API.php

API.php in WebTotem Security 2.4.36, at lib/API.php

1,348 lines 50.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('WEBTOTEM_INIT') || WEBTOTEM_INIT !== true) {
4 if (!headers_sent()) {
5 header('HTTP/1.1 403 Forbidden');
6 }
7 die("Protected By WebTotem!");
8 }
9
10 /**
11 * WebTotem API class.
12 *
13 * Mostly contains wrappers for API methods. Check and send methods.
14 *
15 * @version 1.0
16 * @copyright (C) 2022 WebTotem team (http://wtotem.com)
17 * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
18 */
19 class WebTotemAPI extends WebTotem
20 {
21
22 /**
23 * Method for getting an auth token.
24 *
25 * @param string $api_key
26 * Application programming interface key.
27 *
28 * @return bool|string
29 * Returns auth status
30 */
31 public static function auth($api_key, $repeat = false)
32 {
33 $domain = WEBTOTEM_SITE_DOMAIN;
34
35 if (substr($api_key, 1, 1) == "-") {
36 $prefix = substr($api_key, 0, 1);
37 if ($api_url = self::getApiUrl($prefix)) {
38 WebTotemOption::setOptions(['api_url' => $api_url, 'api_environment' => $prefix]);
39 } else {
40 WebTotemOption::setNotification('error', __('Invalid API key', 'wtotem'));
41 return FALSE;
42 }
43 $api_key = substr($api_key, 2);
44 }
45
46 if (empty($api_key)) {
47 return FALSE;
48 }
49
50 $payload = '{"query":"mutation{ guest{ apiKeys{ auth(apiKey:\"' . $api_key . '\", source:\"' . $domain . '\"),{ token{ value, refreshToken, expiresIn } } } } }"}';
51 $result = self::sendRequest($payload, FALSE, TRUE);
52
53 if (isset($result['data']['guest']['apiKeys']['auth']['token']['value'])) {
54 $auth_token = $result['data']['guest']['apiKeys']['auth']['token'];
55 if(!WebTotemOption::isActivated()){
56 WebTotemOption::login(['token' => $auth_token, 'api_key' => $api_key]);
57 WebTotemAgentManager::postdelete();
58 } else {
59 WebTotemOption::setOptions(['auth_token' => $auth_token['value'], 'auth_token_expired' => time() + $auth_token['expiresIn'] - 60]);
60 }
61
62 return 'success';
63 } elseif (isset($result['errors'][0]['message']) and $result['errors'][0]['message'] == 'INVALID_API_KEY') {
64 WebTotemOption::logout();
65 }
66
67 if($repeat == false){
68 self::checkEndpoint();
69 return self::auth($api_key, true);
70 }
71
72 return FALSE;
73 }
74
75 /**
76 * Method for getting API url.
77 *
78 * @param string $prefix
79 *
80 * @return string|bool
81 * API url
82 */
83 public static function getApiUrl($prefix)
84 {
85 $urls = [
86 'P' => 'wtotem.com',
87 'C' => 'webtotem.kz',
88 'M' => 'wtotem.net',
89 ];
90
91 if (array_key_exists($prefix, $urls)) {
92 return 'https://api.' . $urls[$prefix] . '/graphql';
93 }
94 return false;
95 }
96
97 /**
98 * Method to check endpoint.
99 */
100 public static function checkEndpoint() {
101 global $wp_filesystem;
102
103 if ( empty( $wp_filesystem ) ) {
104 require_once( ABSPATH . 'wp-admin/includes/file.php' );
105 WP_Filesystem();
106 }
107
108 $api_params['api_url'] = WebTotemOption::getOption('api_url');
109 $api_params['api_environment'] = WebTotemOption::getOption('api_environment');
110
111 switch ($api_params['api_environment'] ?? $api_params['api_url'] ){
112 case 'P' :
113 case 'https://api.wtotem.com/graphql':
114 $path = 'https://api.wtotem.com/isv20/health-check';
115 $new_api_params = ['api_environment' => 'M', 'api_url' => 'https://api.wtotem.net/graphql' ];
116 break;
117
118 case "M":
119 case "https://api.wtotem.net/graphql":
120 $path = 'https://api.wtotem.net/isv20/health-check';
121 $new_api_params = ['api_environment' => 'P', 'api_url' => 'https://api.wtotem.com/graphql' ];
122 break;
123
124 default:
125 $path = 'https://api.wtotem.com/isv20/health-check';
126 $new_api_params = ['api_environment' => 'M', 'api_url' => 'https://api.wtotem.net/graphql' ];
127 }
128
129
130 if(!empty($wp_filesystem)){
131 $response = $wp_filesystem->get_contents($path);
132 } else {
133 $response = file_get_contents($path);
134 }
135
136 if($response){
137 $response_json = json_decode($response, true);
138
139 if(is_array($response_json)){
140 if($response_json['status'] === "OK"){
141 return true;
142 }
143 }
144 }
145
146 WebTotemOption::setOptions($new_api_params);
147 return false;
148
149 }
150
151 /**
152 * Get site info from API server.
153 *
154 * @param string $attempt
155 * Is the request an attempt to get host data.
156 *
157 * @return array
158 * Returns host data.
159 */
160 public static function siteInfo($attempt = FALSE)
161 {
162 if (self::isMultiSite()) {
163 $host['id'] = WebTotemOption::getSessionOption('host_id');
164 $host['name'] = WebTotemOption::getSessionOption('host_name');
165
166 if ($host['id']) {
167 return $host;
168 }
169 }
170
171 $host = WebTotemOption::getHost();
172
173 if ($host['id']) {
174 return $host;
175 }
176
177 if (self::isMultiSite()) {
178 $sites = get_sites();
179 foreach ($sites as $site) {
180 $domain = untrailingslashit($site->domain . $site->path);
181 self::addSite($domain);
182 }
183
184 if (!$attempt) {
185 return self::siteInfo(TRUE);
186 }
187 } else {
188 $domain = WEBTOTEM_SITE_DOMAIN;
189 return self::addSite($domain);
190 }
191
192
193 return [];
194 }
195
196 /**
197 * Method for adding a site to the WebTotem platform.
198 *
199 * @param string $domain
200 * Domain to add.
201 *
202 * @return array
203 * Returns host data.
204 */
205 public static function addSite($domain)
206 {
207 if (function_exists('idn_to_utf8')) {
208 $domain = idn_to_utf8($domain);
209 }
210
211 $matches = self::checkForMatches($domain);
212
213 // Checking if the site has been added to the WebTotem.
214 if (array_key_exists('edges', $matches)) {
215
216 foreach ($matches['edges'] as $site) {
217 $site = $site['node'];
218 $hostname = untrailingslashit($site['hostname']);
219 // If it added, save site data to DB.
220 if ($hostname == $domain or $hostname == 'www.' . $domain) {
221 WebTotemOption::setHost($site['hostname'], $site['id']);
222 return [
223 'id' => $site['id'],
224 'name' => $site['hostname'],
225 ];
226 }
227 }
228
229 }
230
231
232
233 $scheme = is_ssl() ? 'https' : 'http';
234
235 // If the site is not added then try to add.
236 $payload = '{"variables":{"input":{"title":"' . $domain . '","hostname":"' . $domain . '","configs":{"scheme":"' . $scheme . '","port":' . $_SERVER['SERVER_PORT'] . ',"wa":{},"dec":{},"ps":{}}}},"query":"mutation ($input: CreateSiteInput) { auth { sites { create(input: $input) { id hostname title } } } }"}';
237 $add_site = self::sendRequest($payload, TRUE);
238 if (isset($add_site['errors'])) {
239 WebTotemOption::setNotification('error', __('Failed to add the site to the WebTotem platform.', 'wtotem'));
240 } else {
241 if ($host = $add_site['data']['auth']['sites']['create']) {
242 // If it added, save site ID.
243 WebTotemOption::setHost($host['title'], $host['id']);
244 return [
245 'id' => $host['id'],
246 'name' => $host['title'],
247 ];
248 }
249 }
250 return [];
251 }
252
253 /**
254 * Get all sites from API.
255 *
256 * @param string $cursor
257 * Mark for loading data.
258 * @param string $limit
259 * Limit of sites to loading.
260 *
261 * @return array
262 * Returns host data.
263 */
264 public static function getSites($cursor = null, $limit = 15, $filter = false)
265 {
266 $cursor = ($cursor == null) ? 'null' : '\"' . $cursor . '\"';
267 if (!$filter) {
268 $filter = ($limit === 0) ? '' : 'pagination:{ first: ' . $limit . ', cursor: ' . $cursor . ' }';
269 }
270
271 $payload = '{"query":"query getSites { auth { viewer { sites { ...sites } } } } fragment sites on SiteQueries { list(filter: { ' . $filter . ' }) { pageInfo{ hasNextPage endCursor } edges { node { id hostname title createdAt ssl { status } availability { status } reputation { status } ports { status } deface { status } antivirus { status } firewall { status } maliciousScript { stack { name } } } } } }"}';
272 $result = self::sendRequest($payload, true);
273
274 if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
275 return $result['data']['auth']['viewer']['sites']['list'];
276 }
277
278 return [];
279 }
280
281 /**
282 * Check the site's presence in the list on the API side.
283 *
284 * @param string $site
285 * The domain we want to check.
286 *
287 * @return array
288 * Returns host data.
289 */
290 public static function checkForMatches($site)
291 {
292 $payload = '{"query": "query getSites { auth { viewer { sites { list(filter: { search: \"'. $site .'\" }) { edges{ node{ hostname id } } } } } } }" }';
293 $result = self::sendRequest($payload, true);
294
295 if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
296 return $result['data']['auth']['viewer']['sites']['list'];
297 }
298
299 return [];
300 }
301
302
303 /**
304 * Method to get the agents file names and AM file link.
305 *
306 * @param string $host_id
307 * Host id on WebTotem.
308 *
309 * @return array
310 * Returns agents files data.
311 */
312 public static function getAgentsFiles($host_id)
313 {
314
315 if (WebTotem::isMultiSite()) {
316 $all_hosts = WebTotemOption::getOption('all_hosts');
317 $all_hosts = $all_hosts ? json_decode($all_hosts, true) : [];
318
319 $siteIdsArray = $all_hosts ? array_values($all_hosts) : [];
320 $siteIds = $siteIdsArray ? addslashes(WebTotem::convertArrayToString($siteIdsArray)) : '';
321
322 $payload = '{"query":"mutation { auth { am { installMultisite(mainSiteId: \"' . $host_id . '\", siteIds: [' . $siteIds . ']){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
323 $response = self::sendRequest($payload, TRUE);
324
325 if (isset($response['data']['auth']['am']['installMultisite'])) {
326 return $response['data']['auth']['am']['installMultisite'];
327 }
328 } else {
329 $payload = '{"query":"mutation { auth { am { install(siteId: \"' . $host_id . '\"){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
330 $response = self::sendRequest($payload, TRUE);
331 if (isset($response['data']['auth']['am']['install'])) {
332 return $response['data']['auth']['am']['install'];
333 }
334 }
335 return [];
336 }
337
338 /**
339 * Add secondary MultiSite host.
340 *
341 * @param $new_sites
342 * An array with sites to add.
343 *
344 * @return void.
345 */
346 public static function addMultiSiteNewSites($new_sites)
347 {
348 // Host id of the main site in MultiSite network.
349 $main_host = WebTotemOption::getMainHost();
350
351 foreach ($new_sites as $site) {
352 $all_sites = self::getSites(null, 1000000);
353 $host = self::addSite($site, $all_sites);
354 if (key_exists('id', $host)) {
355 $payload = '{"query":"mutation { auth { am { addMultisiteHost(mainSiteId: \"' . $main_host['id'] . '\", siteId: \"' . $host['id'] . '\") } } }"}';
356
357 $result = self::sendRequest($payload, TRUE);
358 if (!$result['errors'][0]['message']) {
359 WebTotemOption::setNotification('info', __('A new website has been added: ', 'wtotem') . $site);
360 }
361 }
362 }
363 }
364
365 /**
366 * Get the date of creation of the site.
367 *
368 * @param string $site
369 * The domain we want to check.
370 *
371 * @return string|bool
372 * Returns host data.
373 */
374 public static function getGetSiteAddedDate($site)
375 {
376 $payload = '{"query": "query getSites { auth { viewer { sites { list(filter: { search: \"'. $site .'\" }) { edges{ node{ createdAt } } } } } } }" }';
377 $result = self::sendRequest($payload, true);
378
379 if (isset($result['data']['auth']['viewer']['sites']['list']['edges'][0]['node']['createdAt'])) {
380 return $result['data']['auth']['viewer']['sites']['list']['edges'][0]['node']['createdAt'];
381 }
382
383 return false;
384 }
385
386 /**
387 * Remove secondary MultiSite host.
388 *
389 * @param $host_id
390 * Host id on WebTotem.
391 *
392 * @return bool
393 * Returns result removing host.
394 */
395 public static function removeMultiSiteHost($host_id)
396 {
397 $payload = '{"query":"mutation { auth { am { removeMultisiteHost(siteId: \"' . $host_id . '\") } } }"}';
398 $response = self::sendRequest($payload, TRUE);
399 if (isset($response['data']['auth']['am']['removeSecondaryMultisiteHost'])) {
400 return $response['data']['auth']['am']['removeSecondaryMultisiteHost'];
401 }
402
403 return false;
404 }
405
406 /**
407 * Method to get agents (AM, WAF, AV) statuses.
408 *
409 * @param string $host_id
410 * Host id on WebTotem.
411 *
412 * @return array
413 * Returns agents statuses data.
414 */
415 public static function getAgentsStatusesFromAPI($host_id)
416 {
417 $payload = '{"query":"query ($id: ID!) { auth { viewer { sites { one(id: $id) { agentManager { statuses { am { status } av { status } waf { status } } } } } } } }", "variables":{"id":"' . $host_id . '"}}';
418 $response = self::sendRequest($payload, TRUE);
419
420 if (isset($response['data']['auth']['viewer']['sites']['one']['agentManager']['statuses'])) {
421 return $response['data']['auth']['viewer']['sites']['one']['agentManager']['statuses'];
422 }
423
424 return [];
425 }
426
427 /**
428 * Method to get user time zone.
429 *
430 * @return string|bool
431 * Returns time zone data.
432 */
433 public static function getTimeZone()
434 {
435 $payload = '{"query":"query { auth { viewer{ timezone } } } "}';
436 $response = self::sendRequest($payload, TRUE);
437
438 if (isset($response['data']['auth']['viewer']['timezone'])) {
439 return $response['data']['auth']['viewer']['timezone'];
440 }
441 return FALSE;
442 }
443
444 /**
445 * Method for get all the site security data.
446 *
447 * @param string $host_id
448 * Host id on WebTotem.
449 * @param int|array $days
450 * For what period data is needed.
451 *
452 * @return array
453 * Returns all data.
454 */
455 public static function getAllData($host_id, $days = 7)
456 {
457 $language = WebTotem::getLanguage();
458 $period = WebTotem::getPeriod($days);
459
460 $payload = '{"query":"query($id: ID!, $dateRange: DateRangeInput!, $language: Language!, $dateRangeWeek: DateRangeInput!, $wafLogFilter: WafLogFilter!) { auth { viewer { sites { one(id: $id) { openPathSearch { time paths { httpCode severity path } } ports { status lastTest { time } ignorePorts TCPResults{ port technology version cveList{id summary } } UDPResults { port technology version cveList{id summary } } } domain { lastScanResult { isTaken hasSite redirectLink isLocal protection ips { ip location } status time } } sslResults{ results{ certStatus certIssuerName certExpiryDate certIssueDate } } ssl { status daysLeft expiryDate issueDate } reputation { status lastTest { time } virusList { virus{ type path } antiVirus } } firewall { lastTest { time } logs(wafLogFilter: $wafLogFilter){ edges{ node{ type blocked payload ip proxyIp userAgent description source region signatureId location{ country{ nameEn } } time request status country category } } } map(dateRange: $dateRange) { attacks, country } status chart(dateRange: $dateRange) { time attacks blocked } report(dateRange: $dateRange) { time attacks ip } } serverStatus { info { phpVersion phpServerUser phpServerSoftware phpGatewayInterface phpServerProtocol osInfo cpuCount cpuModel CpuFreq cpuFamily lsCpu maxExecTime mathLibraries } ramChart(dateRange: $dateRangeWeek){ total value time } cpuChart(dateRange: $dateRangeWeek){ value time } discUsage{ total free } status } maliciousScript { lastTest { time } status } scoring( language: $language ){ score lastTest{ time } result{ ip country isHigherThan }} agentManager{ createdAt } antivirus { status stats { changed deleted scanned infected error } lastTest { time } isFirstCheck } } } } } }","variables":{"id":"' . $host_id . '","dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '}, "dateRangeWeek":{"to":' . $period['to'] . ',"from":' . $period['from'] . '}, "wafLogFilter": {"dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '},"order":{"direction":"DESC","field":"time"},"pagination":{"first": 10,"cursor":null}}, "language":"' . $language . '"}}';
461 $response = self::sendRequest($payload, TRUE);
462
463 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
464 return $response['data']['auth']['viewer']['sites']['one'];
465 }
466
467 return [];
468 }
469
470
471 /**
472 * Method for get all the site security data.
473 *
474 * @param string $host_id
475 * Host id on WebTotem.
476 *
477 * @return array
478 * Returns all data.
479 */
480 public static function getMonitoring($host_id)
481 {
482
483 $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) { domain { lastScanResult { isTaken hasSite redirectLink isLocal protection ips { ip location } status time } } sslResults{ results{ certStatus certIssuerName certExpiryDate certIssueDate } } ssl { status daysLeft expiryDate issueDate } reputation { status lastTest { time } virusList { virus{ type path } antiVirus } } } } } } }","variables":{"id":"' . $host_id . '"}}';
484 $response = self::sendRequest($payload, TRUE);
485
486 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
487 return $response['data']['auth']['viewer']['sites']['one'];
488 }
489
490 return [];
491 }
492
493 /**
494 * Method to get firewall data.
495 *
496 * @param string $host_id
497 * Host id on WebTotem.
498 * @param int $limit
499 * Limit on the number of records.
500 * @param string $cursor
501 * Mark for loading data.
502 * @param int|array $days
503 * For what period data is needed.
504 *
505 * @return array
506 * Returns firewall data.
507 */
508 public static function getFirewall($host_id, $limit = 20, $cursor = NULL, $days = 365)
509 {
510 $period = WebTotem::getPeriod($days);
511 $cursor = ($cursor == NULL) ? 'null' : '"' . $cursor . '"';
512
513 $payload = '{"query":"query($id: ID!, $wafLogFilter: WafLogFilter!, $dateRange: DateRangeInput!) { auth { viewer { sites { one(id: $id) { firewall { lastTest { time } status map(dateRange: $dateRange) { attacks, country, location { country { nameEn } } } chart(dateRange: $dateRange) { time attacks blocked } ...FirewallLogFragment } agentManager { createdAt } } } } } } fragment FirewallLogFragment on Waf { logs(wafLogFilter: $wafLogFilter) { edges { cursor node { type blocked payload ip proxyIp userAgent description source region signatureId location { country { nameEn } } time request status country category } } pageInfo { endCursor hasNextPage } } }", "variables":{"dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '},"id":"' . $host_id . '","wafLogFilter":{"dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '},"order":{"direction":"DESC","field":"time"},"pagination":{"first":' . $limit . ',"cursor":' . $cursor . '}}} }';
514 $response = self::sendRequest($payload, TRUE);
515
516 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
517 return $response['data']['auth']['viewer']['sites']['one'];
518 }
519
520 return [];
521 }
522
523 /**
524 * Method to get firewall chart data.
525 *
526 * @param string $host_id
527 * Host id on WebTotem.
528 * @param int $days
529 * For what period data is needed.
530 *
531 * @return array
532 * Returns firewall chart data.
533 */
534 public static function getFirewallChart($host_id, $days = 7)
535 {
536 $period = WebTotem::getPeriod($days);
537
538 $payload = '{ "query":"query($id: ID!, $dateRange: DateRangeInput!) { auth { viewer { sites { one(id: $id) { firewall { lastTest { time } status map(dateRange: $dateRange) { attacks, country, location { country { nameEn } } } chart(dateRange: $dateRange) { time attacks blocked } } } } } } }", "operationName":null,"variables":{"id":"' . $host_id . '","dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '} } }';
539 $response = self::sendRequest($payload, TRUE);
540
541 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
542 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
543 }
544
545 return [];
546 }
547
548 /**
549 * Method to set firewall settings.
550 *
551 * @param string $host_id
552 * Host id on WebTotem.
553 * @param array $settings
554 * User-specified settings.
555 *
556 * @return array
557 * Returns information whether the request was successful.
558 */
559 public static function setFirewallSettings($host_id, array $settings)
560 {
561 $payload = '{"variables":{"input": {"siteId": "' . $host_id . '", "gdn": ' . $settings['gdn'] . ', "dosProtection": ' . $settings['dosProtection'] . ', "dosLimit": ' . $settings['dosLimit'] . ', "loginAttemptsProtection": ' . $settings['loginAttemptsProtection'] . ', "loginAttemptsLimit": ' . $settings['loginAttemptsLimit'] . '}},"query":"mutation WafSettings($input: WafSettingsInput!) { auth { sites { waf{ settings(input: $input) { gdn dosProtection loginAttemptsProtection dosLimit loginAttemptsLimit } } } } }"}';
562 return self::sendRequest($payload, TRUE);
563 }
564
565 /**
566 * Method to get antivirus data.
567 *
568 * @param array $params
569 * Parameters for filtering data.
570 *
571 * @return array
572 * Returns antivirus data.
573 */
574 public static function getAntivirus(array $params)
575 {
576
577 $cursor = ($params['cursor']) ? '"' . $params['cursor'] . '"' : 'null';
578 $event = ($params['event']) ? '"' . $params['event'] . '"' : '"new"';
579 $permissions = ($params['permissions']) ? ' "permissionsChanged":true, ' : '';
580 $period = WebTotem::getPeriod($params['days']);
581
582 $payload = '{"operationName":null,"variables":{"id":"' . $params['host_id'] . '","avLogFilter":{' . $permissions . '"event":' . $event . ', "dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '},"order":{"direction":"DESC","field":"time"},"pagination":{"first":' . $params['limit'] . ',"cursor":' . $cursor . '}}},"query":"query ($id: ID!, $avLogFilter: AvLogFilter!) { auth { viewer { sites { one(id: $id) { id ... on Site { configs { ... on AvConfig { isActive id } } } antivirus { quarantine{ id path date } status log(avLogFilter: $avLogFilter) { edges { node { filePath event signatures time permissions permissionsChanged } } pageInfo { endCursor hasNextPage } } lastTest { time } stats { changed deleted scanned infected } } } } } } }"}';
583 $response = self::sendRequest($payload, TRUE);
584
585 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus'])) {
586 return $response['data']['auth']['viewer']['sites']['one']['antivirus'];
587 }
588 return [];
589 }
590
591 /**
592 * Method to get antivirus last test.
593 *
594 * @param string $host_id
595 * Host id on WebTotem.
596 *
597 * @return array
598 * Returns antivirus last test data.
599 */
600 public static function getAntivirusLastTest($host_id)
601 {
602
603 $payload = '{"variables":{"id":"' . $host_id . '"},"query":"query ($id: ID!) { auth { viewer { sites { one(id: $id) { antivirus { status lastTest { time } } } } } } }"}';
604 $response = self::sendRequest($payload, TRUE);
605
606 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus'])) {
607 return $response['data']['auth']['viewer']['sites']['one']['antivirus'];
608 }
609 return [];
610 }
611
612 /**
613 * Method to force check services.
614 *
615 * @param string $host_id
616 * Host id on WebTotem.
617 * @param string $service
618 * Service that needs to be checked.
619 *
620 * @return array
621 * Returns information whether the request was successful.
622 */
623 public static function forceCheck($host_id, $service)
624 {
625 $payload = '{"variables":{"id":"' . $host_id . '","service":"' . $service . '"},"query":"mutation ($id: ID!, $service: ForceCheckService!) { auth { sites { forceCheck(siteId: $id, service: $service) } } }"} ';
626 return self::sendRequest($payload, TRUE);
627 }
628
629 /**
630 * Method to export antivirus report.
631 *
632 * @param string $host_id
633 * Host id on WebTotem.
634 * @param int|array $days
635 * For what period data is needed.
636 *
637 * @return array
638 * Returns information whether the request was successful.
639 */
640 public static function avExport($host_id, $days = 30)
641 {
642 $period = WebTotem::getPeriod($days);
643 $payload = '{"variables":{ "input":{"siteId":"' . $host_id . '", "dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '} }},"query":"mutation ($input: AvLogExportInput!) { auth { sites { av { export(input: $input) } } } }"} ';
644 return self::sendRequest($payload, TRUE);
645 }
646
647 /**
648 * Method to get quarantine data.
649 *
650 * @param string $host_id
651 * Host id on WebTotem.
652 *
653 * @return array
654 * Returns quarantine data.
655 */
656 public static function getQuarantineList($host_id)
657 {
658 $payload = '{"query":"query{ auth{ viewer{ sites{ one(id:\"' . $host_id . '\"){ antivirus{ quarantine{ id path date } } } } } } } "}';
659 $response = self::sendRequest($payload, TRUE);
660
661 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus']['quarantine'])) {
662 return $response['data']['auth']['viewer']['sites']['one']['antivirus']['quarantine'];
663 }
664 return [];
665 }
666
667 /**
668 * Method to move file to quarantine.
669 *
670 * @param string $host_id
671 * Host id on WebTotem.
672 * @param string $path
673 * Path to the file.
674 *
675 * @return array
676 * Returns information whether the request was successful.
677 */
678 public static function moveToQuarantine($host_id, $path)
679 {
680 $payload = '{"query":"mutation{ auth{ sites{ av{ moveToQuarantine(input:{ siteId:\"' . $host_id . '\", path:\"' . $path . '\" }) } } } } "}';
681 return self::sendRequest($payload, TRUE);
682 }
683
684 /**
685 * Method to move file from quarantine.
686 *
687 * @param string $id
688 * Id assigned to the file.
689 *
690 * @return array
691 * Returns information whether the request was successful.
692 */
693 public static function moveFromQuarantine($id)
694 {
695 $payload = '{"query":"mutation{ auth{ sites{ av{ moveFromQuarantine(id: \"' . $id . '\") } } } } "}';
696 return self::sendRequest($payload, TRUE);
697 }
698
699 /**
700 * Method to get server status data.
701 *
702 * @param string $host_id
703 * Host id on WebTotem.
704 * @param int|array $days
705 * For what period data is needed.
706 *
707 * @return array
708 * Returns server status data.
709 */
710 public static function getServerStatusData($host_id, $days = 7)
711 {
712 $period = WebTotem::getPeriod($days);
713 $payload = '{ "query":"query($id: ID!, $dateRange: DateRangeInput!) { auth { viewer { sites { one(id: $id) { serverStatus { info { phpVersion phpServerUser phpServerSoftware phpGatewayInterface phpServerProtocol osInfo cpuCount cpuModel CpuFreq cpuFamily lsCpu maxExecTime mathLibraries } ramChart(dateRange: $dateRange){ total value time } cpuChart(dateRange: $dateRange){ value time } } } } } } }", "variables":{"id":"' . $host_id . '","dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '} } }';
714
715 $response = self::sendRequest($payload, TRUE);
716
717 if (isset($response['data']['auth']['viewer']['sites']['one']['serverStatus'])) {
718 return $response['data']['auth']['viewer']['sites']['one']['serverStatus'];
719 }
720
721 return [];
722 }
723
724 /**
725 * Method to remove port from ignore list.
726 *
727 * @param string $host_id
728 * Host id on WebTotem.
729 * @param string $port
730 * User specified port.
731 *
732 * @return array
733 * Returns information whether the request was successful.
734 */
735 public static function removeIgnorePort($host_id, $port)
736 {
737 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . $port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { removeIgnorePort(input: $input) } } } }"} ';
738 return self::sendRequest($payload, TRUE);
739 }
740
741 /**
742 * Method to add port to ignore list.
743 *
744 * @param string $host_id
745 * Host id on WebTotem.
746 * @param string $port
747 * User specified port.
748 *
749 * @return array
750 * Returns information whether the request was successful.
751 */
752 public static function addIgnorePort($host_id, $port)
753 {
754 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . (int)$port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { addIgnorePort(input: $input) } } } }"} ';
755 return self::sendRequest($payload, TRUE);
756 }
757
758 /**
759 * Method to get all ports list.
760 *
761 * @param string $host_id
762 * Host id on WebTotem.
763 *
764 * @return array
765 * Returns ports data.
766 */
767 public static function getAllPortsList($host_id)
768 {
769 $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) { ports { status lastTest { time } ignorePorts TCPResults{ port technology version cveList{id summary } } UDPResults { port technology version cveList{id summary } } } } } } } } ","variables":{"id":"' . $host_id . '"}}';
770
771 $response = self::sendRequest($payload, TRUE);
772
773 if (isset($response['data']['auth']['viewer']['sites']['one']['ports'])) {
774 return $response['data']['auth']['viewer']['sites']['one']['ports'];
775 }
776
777 return [];
778 }
779
780 /**
781 * Method to get all ports list.
782 *
783 * @param string $host_id
784 * Host id on WebTotem.
785 *
786 * @return array
787 * Returns ports data.
788 */
789 public static function getOpenPaths($host_id)
790 {
791 $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) { openPathSearch { time paths { httpCode severity path } } } } } } } ","variables":{"id":"' . $host_id . '"}}';
792
793 $response = self::sendRequest($payload, TRUE);
794
795 if (isset($response['data']['auth']['viewer']['sites']['one']['openPathSearch'])) {
796 return $response['data']['auth']['viewer']['sites']['one']['openPathSearch'];
797 }
798
799 return [];
800 }
801
802 /**
803 * Method to get all reports.
804 *
805 * @param string $host_id
806 * Host id on WebTotem.
807 * @param int $limit
808 * Limit on the number of records.
809 * @param string $cursor
810 * Mark for loading data.
811 *
812 * @return array
813 * Returns reports data.
814 */
815 public static function getAllReports($host_id, $limit = 10, $cursor = NULL)
816 {
817 $cursor = ($cursor == NULL) ? 'null' : '"' . $cursor . '"';
818 $payload = '{"variables":{"filter": { "order": { "direction": "DESC", "field": "created_at"}, "siteId":"' . $host_id . '", "pagination":{"first":' . $limit . ', "cursor":' . $cursor . '} } },"query":"query ReportsQuery($filter: ReportListFilter!) { auth { viewer { reports { list(filter: $filter) { edges { node { id site { hostname } createdAt wa dc ps rc sc av waf } cursor } pageInfo { endCursor hasNextPage } } } } } }"}';
819 $response = self::sendRequest($payload, TRUE);
820
821 if (isset($response['data']['auth']['viewer']['reports']['list']['edges'])) {
822 return $response['data']['auth']['viewer']['reports']['list'];
823 }
824
825 return [];
826 }
827
828 /**
829 * Method to generate report.
830 *
831 * @param string $host_id
832 * Host id on WebTotem.
833 * @param int|array $days
834 * For what period data is needed.
835 * @param array $services
836 * User-specified module settings.
837 *
838 * @return string|bool
839 * Returns report download link.
840 */
841 public static function generateReport(string $host_id, $days, array $services)
842 {
843 $period = WebTotem::getPeriod($days);
844 $language = WebTotem::getLanguage();
845
846 $payload = '{"query":"query ($input: GenerateReportInput) { auth { viewer { reports { generate(input: $input) } } } }", "variables":{ "input": { "siteId": "' . $host_id . '", "from": ' . $period['from'] . ', "to": ' . $period['to'] . ', "wa": ' . $services['wa'] . ', "dc": ' . $services['dc'] . ', "ps": ' . $services['ps'] . ', "rc": ' . $services['rc'] . ', "sc": ' . $services['sc'] . ', "av": ' . $services['av'] . ', "waf": ' . $services['waf'] . ', "language": "' . $language . '" } } }';
847 $response = self::sendRequest($payload, TRUE);
848
849 if (isset($response['data']['auth']['viewer']['reports']['generate'])) {
850 return $response['data']['auth']['viewer']['reports']['generate'];
851 }
852
853 return FALSE;
854 }
855
856 /**
857 * Method to download report.
858 *
859 * @param string $id
860 * Assigned to the report.
861 *
862 * @return string|bool
863 * Returns report download link.
864 */
865 public static function downloadReport($id)
866 {
867 $payload = '{"query": "query { auth { viewer { reports { download(id: \"' . $id . '\") } } } }"}';
868 $response = self::sendRequest($payload, TRUE);
869
870 if (isset($response['data']['auth']['viewer']['reports']['download'])) {
871 return $response['data']['auth']['viewer']['reports']['download'];
872 }
873
874 return FALSE;
875 }
876
877 /**
878 * Method to get configs data.
879 *
880 * @param string $host_id
881 * Host id on WebTotem.
882 *
883 * @return array|bool
884 * Returns configs data.
885 */
886 public static function getConfigs($host_id)
887 {
888 $payload = '{"query":"query{ auth{ viewer{ sites{ one(id:\"' . $host_id . '\"){ configs{ ... on WaConfig { id service isActive notifications } ... on WafConfig { id service isActive notifications } ... on AvConfig { id service isActive notifications } ... on DcConfig { id service isActive notifications } ... on DecConfig { id service isActive } ... on RcConfig { id service isActive notifications} ... on CmsConfig { id service isActive } ... on PsConfig { id service isActive notifications } ... on SsConfig { id service isActive } ... on ScConfig { id service isActive } } } } } } } "}';
889 $response = self::sendRequest($payload, TRUE);
890
891 if (isset($response['data']['auth']['viewer']['sites']['one']['configs'])) {
892 return $response['data']['auth']['viewer']['sites']['one']['configs'];
893 }
894
895 return FALSE;
896 }
897
898 /**
899 * Method to toggle modules config.
900 *
901 * @param string $service_id
902 * Service id that we enable or disable.
903 *
904 * @return string|bool
905 * Returns information whether the request was successful.
906 */
907 public static function toggleConfigs($service_id)
908 {
909 $payload = '{"query":"mutation{ auth{ configs{ toggle(id: \"' . $service_id . '\"){ ... on WaConfig { service isActive } ... on AvConfig { service isActive } ... on DcConfig { service isActive } ... on DecConfig { service isActive } ... on RcConfig { service isActive } ... on CmsConfig { service isActive } ... on PsConfig { service isActive } ... on WafConfig { service isActive } } } } } "}';
910 $response = self::sendRequest($payload, TRUE);
911
912 if (isset($response['data']['auth']['configs']['toggle'])) {
913 return $response['data']['auth']['configs']['toggle'];
914 }
915
916 return FALSE;
917 }
918
919 /**
920 * Method to toggle modules notification.
921 *
922 * @param string $host_id
923 * Host id on WebTotem.
924 * @param string $service
925 * Service id in which we enable or disable notifications.
926 *
927 * @return string|bool
928 * Returns information whether the request was successful.
929 */
930 public static function toggleNotifications($host_id, $service)
931 {
932 $payload = '{"query":"mutation{ auth{ sites{ toggleNotifications(siteId: \"' . $host_id . '\", service: ' . $service . ') } } }"}';
933 $response = self::sendRequest($payload, TRUE);
934
935 if (isset($response['data']['auth']['sites']['toggleNotifications'])) {
936 return $response;//['data']['auth']['sites']['toggleNotifications'];
937 }
938
939 return FALSE;
940 }
941
942 /**
943 * Method to get allow/deny ip list.
944 *
945 * @param string $host_id
946 * Host id on WebTotem.
947 *
948 * @return array|bool
949 * Returns ip allow/deny lists.
950 */
951 public static function getIpLists($host_id)
952 {
953 $payload = '{"variables":{ "id": "' . $host_id . '" },"query":"query($id: ID!) { auth { viewer { sites{ one(id: $id){ firewall{ blackList{ id ip createdAt } whiteList{ id ip createdAt } settings{ gdn dosProtection dosLimit loginAttemptsProtection loginAttemptsLimit } } } } } } }"} ';
954 $response = self::sendRequest($payload, TRUE);
955
956 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
957 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
958 }
959
960 return [];
961 }
962
963 /**
964 * Method to add ip to allow/deny list.
965 *
966 * @param string $host_id
967 * Host id on WebTotem.
968 * @param string $ips
969 * Ip address list.
970 * @param string $list
971 * Allow or deny list.
972 *
973 * @return bool
974 * Returns information whether the request was successful.
975 */
976 public static function addIpToList($host_id, $ips, $list)
977 {
978
979 if ($ips) {
980 $ips = WebTotem::convertIpListForApi($ips);
981 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "ips": ' . $ips . ', "color": "' . $list . '" } }, "query":"mutation($input: WafListInput!) { auth { sites { waf { addToList(input: $input){ status invalidIPs} } } } }"} ';
982 $response = self::sendRequest($payload, TRUE);
983
984 if (isset($response['data']['auth']['sites']['waf']['addToList'])) {
985 return $response['data']['auth']['sites']['waf']['addToList'];
986 }
987 }
988
989 return FALSE;
990 }
991
992 /**
993 * Method to remove ip from allow/deny list by id.
994 *
995 * @param string $id
996 * Id assignment to ip address.
997 *
998 * @return bool
999 * Returns information whether the request was successful.
1000 */
1001 public static function removeIpFromList($id)
1002 {
1003 $payload = '{"variables":{ "id": "' . $id . '" },"query":"mutation($id: ID!) { auth { sites { waf { removeFromList(id: $id) } } } }"} ';
1004 $response = self::sendRequest($payload, TRUE);
1005
1006 if (isset($response['data']['auth']['sites']['waf']['removeFromList'])) {
1007 return $response['data']['auth']['sites']['waf']['removeFromList'];
1008 }
1009
1010 return FALSE;
1011 }
1012
1013 /**
1014 * Method to get allow url list.
1015 *
1016 * @param string $host_id
1017 * Host id on WebTotem.
1018 *
1019 * @return array
1020 * Returns url allow lists.
1021 */
1022 public static function getAllowUrlList($host_id)
1023 {
1024 $payload = '{"query":"query { auth { viewer { sites { one(id: \"' . $host_id . '\"){ firewall{ urlWhiteList{ id url createdAt } } } } } } }"} ';
1025 $response = self::sendRequest($payload, TRUE);
1026
1027 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'])) {
1028 return $response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'];
1029 }
1030
1031 return [];
1032 }
1033
1034 /**
1035 * Method to add url to allow list.
1036 *
1037 * @param string $host_id
1038 * Host id on WebTotem.
1039 * @param string $url
1040 * User-specified url.
1041 *
1042 * @return bool|string
1043 * Returns information whether the request was successful.
1044 */
1045 public static function addUrlToAllowList($host_id, $url)
1046 {
1047 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "url": "' . $url . '" } }, "query":"mutation($input: WafUrlWhiteListInput!) { auth { sites { waf { addToUrlWhiteList(input: $input) } } } }"} ';
1048 $response = self::sendRequest($payload, TRUE);
1049
1050 if (isset($response['data']['auth']['sites']['waf']['addToUrlWhiteList'])) {
1051 return $response['data']['auth']['sites']['waf']['addToUrlWhiteList'];
1052 }
1053
1054 return FALSE;
1055 }
1056
1057 /**
1058 * Method to remove url from allow list.
1059 *
1060 * @param string $id
1061 * Id assignment to url address.
1062 *
1063 * @return bool|string
1064 * Returns information whether the request was successful.
1065 */
1066 public static function removeUrlFromAllowList($id)
1067 {
1068 $payload = '{"variables":{ "id": "' . $id . '" }, "query":"mutation($id: ID!) { auth { sites { waf { removeFromUrlWhiteList(id: $id) } } } }"} ';
1069 $response = self::sendRequest($payload, TRUE);
1070
1071 if (isset($response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'])) {
1072 return $response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'];
1073 }
1074
1075 return FALSE;
1076 }
1077
1078 /**
1079 * Method to get blocked countries list.
1080 *
1081 * @param string $host_id
1082 * Host id on WebTotem.
1083 *
1084 * @return array
1085 * Returns blocked countries list.
1086 */
1087 public static function getBlockedCountries($host_id)
1088 {
1089 $period = WebTotem::getPeriod(7);
1090 $payload = '{"variables":{"dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '}} , "query":"query($dateRange: DateRangeInput!){ auth { viewer { sites { one(id: \"' . $host_id . '\"){ firewall{ blockedCountries map(dateRange: $dateRange) { attacks, country, location { country { nameEn } } } } } } } } }"}';
1091 $response = self::sendRequest($payload, TRUE);
1092
1093 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
1094 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
1095 }
1096
1097 return [];
1098 }
1099
1100 /**
1101 * Method for synchronizing data on the list of blocked countries.
1102 *
1103 * @param string $host_id
1104 * Host id on WebTotem.
1105 * @param array $countries
1106 * Array of countries to block.
1107 *
1108 * @return bool|string
1109 * Returns information whether the request was successful.
1110 */
1111 public static function syncBlockedCountries($host_id, $countries)
1112 {
1113
1114 $countries = $countries ? WebTotem::convertArrayToString($countries) : '';
1115 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "countries": [' . $countries . '] } }, "query":"mutation($input: WafBlockedCountriesInput!) { auth { sites { waf { syncBlockedCountries(input: $input) } } } }"} ';
1116 $response = self::sendRequest($payload, TRUE);
1117
1118 if (isset($response['data']['auth']['sites']['waf']['syncBlockedCountries'])) {
1119 return $response['data']['auth']['sites']['waf']['syncBlockedCountries'];
1120 }
1121
1122 return FALSE;
1123 }
1124
1125 /**
1126 * Method to get user's email.
1127 *
1128 * @return string
1129 * Returns user's email.
1130 */
1131 public static function getEmail()
1132 {
1133 $payload = '{"query":"query { auth { viewer { email } } }"}';
1134 $response = self::sendRequest($payload, true);
1135
1136 return $response['data']['auth']['viewer']['email'];
1137 }
1138
1139 /**
1140 * Method to get user's email.
1141 *
1142 * @param string $plugin_list
1143 * List of plugins and their versions.
1144 *
1145 * @return array
1146 * Returns cve list.
1147 */
1148 public static function getCVE($plugin_list)
1149 {
1150 $payload = '{"variables":{ "params": [' . $plugin_list . '] }, "query":"query searchByTechnologyAndVersion($params: [SearchByTechnologyAndVersionInput!]) { auth { viewer { cve { searchByTechnologyAndVersion(params: $params) { cves { cve_id id summary published reference } technology version } } } } }"}';
1151 $response = self::sendRequest($payload, true);
1152
1153 if (isset($response['data']['auth']['viewer']['cve']['searchByTechnologyAndVersion'])) {
1154 return $response['data']['auth']['viewer']['cve']['searchByTechnologyAndVersion'];
1155 }
1156
1157 return [];
1158 }
1159
1160 /**
1161 * Method to get user's feedback.
1162 *
1163 * @return array
1164 */
1165 public static function getFeedback()
1166 {
1167 return self::sendFeedbackRequest("GET");
1168 }
1169
1170 /**
1171 * Method to set user's feedback.
1172 *
1173 * @return array
1174 */
1175 public static function setFeedback($data)
1176 {
1177 return self::sendFeedbackRequest("POST", $data);
1178 }
1179
1180 /**
1181 * Function sends data request to endpoint.
1182 *
1183 * @param array $data
1184 * Data array to be sent to endpoint.
1185 *
1186 * @return array
1187 * Returns response from WebTotem endpoint.
1188 */
1189 protected static function sendFeedbackRequest($method, $data = [])
1190 {
1191 $url = 'https://nps.wtotem.com/user-score';
1192 $email = WebTotem::getUserEmail();
1193
1194 if (!$email) {
1195 return [];
1196 }
1197
1198 if ($method == "GET") {
1199
1200 $args = [
1201 'timeout' => '30',
1202 'sslverify' => FALSE,
1203 ];
1204
1205 $response = wp_remote_get($url . '?email=' . urlencode($email), $args);
1206
1207 } else {
1208 $data['email'] = $email;
1209 $data['platform'] = 'WORDPRESS';
1210 $data = json_encode($data);
1211
1212 $args = [
1213 'body' => $data,
1214 'timeout' => '30',
1215 'sslverify' => FALSE,
1216 'headers' => [
1217 'Content-Type' => 'application/json',
1218 ],
1219 ];
1220
1221 $response = wp_remote_post($url, $args);
1222 }
1223
1224
1225 $http_code = wp_remote_retrieve_response_code($response);
1226
1227 if ($http_code < 200) {
1228 // WebTotemOption::setNotification('error', __('Could not connect to feedback endpoint.', 'wtotem'));
1229 return [];
1230 }
1231
1232 $response_body = wp_remote_retrieve_body($response);
1233 return json_decode($response_body, true);
1234 }
1235
1236 /**
1237 * Function sends GraphQL request to API server.
1238 *
1239 * @param string $payload
1240 * Payload to be sent to API server.
1241 * @param bool $token
1242 * Whether a token is needed when sending a request.
1243 * @param bool $repeat
1244 * Required to avoid recursion.
1245 *
1246 * @return array
1247 * Returns response from WebTotem API.
1248 */
1249 protected static function sendRequest($payload, $token = FALSE, $repeat = FALSE)
1250 {
1251 $api_key = WebTotemOption::getOption('api_key');
1252
1253 // Remote URL where the public WebTotem API service is running.
1254 $api_url = WebTotemOption::getOption('api_url');
1255 if (!$api_url) {
1256 $api_url = self::getApiUrl('P');
1257 WebTotemOption::setOptions(['api_url' => $api_url]);
1258 }
1259
1260 // Checking whether a token is needed.
1261 if ($token) {
1262 $auth_token = WebTotemOption::getOption('auth_token');
1263 $auth_token_expired = WebTotemOption::getOption('auth_token_expired');
1264
1265 // Checking whether the token has expired.
1266 if ($auth_token_expired <= time() && !$repeat) {
1267 $result = self::auth($api_key);
1268 if ($result === 'success') {
1269 return self::sendRequest($payload, $token, TRUE);
1270 } else {
1271 if (isset($result['errors'])) {
1272 $message = WebTotem::messageForHuman($result['errors'][0]['message']);
1273 WebTotemOption::setNotification('error', $message);
1274 }
1275 }
1276 }
1277 }
1278
1279 if (function_exists('wp_remote_post')) {
1280
1281 $args = [
1282 'body' => $payload,
1283 'timeout' => '60',
1284 'sslverify' => false,
1285 'headers' => [
1286 'Content-Type:application/json',
1287 'Content-Type' => 'application/json',
1288 'Accept: application/json',
1289 'source: WORDPRESS',
1290 ],
1291 ];
1292
1293 if (isset($auth_token)) {
1294 $auth = "Bearer " . $auth_token;
1295 $args['headers'] = array_merge($args['headers'], ["Authorization" => $auth]);
1296 }
1297
1298 $response = wp_remote_post($api_url, $args);
1299 $response = wp_remote_retrieve_body($response);
1300 $response = json_decode($response, true);
1301
1302 } else {
1303 $error = 'WP_REMOTE_POST_NOT_EXIST';
1304 }
1305
1306 // Checking if there are errors in the response.
1307 if (isset($response['errors'][0]['message'])) {
1308 // Show error page if WebTotem cabinet's password is expired.
1309 if (stripos($response['errors'][0]['message'], "Password expired") !== FALSE) {
1310 wtotem_error_page(['errors' => 'PASSWORD_EXPIRED']);
1311 exit();
1312 }
1313
1314 if (stripos($response['errors'][0]['message'], "API_KEY_DEACTIVATED") !== FALSE) {
1315 wtotem_error_page(['errors' => 'TARIFF_EXPIRED']);
1316 exit();
1317 }
1318
1319 $message = WebTotem::messageForHuman($response['errors'][0]['message']);
1320 if (stripos($response['errors'][0]['message'], "INVALID_TOKEN") !== FALSE && !$repeat) {
1321 $response = self::auth($api_key);
1322 if ($response === 'success') {
1323 return self::sendRequest($payload, $token, TRUE);
1324 }
1325 } elseif (stripos($response['errors'][0]['message'], "USERHOST_NOT_BELONG_TO_USER") !== FALSE) {
1326 if (WebTotem::isMultiSite()) {
1327 WebTotemOption::clearAllHosts();
1328 WebTotemOption::clearOptions(['host_id', 'host_name']);
1329 } else {
1330 WebTotemOption::clearOptions(['host_id', 'host_name']);
1331 }
1332 } else {
1333 WebTotemOption::setNotification('error', $message);
1334 }
1335 }
1336
1337 if (!empty($error)) {
1338 WebTotemOption::setNotification('error', $error);
1339 }
1340 if($response == null){
1341 self::checkEndpoint();
1342 }
1343
1344 return $response;
1345 }
1346
1347 }
1348