PluginProbe
WebTotem Security / 2.4.32
WebTotem Security v2.4.32
3.0.2 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 All 110 releases
wt-security / lib / API.php

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

1,321 lines 49.2 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
165 if ($host['id']) {
166 return $host;
167 }
168 }
169
170 $host = WebTotemOption::getHost();
171
172 if ($host['id']) {
173 return $host;
174 }
175
176 if (self::isMultiSite()) {
177 $sites = get_sites();
178 foreach ($sites as $site) {
179 $domain = untrailingslashit($site->domain . $site->path);
180 self::addSite($domain);
181 }
182
183 if (!$attempt) {
184 return self::siteInfo(TRUE);
185 }
186 } else {
187 $domain = WEBTOTEM_SITE_DOMAIN;
188 return self::addSite($domain);
189 }
190
191
192 return [];
193 }
194
195 /**
196 * Method for adding a site to the WebTotem platform.
197 *
198 * @param string $domain
199 * Domain to add.
200 *
201 * @return array
202 * Returns host data.
203 */
204 public static function addSite($domain)
205 {
206 if (function_exists('idn_to_utf8')) {
207 $domain = idn_to_utf8($domain);
208 }
209
210 $matches = self::checkForMatches($domain);
211
212 // Checking if the site has been added to the WebTotem.
213 if (array_key_exists('edges', $matches)) {
214
215 foreach ($matches['edges'] as $site) {
216 $site = $site['node'];
217 $hostname = untrailingslashit($site['hostname']);
218 // If it added, save site data to DB.
219 if ($hostname == $domain or $hostname == 'www.' . $domain) {
220 WebTotemOption::setHost($site['hostname'], $site['id']);
221 return [
222 'id' => $site['id'],
223 'name' => $site['hostname'],
224 ];
225 }
226 }
227
228 }
229
230 $scheme = is_ssl() ? 'https' : 'http';
231
232 // If the site is not added then try to add.
233 $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 } } } }"}';
234 $add_site = self::sendRequest($payload, TRUE);
235 if (isset($add_site['errors'])) {
236 WebTotemOption::setNotification('error', __('Failed to add the site to the WebTotem platform.', 'wtotem'));
237 } else {
238 if ($host = $add_site['data']['auth']['sites']['create']) {
239 // If it added, save site ID.
240 WebTotemOption::setHost($host['title'], $host['id']);
241 return [
242 'id' => $host['id'],
243 'name' => $host['title'],
244 ];
245 }
246 }
247 return [];
248 }
249
250 /**
251 * Get all sites from API.
252 *
253 * @param string $cursor
254 * Mark for loading data.
255 * @param string $limit
256 * Limit of sites to loading.
257 *
258 * @return array
259 * Returns host data.
260 */
261 public static function getSites($cursor = null, $limit = 15, $filter = false)
262 {
263 $cursor = ($cursor == null) ? 'null' : '\"' . $cursor . '\"';
264 if (!$filter) {
265 $filter = ($limit === 0) ? '' : 'pagination:{ first: ' . $limit . ', cursor: ' . $cursor . ' }';
266 }
267
268 $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 } } } } } }"}';
269 $result = self::sendRequest($payload, true);
270
271 if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
272 return $result['data']['auth']['viewer']['sites']['list'];
273 }
274
275 return [];
276 }
277
278 /**
279 * Check the site's presence in the list on the API side.
280 *
281 * @param string $site
282 * The domain we want to check.
283 *
284 * @return array
285 * Returns host data.
286 */
287 public static function checkForMatches($site)
288 {
289 $payload = '{"query": "query getSites { auth { viewer { sites { list(filter: { search: \"'. $site .'\" }) { edges{ node{ hostname id } } } } } } }" }';
290 $result = self::sendRequest($payload, true);
291
292 if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
293 return $result['data']['auth']['viewer']['sites']['list'];
294 }
295
296 return [];
297 }
298
299
300 /**
301 * Method to get the agents file names and AM file link.
302 *
303 * @param string $host_id
304 * Host id on WebTotem.
305 *
306 * @return array
307 * Returns agents files data.
308 */
309 public static function getAgentsFiles($host_id)
310 {
311
312 if (WebTotem::isMultiSite()) {
313 $all_hosts = WebTotemOption::getOption('all_hosts');
314 $all_hosts = $all_hosts ? json_decode($all_hosts, true) : [];
315
316 $siteIdsArray = $all_hosts ? array_values($all_hosts) : [];
317 $siteIds = $siteIdsArray ? addslashes(WebTotem::convertArrayToString($siteIdsArray)) : '';
318
319 $payload = '{"query":"mutation { auth { am { installMultisite(mainSiteId: \"' . $host_id . '\", siteIds: [' . $siteIds . ']){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
320 $response = self::sendRequest($payload, TRUE);
321
322 if (isset($response['data']['auth']['am']['installMultisite'])) {
323 return $response['data']['auth']['am']['installMultisite'];
324 }
325 } else {
326 $payload = '{"query":"mutation { auth { am { install(siteId: \"' . $host_id . '\"){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
327 $response = self::sendRequest($payload, TRUE);
328 if (isset($response['data']['auth']['am']['install'])) {
329 return $response['data']['auth']['am']['install'];
330 }
331 }
332 return [];
333 }
334
335 /**
336 * Add secondary MultiSite host.
337 *
338 * @param $new_sites
339 * An array with sites to add.
340 *
341 * @return void.
342 */
343 public static function addMultiSiteNewSites($new_sites)
344 {
345 // Host id of the main site in MultiSite network.
346 $main_host = WebTotemOption::getMainHost();
347
348 foreach ($new_sites as $site) {
349 $all_sites = self::getSites(null, 1000000);
350 $host = self::addSite($site, $all_sites);
351 if (key_exists('id', $host)) {
352 $payload = '{"query":"mutation { auth { am { addMultisiteHost(mainSiteId: \"' . $main_host['id'] . '\", siteId: \"' . $host['id'] . '\") } } }"}';
353
354 $result = self::sendRequest($payload, TRUE);
355 if (!$result['errors'][0]['message']) {
356 WebTotemOption::setNotification('info', __('A new website has been added: ', 'wtotem') . $site);
357 }
358 }
359 }
360 }
361
362 /**
363 * Remove secondary MultiSite host.
364 *
365 * @param $host_id
366 * Host id on WebTotem.
367 *
368 * @return bool
369 * Returns result removing host.
370 */
371 public static function removeMultiSiteHost($host_id)
372 {
373 $payload = '{"query":"mutation { auth { am { removeMultisiteHost(siteId: \"' . $host_id . '\") } } }"}';
374 $response = self::sendRequest($payload, TRUE);
375 if (isset($response['data']['auth']['am']['removeSecondaryMultisiteHost'])) {
376 return $response['data']['auth']['am']['removeSecondaryMultisiteHost'];
377 }
378
379 return false;
380 }
381
382 /**
383 * Method to get agents (AM, WAF, AV) statuses.
384 *
385 * @param string $host_id
386 * Host id on WebTotem.
387 *
388 * @return array
389 * Returns agents statuses data.
390 */
391 public static function getAgentsStatusesFromAPI($host_id)
392 {
393 $payload = '{"query":"query ($id: ID!) { auth { viewer { sites { one(id: $id) { agentManager { statuses { am { status } av { status } waf { status } } } } } } } }", "variables":{"id":"' . $host_id . '"}}';
394 $response = self::sendRequest($payload, TRUE);
395
396 if (isset($response['data']['auth']['viewer']['sites']['one']['agentManager']['statuses'])) {
397 return $response['data']['auth']['viewer']['sites']['one']['agentManager']['statuses'];
398 }
399
400 return [];
401 }
402
403 /**
404 * Method to get user time zone.
405 *
406 * @return string|bool
407 * Returns time zone data.
408 */
409 public static function getTimeZone()
410 {
411 $payload = '{"query":"query { auth { viewer{ timezone } } } "}';
412 $response = self::sendRequest($payload, TRUE);
413
414 if (isset($response['data']['auth']['viewer']['timezone'])) {
415 return $response['data']['auth']['viewer']['timezone'];
416 }
417 return FALSE;
418 }
419
420 /**
421 * Method for get all the site security data.
422 *
423 * @param string $host_id
424 * Host id on WebTotem.
425 * @param int|array $days
426 * For what period data is needed.
427 *
428 * @return array
429 * Returns all data.
430 */
431 public static function getAllData($host_id, $days = 7)
432 {
433 $language = WebTotem::getLanguage();
434 $period = WebTotem::getPeriod($days);
435
436 $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 . '"}}';
437 $response = self::sendRequest($payload, TRUE);
438
439 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
440 return $response['data']['auth']['viewer']['sites']['one'];
441 }
442
443 return [];
444 }
445
446
447 /**
448 * Method for get all the site security data.
449 *
450 * @param string $host_id
451 * Host id on WebTotem.
452 *
453 * @return array
454 * Returns all data.
455 */
456 public static function getMonitoring($host_id)
457 {
458
459 $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 . '"}}';
460 $response = self::sendRequest($payload, TRUE);
461
462 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
463 return $response['data']['auth']['viewer']['sites']['one'];
464 }
465
466 return [];
467 }
468
469 /**
470 * Method to get firewall data.
471 *
472 * @param string $host_id
473 * Host id on WebTotem.
474 * @param int $limit
475 * Limit on the number of records.
476 * @param string $cursor
477 * Mark for loading data.
478 * @param int|array $days
479 * For what period data is needed.
480 *
481 * @return array
482 * Returns firewall data.
483 */
484 public static function getFirewall($host_id, $limit = 20, $cursor = NULL, $days = 365)
485 {
486 $period = WebTotem::getPeriod($days);
487 $cursor = ($cursor == NULL) ? 'null' : '"' . $cursor . '"';
488
489 $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 . '}}} }';
490 $response = self::sendRequest($payload, TRUE);
491
492 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
493 return $response['data']['auth']['viewer']['sites']['one'];
494 }
495
496 return [];
497 }
498
499 /**
500 * Method to get firewall chart data.
501 *
502 * @param string $host_id
503 * Host id on WebTotem.
504 * @param int $days
505 * For what period data is needed.
506 *
507 * @return array
508 * Returns firewall chart data.
509 */
510 public static function getFirewallChart($host_id, $days = 7)
511 {
512 $period = WebTotem::getPeriod($days);
513
514 $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'] . '} } }';
515 $response = self::sendRequest($payload, TRUE);
516
517 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
518 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
519 }
520
521 return [];
522 }
523
524 /**
525 * Method to set firewall settings.
526 *
527 * @param string $host_id
528 * Host id on WebTotem.
529 * @param array $settings
530 * User-specified settings.
531 *
532 * @return array
533 * Returns information whether the request was successful.
534 */
535 public static function setFirewallSettings($host_id, array $settings)
536 {
537 $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 } } } } }"}';
538 return self::sendRequest($payload, TRUE);
539 }
540
541 /**
542 * Method to get antivirus data.
543 *
544 * @param array $params
545 * Parameters for filtering data.
546 *
547 * @return array
548 * Returns antivirus data.
549 */
550 public static function getAntivirus(array $params)
551 {
552
553 $cursor = ($params['cursor']) ? '"' . $params['cursor'] . '"' : 'null';
554 $event = ($params['event']) ? '"' . $params['event'] . '"' : '"new"';
555 $permissions = ($params['permissions']) ? ' "permissionsChanged":true, ' : '';
556 $period = WebTotem::getPeriod($params['days']);
557
558 $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 } } } } } } }"}';
559 $response = self::sendRequest($payload, TRUE);
560
561 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus'])) {
562 return $response['data']['auth']['viewer']['sites']['one']['antivirus'];
563 }
564 return [];
565 }
566
567 /**
568 * Method to get antivirus last test.
569 *
570 * @param string $host_id
571 * Host id on WebTotem.
572 *
573 * @return array
574 * Returns antivirus last test data.
575 */
576 public static function getAntivirusLastTest($host_id)
577 {
578
579 $payload = '{"variables":{"id":"' . $host_id . '"},"query":"query ($id: ID!) { auth { viewer { sites { one(id: $id) { antivirus { status lastTest { time } } } } } } }"}';
580 $response = self::sendRequest($payload, TRUE);
581
582 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus'])) {
583 return $response['data']['auth']['viewer']['sites']['one']['antivirus'];
584 }
585 return [];
586 }
587
588 /**
589 * Method to force check services.
590 *
591 * @param string $host_id
592 * Host id on WebTotem.
593 * @param string $service
594 * Service that needs to be checked.
595 *
596 * @return array
597 * Returns information whether the request was successful.
598 */
599 public static function forceCheck($host_id, $service)
600 {
601 $payload = '{"variables":{"id":"' . $host_id . '","service":"' . $service . '"},"query":"mutation ($id: ID!, $service: ForceCheckService!) { auth { sites { forceCheck(siteId: $id, service: $service) } } }"} ';
602 return self::sendRequest($payload, TRUE);
603 }
604
605 /**
606 * Method to export antivirus report.
607 *
608 * @param string $host_id
609 * Host id on WebTotem.
610 * @param int|array $days
611 * For what period data is needed.
612 *
613 * @return array
614 * Returns information whether the request was successful.
615 */
616 public static function avExport($host_id, $days = 30)
617 {
618 $period = WebTotem::getPeriod($days);
619 $payload = '{"variables":{ "input":{"siteId":"' . $host_id . '", "dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '} }},"query":"mutation ($input: AvLogExportInput!) { auth { sites { av { export(input: $input) } } } }"} ';
620 return self::sendRequest($payload, TRUE);
621 }
622
623 /**
624 * Method to get quarantine data.
625 *
626 * @param string $host_id
627 * Host id on WebTotem.
628 *
629 * @return array
630 * Returns quarantine data.
631 */
632 public static function getQuarantineList($host_id)
633 {
634 $payload = '{"query":"query{ auth{ viewer{ sites{ one(id:\"' . $host_id . '\"){ antivirus{ quarantine{ id path date } } } } } } } "}';
635 $response = self::sendRequest($payload, TRUE);
636
637 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus']['quarantine'])) {
638 return $response['data']['auth']['viewer']['sites']['one']['antivirus']['quarantine'];
639 }
640 return [];
641 }
642
643 /**
644 * Method to move file to quarantine.
645 *
646 * @param string $host_id
647 * Host id on WebTotem.
648 * @param string $path
649 * Path to the file.
650 *
651 * @return array
652 * Returns information whether the request was successful.
653 */
654 public static function moveToQuarantine($host_id, $path)
655 {
656 $payload = '{"query":"mutation{ auth{ sites{ av{ moveToQuarantine(input:{ siteId:\"' . $host_id . '\", path:\"' . $path . '\" }) } } } } "}';
657 return self::sendRequest($payload, TRUE);
658 }
659
660 /**
661 * Method to move file from quarantine.
662 *
663 * @param string $id
664 * Id assigned to the file.
665 *
666 * @return array
667 * Returns information whether the request was successful.
668 */
669 public static function moveFromQuarantine($id)
670 {
671 $payload = '{"query":"mutation{ auth{ sites{ av{ moveFromQuarantine(id: \"' . $id . '\") } } } } "}';
672 return self::sendRequest($payload, TRUE);
673 }
674
675 /**
676 * Method to get server status data.
677 *
678 * @param string $host_id
679 * Host id on WebTotem.
680 * @param int|array $days
681 * For what period data is needed.
682 *
683 * @return array
684 * Returns server status data.
685 */
686 public static function getServerStatusData($host_id, $days = 7)
687 {
688 $period = WebTotem::getPeriod($days);
689 $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'] . '} } }';
690
691 $response = self::sendRequest($payload, TRUE);
692
693 if (isset($response['data']['auth']['viewer']['sites']['one']['serverStatus'])) {
694 return $response['data']['auth']['viewer']['sites']['one']['serverStatus'];
695 }
696
697 return [];
698 }
699
700 /**
701 * Method to remove port from ignore list.
702 *
703 * @param string $host_id
704 * Host id on WebTotem.
705 * @param string $port
706 * User specified port.
707 *
708 * @return array
709 * Returns information whether the request was successful.
710 */
711 public static function removeIgnorePort($host_id, $port)
712 {
713 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . $port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { removeIgnorePort(input: $input) } } } }"} ';
714 return self::sendRequest($payload, TRUE);
715 }
716
717 /**
718 * Method to add port to ignore list.
719 *
720 * @param string $host_id
721 * Host id on WebTotem.
722 * @param string $port
723 * User specified port.
724 *
725 * @return array
726 * Returns information whether the request was successful.
727 */
728 public static function addIgnorePort($host_id, $port)
729 {
730 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . (int)$port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { addIgnorePort(input: $input) } } } }"} ';
731 return self::sendRequest($payload, TRUE);
732 }
733
734 /**
735 * Method to get all ports list.
736 *
737 * @param string $host_id
738 * Host id on WebTotem.
739 *
740 * @return array
741 * Returns ports data.
742 */
743 public static function getAllPortsList($host_id)
744 {
745 $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 . '"}}';
746
747 $response = self::sendRequest($payload, TRUE);
748
749 if (isset($response['data']['auth']['viewer']['sites']['one']['ports'])) {
750 return $response['data']['auth']['viewer']['sites']['one']['ports'];
751 }
752
753 return [];
754 }
755
756 /**
757 * Method to get all ports list.
758 *
759 * @param string $host_id
760 * Host id on WebTotem.
761 *
762 * @return array
763 * Returns ports data.
764 */
765 public static function getOpenPaths($host_id)
766 {
767 $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) { openPathSearch { time paths { httpCode severity path } } } } } } } ","variables":{"id":"' . $host_id . '"}}';
768
769 $response = self::sendRequest($payload, TRUE);
770
771 if (isset($response['data']['auth']['viewer']['sites']['one']['openPathSearch'])) {
772 return $response['data']['auth']['viewer']['sites']['one']['openPathSearch'];
773 }
774
775 return [];
776 }
777
778 /**
779 * Method to get all reports.
780 *
781 * @param string $host_id
782 * Host id on WebTotem.
783 * @param int $limit
784 * Limit on the number of records.
785 * @param string $cursor
786 * Mark for loading data.
787 *
788 * @return array
789 * Returns reports data.
790 */
791 public static function getAllReports($host_id, $limit = 10, $cursor = NULL)
792 {
793 $cursor = ($cursor == NULL) ? 'null' : '"' . $cursor . '"';
794 $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 } } } } } }"}';
795 $response = self::sendRequest($payload, TRUE);
796
797 if (isset($response['data']['auth']['viewer']['reports']['list']['edges'])) {
798 return $response['data']['auth']['viewer']['reports']['list'];
799 }
800
801 return [];
802 }
803
804 /**
805 * Method to generate report.
806 *
807 * @param string $host_id
808 * Host id on WebTotem.
809 * @param int|array $days
810 * For what period data is needed.
811 * @param array $services
812 * User-specified module settings.
813 *
814 * @return string|bool
815 * Returns report download link.
816 */
817 public static function generateReport(string $host_id, $days, array $services)
818 {
819 $period = WebTotem::getPeriod($days);
820 $language = WebTotem::getLanguage();
821
822 $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 . '" } } }';
823 $response = self::sendRequest($payload, TRUE);
824
825 if (isset($response['data']['auth']['viewer']['reports']['generate'])) {
826 return $response['data']['auth']['viewer']['reports']['generate'];
827 }
828
829 return FALSE;
830 }
831
832 /**
833 * Method to download report.
834 *
835 * @param string $id
836 * Assigned to the report.
837 *
838 * @return string|bool
839 * Returns report download link.
840 */
841 public static function downloadReport($id)
842 {
843 $payload = '{"query": "query { auth { viewer { reports { download(id: \"' . $id . '\") } } } }"}';
844 $response = self::sendRequest($payload, TRUE);
845
846 if (isset($response['data']['auth']['viewer']['reports']['download'])) {
847 return $response['data']['auth']['viewer']['reports']['download'];
848 }
849
850 return FALSE;
851 }
852
853 /**
854 * Method to get configs data.
855 *
856 * @param string $host_id
857 * Host id on WebTotem.
858 *
859 * @return array|bool
860 * Returns configs data.
861 */
862 public static function getConfigs($host_id)
863 {
864 $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 } } } } } } } "}';
865 $response = self::sendRequest($payload, TRUE);
866
867 if (isset($response['data']['auth']['viewer']['sites']['one']['configs'])) {
868 return $response['data']['auth']['viewer']['sites']['one']['configs'];
869 }
870
871 return FALSE;
872 }
873
874 /**
875 * Method to toggle modules config.
876 *
877 * @param string $service_id
878 * Service id that we enable or disable.
879 *
880 * @return string|bool
881 * Returns information whether the request was successful.
882 */
883 public static function toggleConfigs($service_id)
884 {
885 $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 } } } } } "}';
886 $response = self::sendRequest($payload, TRUE);
887
888 if (isset($response['data']['auth']['configs']['toggle'])) {
889 return $response['data']['auth']['configs']['toggle'];
890 }
891
892 return FALSE;
893 }
894
895 /**
896 * Method to toggle modules notification.
897 *
898 * @param string $host_id
899 * Host id on WebTotem.
900 * @param string $service
901 * Service id in which we enable or disable notifications.
902 *
903 * @return string|bool
904 * Returns information whether the request was successful.
905 */
906 public static function toggleNotifications($host_id, $service)
907 {
908 $payload = '{"query":"mutation{ auth{ sites{ toggleNotifications(siteId: \"' . $host_id . '\", service: ' . $service . ') } } }"}';
909 $response = self::sendRequest($payload, TRUE);
910
911 if (isset($response['data']['auth']['sites']['toggleNotifications'])) {
912 return $response;//['data']['auth']['sites']['toggleNotifications'];
913 }
914
915 return FALSE;
916 }
917
918 /**
919 * Method to get allow/deny ip list.
920 *
921 * @param string $host_id
922 * Host id on WebTotem.
923 *
924 * @return array|bool
925 * Returns ip allow/deny lists.
926 */
927 public static function getIpLists($host_id)
928 {
929 $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 } } } } } } }"} ';
930 $response = self::sendRequest($payload, TRUE);
931
932 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
933 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
934 }
935
936 return [];
937 }
938
939 /**
940 * Method to add ip to allow/deny list.
941 *
942 * @param string $host_id
943 * Host id on WebTotem.
944 * @param string $ips
945 * Ip address list.
946 * @param string $list
947 * Allow or deny list.
948 *
949 * @return bool
950 * Returns information whether the request was successful.
951 */
952 public static function addIpToList($host_id, $ips, $list)
953 {
954
955 if ($ips) {
956 $ips = WebTotem::convertIpListForApi($ips);
957 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "ips": ' . $ips . ', "color": "' . $list . '" } }, "query":"mutation($input: WafListInput!) { auth { sites { waf { addToList(input: $input){ status invalidIPs} } } } }"} ';
958 $response = self::sendRequest($payload, TRUE);
959
960 if (isset($response['data']['auth']['sites']['waf']['addToList'])) {
961 return $response['data']['auth']['sites']['waf']['addToList'];
962 }
963 }
964
965 return FALSE;
966 }
967
968 /**
969 * Method to remove ip from allow/deny list by id.
970 *
971 * @param string $id
972 * Id assignment to ip address.
973 *
974 * @return bool
975 * Returns information whether the request was successful.
976 */
977 public static function removeIpFromList($id)
978 {
979 $payload = '{"variables":{ "id": "' . $id . '" },"query":"mutation($id: ID!) { auth { sites { waf { removeFromList(id: $id) } } } }"} ';
980 $response = self::sendRequest($payload, TRUE);
981
982 if (isset($response['data']['auth']['sites']['waf']['removeFromList'])) {
983 return $response['data']['auth']['sites']['waf']['removeFromList'];
984 }
985
986 return FALSE;
987 }
988
989 /**
990 * Method to get allow url list.
991 *
992 * @param string $host_id
993 * Host id on WebTotem.
994 *
995 * @return array
996 * Returns url allow lists.
997 */
998 public static function getAllowUrlList($host_id)
999 {
1000 $payload = '{"query":"query { auth { viewer { sites { one(id: \"' . $host_id . '\"){ firewall{ urlWhiteList{ id url createdAt } } } } } } }"} ';
1001 $response = self::sendRequest($payload, TRUE);
1002
1003 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'])) {
1004 return $response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'];
1005 }
1006
1007 return [];
1008 }
1009
1010 /**
1011 * Method to add url to allow list.
1012 *
1013 * @param string $host_id
1014 * Host id on WebTotem.
1015 * @param string $url
1016 * User-specified url.
1017 *
1018 * @return bool|string
1019 * Returns information whether the request was successful.
1020 */
1021 public static function addUrlToAllowList($host_id, $url)
1022 {
1023 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "url": "' . $url . '" } }, "query":"mutation($input: WafUrlWhiteListInput!) { auth { sites { waf { addToUrlWhiteList(input: $input) } } } }"} ';
1024 $response = self::sendRequest($payload, TRUE);
1025
1026 if (isset($response['data']['auth']['sites']['waf']['addToUrlWhiteList'])) {
1027 return $response['data']['auth']['sites']['waf']['addToUrlWhiteList'];
1028 }
1029
1030 return FALSE;
1031 }
1032
1033 /**
1034 * Method to remove url from allow list.
1035 *
1036 * @param string $id
1037 * Id assignment to url address.
1038 *
1039 * @return bool|string
1040 * Returns information whether the request was successful.
1041 */
1042 public static function removeUrlFromAllowList($id)
1043 {
1044 $payload = '{"variables":{ "id": "' . $id . '" }, "query":"mutation($id: ID!) { auth { sites { waf { removeFromUrlWhiteList(id: $id) } } } }"} ';
1045 $response = self::sendRequest($payload, TRUE);
1046
1047 if (isset($response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'])) {
1048 return $response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'];
1049 }
1050
1051 return FALSE;
1052 }
1053
1054 /**
1055 * Method to get blocked countries list.
1056 *
1057 * @param string $host_id
1058 * Host id on WebTotem.
1059 *
1060 * @return array
1061 * Returns blocked countries list.
1062 */
1063 public static function getBlockedCountries($host_id)
1064 {
1065 $period = WebTotem::getPeriod(7);
1066 $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 } } } } } } } } }"}';
1067 $response = self::sendRequest($payload, TRUE);
1068
1069 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
1070 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
1071 }
1072
1073 return [];
1074 }
1075
1076 /**
1077 * Method for synchronizing data on the list of blocked countries.
1078 *
1079 * @param string $host_id
1080 * Host id on WebTotem.
1081 * @param array $countries
1082 * Array of countries to block.
1083 *
1084 * @return bool|string
1085 * Returns information whether the request was successful.
1086 */
1087 public static function syncBlockedCountries($host_id, $countries)
1088 {
1089
1090 $countries = $countries ? WebTotem::convertArrayToString($countries) : '';
1091 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "countries": [' . $countries . '] } }, "query":"mutation($input: WafBlockedCountriesInput!) { auth { sites { waf { syncBlockedCountries(input: $input) } } } }"} ';
1092 $response = self::sendRequest($payload, TRUE);
1093
1094 if (isset($response['data']['auth']['sites']['waf']['syncBlockedCountries'])) {
1095 return $response['data']['auth']['sites']['waf']['syncBlockedCountries'];
1096 }
1097
1098 return FALSE;
1099 }
1100
1101 /**
1102 * Method to get user's email.
1103 *
1104 * @return string
1105 * Returns user's email.
1106 */
1107 public static function getEmail()
1108 {
1109 $payload = '{"query":"query { auth { viewer { email } } }"}';
1110 $response = self::sendRequest($payload, true);
1111
1112 return $response['data']['auth']['viewer']['email'];
1113 }
1114
1115 /**
1116 * Method to get user's email.
1117 *
1118 * @param string $plugin_list
1119 * List of plugins and their versions.
1120 *
1121 * @return array
1122 * Returns cve list.
1123 */
1124 public static function getCVE($plugin_list)
1125 {
1126 $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 } } } } }"}';
1127 $response = self::sendRequest($payload, true);
1128
1129 if (isset($response['data']['auth']['viewer']['cve']['searchByTechnologyAndVersion'])) {
1130 return $response['data']['auth']['viewer']['cve']['searchByTechnologyAndVersion'];
1131 }
1132
1133 return [];
1134 }
1135
1136 /**
1137 * Method to get user's feedback.
1138 *
1139 * @return array
1140 */
1141 public static function getFeedback()
1142 {
1143 return self::sendFeedbackRequest("GET");
1144 }
1145
1146 /**
1147 * Method to set user's feedback.
1148 *
1149 * @return array
1150 */
1151 public static function setFeedback($data)
1152 {
1153 return self::sendFeedbackRequest("POST", $data);
1154 }
1155
1156 /**
1157 * Function sends data request to endpoint.
1158 *
1159 * @param array $data
1160 * Data array to be sent to endpoint.
1161 *
1162 * @return array
1163 * Returns response from WebTotem endpoint.
1164 */
1165 protected static function sendFeedbackRequest($method, $data = [])
1166 {
1167 $url = 'https://nps.wtotem.com/user-score';
1168 $email = WebTotem::getUserEmail();
1169
1170 if (!$email) {
1171 return [];
1172 }
1173
1174 if ($method == "GET") {
1175
1176 $args = [
1177 'timeout' => '30',
1178 'sslverify' => FALSE,
1179 ];
1180
1181 $response = wp_remote_get($url . '?email=' . urlencode($email), $args);
1182
1183 } else {
1184 $data['email'] = $email;
1185 $data['platform'] = 'WORDPRESS';
1186 $data = json_encode($data);
1187
1188 $args = [
1189 'body' => $data,
1190 'timeout' => '30',
1191 'sslverify' => FALSE,
1192 'headers' => [
1193 'Content-Type' => 'application/json',
1194 ],
1195 ];
1196
1197 $response = wp_remote_post($url, $args);
1198 }
1199
1200
1201 $http_code = wp_remote_retrieve_response_code($response);
1202
1203 if ($http_code < 200) {
1204 WebTotemOption::setNotification('error', __('Could not connect to feedback endpoint.', 'wtotem'));
1205 return [];
1206 }
1207
1208 $response_body = wp_remote_retrieve_body($response);
1209 return json_decode($response_body, true);
1210 }
1211
1212 /**
1213 * Function sends GraphQL request to API server.
1214 *
1215 * @param string $payload
1216 * Payload to be sent to API server.
1217 * @param bool $token
1218 * Whether a token is needed when sending a request.
1219 * @param bool $repeat
1220 * Required to avoid recursion.
1221 *
1222 * @return array
1223 * Returns response from WebTotem API.
1224 */
1225 protected static function sendRequest($payload, $token = FALSE, $repeat = FALSE)
1226 {
1227 $api_key = WebTotemOption::getOption('api_key');
1228
1229 // Remote URL where the public WebTotem API service is running.
1230 $api_url = WebTotemOption::getOption('api_url');
1231 if (!$api_url) {
1232 $api_url = self::getApiUrl('P');
1233 WebTotemOption::setOptions(['api_url' => $api_url]);
1234 }
1235
1236 // Checking whether a token is needed.
1237 if ($token) {
1238 $auth_token = WebTotemOption::getOption('auth_token');
1239 $auth_token_expired = WebTotemOption::getOption('auth_token_expired');
1240
1241 // Checking whether the token has expired.
1242 if ($auth_token_expired <= time() && !$repeat) {
1243 $result = self::auth($api_key);
1244 if ($result === 'success') {
1245 return self::sendRequest($payload, $token, TRUE);
1246 } else {
1247 if (isset($result['errors'])) {
1248 $message = WebTotem::messageForHuman($result['errors'][0]['message']);
1249 WebTotemOption::setNotification('error', $message);
1250 }
1251 }
1252 }
1253 }
1254
1255 if (function_exists('wp_remote_post')) {
1256
1257 $args = [
1258 'body' => $payload,
1259 'timeout' => '60',
1260 'sslverify' => false,
1261 'headers' => [
1262 'Content-Type:application/json',
1263 'Content-Type' => 'application/json',
1264 'Accept: application/json',
1265 'source: WORDPRESS',
1266 ],
1267 ];
1268
1269 if (isset($auth_token)) {
1270 $auth = "Bearer " . $auth_token;
1271 $args['headers'] = array_merge($args['headers'], ["Authorization" => $auth]);
1272 }
1273
1274 $response = wp_remote_post($api_url, $args);
1275 $response = wp_remote_retrieve_body($response);
1276 $response = json_decode($response, true);
1277
1278 } else {
1279 $error = 'WP_REMOTE_POST_NOT_EXIST';
1280 }
1281
1282 // Checking if there are errors in the response.
1283 if (isset($response['errors'][0]['message'])) {
1284 // Show error page if WebTotem cabinet's password is expired.
1285 if (stripos($response['errors'][0]['message'], "Password expired") !== FALSE) {
1286 wtotem_error_page(['errors' => 'PASSWORD_EXPIRED']);
1287 exit();
1288 }
1289
1290 if (stripos($response['errors'][0]['message'], "API_KEY_DEACTIVATED") !== FALSE) {
1291 wtotem_error_page(['errors' => 'TARIFF_EXPIRED']);
1292 exit();
1293 }
1294
1295 $message = WebTotem::messageForHuman($response['errors'][0]['message']);
1296 if (stripos($response['errors'][0]['message'], "INVALID_TOKEN") !== FALSE && !$repeat) {
1297 $response = self::auth($api_key);
1298 if ($response === 'success') {
1299 return self::sendRequest($payload, $token, TRUE);
1300 }
1301 } elseif (stripos($response['errors'][0]['message'], "USERHOST_NOT_BELONG_TO_USER") !== FALSE) {
1302 if (WebTotem::isMultiSite()) {
1303 WebTotemOption::clearAllHosts();
1304 WebTotemOption::clearOptions(['host_id', 'host_name']);
1305 } else {
1306 WebTotemOption::clearOptions(['host_id', 'host_name']);
1307 }
1308 } else {
1309 WebTotemOption::setNotification('error', $message);
1310 }
1311 }
1312
1313 if (!empty($error)) {
1314 WebTotemOption::setNotification('error', $error);
1315 }
1316
1317 return $response;
1318 }
1319
1320 }
1321