PluginProbe
WebTotem Security / 2.4.6
WebTotem Security v2.4.6
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.6, at lib/API.php

936 lines 34.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 * Method for getting a auth token.
23 *
24 * @param string $api_key
25 * Application programming interface key.
26 *
27 * @return bool|string
28 * Returns auth status
29 */
30 public static function auth($api_key) {
31 $domain = WEBTOTEM_SITE_DOMAIN;
32
33 $payload = '{"query":"mutation{ guest{ apiKeys{ auth(apiKey:\"' . $api_key . '\", source:\"' . $domain . '\"),{ token{ value, refreshToken, expiresIn } } } } }"}';
34 $result = self::sendRequest($payload, FALSE, TRUE);
35
36 if (isset($result['data']['guest']['apiKeys']['auth']['token']['value'])) {
37 $auth_token = $result['data']['guest']['apiKeys']['auth']['token'];
38 WebTotemOption::login(['token' => $auth_token, 'api_key' => $api_key]);
39 return 'success';
40 } elseif($result['errors'][0]['message'] == 'INVALID_API_KEY') {
41 WebTotemOption::logout();
42 }
43
44 return FALSE;
45 }
46
47
48 /**
49 * Get site info from API server.
50 *
51 * @param string $attempt
52 * Is the request an attempt to get host data.
53 *
54 * @return array
55 * Returns host data.
56 */
57 public static function siteInfo($attempt = FALSE) {
58
59 if(self::isMultiSite()){
60 $host['id'] = WebTotemOption::getSessionOption('host_id');
61
62 if ($host['id']) {
63 return $host;
64 }
65 }
66
67 $host = WebTotemOption::getHost();
68
69 if ($host['id']) {
70 return $host;
71 }
72
73 $all_sites = self::getSites(null, 0);
74 if(self::isMultiSite()) {
75 $sites = get_sites();
76 foreach ($sites as $site){
77 $domain = untrailingslashit($site->domain . $site->path);
78 self::addSite($domain, $all_sites);
79 }
80
81 if (!$attempt) {
82 return self::siteInfo(TRUE);
83 }
84 }
85 else {
86 $domain = WEBTOTEM_SITE_DOMAIN;
87 return self::addSite($domain, $all_sites);
88 }
89
90 return [];
91 }
92
93 /**
94 * Method for adding a site to the WebTotem platform.
95 *
96 * @param string $domain
97 * Domain to add.
98 * @param array $all_sites
99 * Array with site data on the WebTotem platform.
100 *
101 * @return array
102 * Returns host data.
103 */
104 public static function addSite( $domain, $all_sites) {
105
106 if(function_exists('idn_to_utf8')){
107 $domain = idn_to_utf8($domain);
108 }
109
110 // Checking if the site has been added to the WebTotem.
111 if(array_key_exists('edges', $all_sites)){
112
113 foreach ($all_sites['edges'] as $site){
114 $site = $site['node'];
115 // If it added, save site data to DB.
116 if($site['hostname'] == $domain or 'www.' . $site['hostname'] == $domain){
117 WebTotemOption::setHost($site['hostname'], $site['id']);
118 return [
119 'id' => $site['id'],
120 'name' => $site['hostname'],
121 ];
122 }
123 }
124
125 }
126
127 // If the site is not added then try to add.
128 $payload = '{"variables":{"input":{"title":"' . $domain . '","hostname":"' . $domain . '","configs":{"scheme":"http","port":80,"wa":{},"dec":{},"ps":{}}}},"query":"mutation ($input: CreateSiteInput) { auth { sites { create(input: $input) { id hostname title } } } }"}';
129 $add_site = self::sendRequest($payload, TRUE);
130 if (isset($add_site['errors'])) {
131 WebTotemOption::setNotification('error', __('Failed to add the site to the WebTotem platform.', 'wtotem'));
132 }
133 else {
134 if($host = $add_site['data']['auth']['sites']['create']) {
135 // If it added, save site ID.
136 WebTotemOption::setHost($host['title'], $host['id']);
137 return [
138 'id' => $host['id'],
139 'name' => $host['title'],
140 ];
141 }
142 }
143 return [];
144 }
145
146 /**
147 * Get all sites from API.
148 *
149 * @param string $cursor
150 * Mark for loading data.
151 * @param string $limit
152 * Limit of sites to loading.
153 *
154 * @return array
155 * Returns host data.
156 */
157 public static function getSites($cursor = null, $limit = 15, $filter = false) {
158 $cursor = ($cursor == null) ? 'null' : '\"' . $cursor . '\"';
159 if(!$filter) {
160 $filter = ($limit === 0) ? '' : 'pagination:{ first: ' . $limit . ', cursor: ' . $cursor . ' }';
161 }
162
163 $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 } domain { status } antivirus { status } firewall { status } maliciousScript { stack { name } } } } } }"}';
164 $result = self::sendRequest($payload, true);
165
166 if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
167 return $result['data']['auth']['viewer']['sites']['list'];
168 }
169
170 return [];
171 }
172
173 /**
174 * Method to get the agents file names and AM file link.
175 *
176 * @param string $host_id
177 * Host id on WebTotem.
178 *
179 * @return array
180 * Returns agents files data.
181 */
182 public static function getAgentsFiles($host_id) {
183
184 if(WebTotem::isMultiSite()){
185 $all_hosts = WebTotemOption::getOption('all_hosts');
186 $siteIdsArray = array_values($all_hosts);
187 $siteIds = addslashes(WebTotem::convertArrayToString($siteIdsArray));
188
189 $payload = '{"query":"mutation { auth { am { installMultisite(mainSiteId: \"' . $host_id . '\", siteIds: [' . $siteIds . ']){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
190 $response = self::sendRequest($payload, TRUE);
191 return $response['data']['auth']['am']['installMultisite'];
192 }
193 else {
194 $payload = '{"query":"mutation { auth { am { install(siteId: \"' . $host_id . '\"){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
195 $response = self::sendRequest($payload, TRUE);
196 return $response['data']['auth']['am']['install'];
197 }
198 }
199
200 /**
201 * Add secondary MultiSite host.
202 *
203 * @param $main_host_id
204 * Host id of the main site in MultiSite network.
205 * @param $new_sites
206 * An array with sites to add.
207 *
208 * @return void.
209 */
210 public static function addMultiSiteNewSites($new_sites){
211 $main_host = WebTotemOption::getMainHost();
212 foreach ($new_sites as $site){
213 $all_sites = self::getSites(null, 0);
214 $host = self::addSite($site, $all_sites);
215 if(key_exists('id', $host)){
216 $payload = '{"query":"mutation { auth { am { addMultisiteHost(mainSiteId: \"' . $main_host['id'] . '\", siteId: \"' . $host['id'] . '\") } } }"}';
217 self::sendRequest($payload, TRUE);
218 }
219 }
220 }
221
222 /**
223 * Remove secondary MultiSite host.
224 *
225 * @param $host_id
226 * Host id on WebTotem.
227 *
228 * @return bool
229 * Returns result removing host.
230 */
231 public static function removeMultiSiteHost($host_id){
232 $payload = '{"query":"mutation { auth { am { removeMultisiteHost(siteId: \"' . $host_id . '\") } } }"}';
233 $response = self::sendRequest($payload, TRUE);
234 return $response['data']['auth']['am']['removeSecondaryMultisiteHost'];
235 }
236
237 /**
238 * Method to get agents (AM, WAF, AV) statuses.
239 *
240 * @param string $host_id
241 * Host id on WebTotem.
242 *
243 * @return array
244 * Returns agents statuses data.
245 */
246 public static function getAgentsStatusesFromAPI($host_id) {
247 $payload = '{"query":"query ($id: ID!) { auth { viewer { sites { one(id: $id) { agentManager { statuses { am { status } av { status } waf { status } } } } } } } }", "variables":{"id":"' . $host_id . '"}}';
248 $response = self::sendRequest($payload, TRUE);
249
250 if (isset($response['data']['auth']['viewer']['sites']['one']['agentManager']['statuses'])) {
251 return $response['data']['auth']['viewer']['sites']['one']['agentManager']['statuses'];
252 }
253
254 return [];
255 }
256
257 /**
258 * Method to get user time zone.
259 *
260 * @return string|bool
261 * Returns time zone data.
262 */
263 public static function getTimeZone() {
264 $payload = '{"query":"query { auth { viewer{ timezone } } } "}';
265 $response = self::sendRequest($payload, TRUE);
266
267 if (isset($response['data']['auth']['viewer']['timezone'])) {
268 return $response['data']['auth']['viewer']['timezone'];
269 }
270 return FALSE;
271 }
272
273 /**
274 * Method for get all the site security data.
275 *
276 * @param string $host_id
277 * Host id on WebTotem.
278 * @param int|array $days
279 * For what period data is needed.
280 *
281 * @return array
282 * Returns all data.
283 */
284 public static function getAllData($host_id, $days = 7) {
285 $language = WebTotem::getLanguage();
286 $period = WebTotem::getPeriod($days);
287
288 $payload = '{"query":"query($id: ID!, $dateRange: DateRangeInput!, $language: Language!, $dateRangeWeek: DateRangeInput!, $wafLogFilter: WafLogFilter!) { auth { viewer { sites { one(id: $id) { ports { status ip tcp ignorePorts lastTest { time } } availability { status lastTest { time } responseTime downTime(dateRange: $dateRange) percent(dateRange: $dateRange) } deface { status lastTest { time } words count } domain { status registrar owner email createdDate expiredDate } ports { status lastTest { time } ip tcp country } 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 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 . '"}}';
289 $response = self::sendRequest($payload, TRUE);
290
291 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
292 return $response['data']['auth']['viewer']['sites']['one'];
293 }
294
295 return [];
296 }
297
298 /**
299 * Method to get firewall data.
300 *
301 * @param string $host_id
302 * Host id on WebTotem.
303 * @param int $limit
304 * Limit on the number of records.
305 * @param string $cursor
306 * Mark for loading data.
307 * @param int|array $days
308 * For what period data is needed.
309 *
310 * @return array
311 * Returns firewall data.
312 */
313 public static function getFirewall($host_id, $limit = 20, $cursor = NULL, $days = 365) {
314 $period = WebTotem::getPeriod($days);
315 $cursor = ($cursor == NULL) ? 'null' : '"' . $cursor . '"';
316
317 $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 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 . '}}} }';
318 $response = self::sendRequest($payload, TRUE);
319
320 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
321 return $response['data']['auth']['viewer']['sites']['one'];
322 }
323
324 return [];
325 }
326
327 /**
328 * Method to get firewall chart data.
329 *
330 * @param string $host_id
331 * Host id on WebTotem.
332 * @param int $days
333 * For what period data is needed.
334 *
335 * @return array
336 * Returns firewall chart data.
337 */
338 public static function getFirewallChart($host_id, $days = 7) {
339 $period = WebTotem::getPeriod($days);
340
341 $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'] . '} } }';
342 $response = self::sendRequest($payload, TRUE);
343
344 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
345 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
346 }
347
348 return [];
349 }
350
351 /**
352 * Method to set firewall settings.
353 *
354 * @param string $host_id
355 * Host id on WebTotem.
356 * @param array $settings
357 * User-specified settings.
358 *
359 * @return array
360 * Returns information whether the request was successful.
361 */
362 public static function setFirewallSettings($host_id, array $settings) {
363 $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 } } } } }"}';
364 return self::sendRequest($payload, TRUE);
365 }
366
367 /**
368 * Method to get antivirus data.
369 *
370 * @param array $params
371 * Parameters for filtering data.
372 *
373 * @return array
374 * Returns antivirus data.
375 */
376 public static function getAntivirus(array $params) {
377 $cursor = ($params['cursor']) ? '"' . $params['cursor'] . '"' : 'null';
378 $event = ($params['event']) ? '"' . $params['event'] . '"' : '"new"';
379 $permissions = ($params['permissions']) ? ' "permissionsChanged":true, ' : '';
380 $period = WebTotem::getPeriod($params['days']);
381
382 $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 __typename } } lastTest { time } stats { changed deleted scanned infected } } } } } } }"}';
383 $response = self::sendRequest($payload, TRUE);
384
385 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus'])) {
386 return $response['data']['auth']['viewer']['sites']['one']['antivirus'];
387 }
388 return [];
389 }
390
391 /**
392 * Method to get antivirus last test.
393 *
394 * @param string $host_id
395 * Host id on WebTotem.
396 *
397 * @return array
398 * Returns antivirus last test data.
399 */
400 public static function getAntivirusLastTest($host_id) {
401
402 $payload = '{"variables":{"id":"' . $host_id . '"},"query":"query ($id: ID!) { auth { viewer { sites { one(id: $id) { antivirus { status lastTest { time } } } } } } }"}';
403 $response = self::sendRequest($payload, TRUE);
404
405 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus'])) {
406 return $response['data']['auth']['viewer']['sites']['one']['antivirus'];
407 }
408 return [];
409 }
410
411 /**
412 * Method to force check services.
413 *
414 * @param string $host_id
415 * Host id on WebTotem.
416 * @param string $service
417 * Service that needs to be checked.
418 *
419 * @return array
420 * Returns information whether the request was successful.
421 */
422 public static function forceCheck($host_id, $service) {
423 $payload = '{"variables":{"id":"' . $host_id . '","service":"' . $service . '"},"query":"mutation ($id: ID!, $service: ForceCheckService!) { auth { sites { forceCheck(siteId: $id, service: $service) } } }"} ';
424 return self::sendRequest($payload, TRUE);
425 }
426
427 /**
428 * Method to export antivirus report.
429 *
430 * @param string $host_id
431 * Host id on WebTotem.
432 * @param int|array $days
433 * For what period data is needed.
434 *
435 * @return array
436 * Returns information whether the request was successful.
437 */
438 public static function avExport($host_id, $days = 30) {
439 $period = WebTotem::getPeriod($days);
440 $payload = '{"variables":{ "input":{"siteId":"' . $host_id . '", "dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '} }},"query":"mutation ($input: AvLogExportInput!) { auth { sites { av { export(input: $input) } } } }"} ';
441 return self::sendRequest($payload, TRUE);
442 }
443
444 /**
445 * Method to get quarantine data.
446 *
447 * @param string $host_id
448 * Host id on WebTotem.
449 *
450 * @return array
451 * Returns quarantine data.
452 */
453 public static function getQuarantineList($host_id) {
454 $payload = '{"query":"query{ auth{ viewer{ sites{ one(id:\"' . $host_id . '\"){ antivirus{ quarantine{ id path date } } } } } } } "}';
455 $response = self::sendRequest($payload, TRUE);
456
457 if (isset($response['data']['auth']['viewer']['sites']['one']['antivirus']['quarantine'])) {
458 return $response['data']['auth']['viewer']['sites']['one']['antivirus']['quarantine'];
459 }
460 return [];
461 }
462
463 /**
464 * Method to move file to quarantine.
465 *
466 * @param string $host_id
467 * Host id on WebTotem.
468 * @param string $path
469 * Path to the file.
470 *
471 * @return array
472 * Returns information whether the request was successful.
473 */
474 public static function moveToQuarantine($host_id, $path) {
475 $payload = '{"query":"mutation{ auth{ sites{ av{ moveToQuarantine(input:{ siteId:\"' . $host_id . '\", path:\"' . $path . '\" }) } } } } "}';
476 return self::sendRequest($payload, TRUE);
477 }
478
479 /**
480 * Method to move file from quarantine.
481 *
482 * @param string $id
483 * Id assigned to the file.
484 *
485 * @return array
486 * Returns information whether the request was successful.
487 */
488 public static function moveFromQuarantine($id) {
489 $payload = '{"query":"mutation{ auth{ sites{ av{ moveFromQuarantine(id: \"' . $id . '\") } } } } "}';
490 return self::sendRequest($payload, TRUE);
491 }
492
493 /**
494 * Method to get server status data.
495 *
496 * @param string $host_id
497 * Host id on WebTotem.
498 * @param int|array $days
499 * For what period data is needed.
500 *
501 * @return array
502 * Returns server status data.
503 */
504 public static function getServerStatusData($host_id, $days = 7) {
505 $period = WebTotem::getPeriod($days);
506 $payload = '{ "query":"query($id: ID!, $dateRange: DateRangeInput!) { auth { viewer { sites { one(id: $id) { serverStatus { ramChart(dateRange: $dateRange){ total value time } cpuChart(dateRange: $dateRange){ value time } } } } } } }", "variables":{"id":"' . $host_id . '","dateRange":{"to":' . $period['to'] . ',"from":' . $period['from'] . '} } }';
507
508 $response = self::sendRequest($payload, TRUE);
509
510 if (isset($response['data']['auth']['viewer']['sites']['one']['serverStatus'])) {
511 return $response['data']['auth']['viewer']['sites']['one']['serverStatus'];
512 }
513
514 return [];
515 }
516
517 /**
518 * Method to remove port from ignore list.
519 *
520 * @param string $host_id
521 * Host id on WebTotem.
522 * @param string $port
523 * User specified port.
524 *
525 * @return array
526 * Returns information whether the request was successful.
527 */
528 public static function removeIgnorePort($host_id, $port) {
529 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . $port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { removeIgnorePort(input: $input) } } } }"} ';
530 return self::sendRequest($payload, TRUE);
531 }
532
533 /**
534 * Method to add port to ignore list.
535 *
536 * @param string $host_id
537 * Host id on WebTotem.
538 * @param string $port
539 * User specified port.
540 *
541 * @return array
542 * Returns information whether the request was successful.
543 */
544 public static function addIgnorePort($host_id, $port) {
545 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "port":' . (int) $port . '} },"query":"mutation($input: IgnorePortInput!) { auth { sites { ps { addIgnorePort(input: $input) } } } }"} ';
546 return self::sendRequest($payload, TRUE);
547 }
548
549 /**
550 * Method to get all ports list.
551 *
552 * @param string $host_id
553 * Host id on WebTotem.
554 *
555 * @return array
556 * Returns ports data.
557 */
558 public static function getAllPortsList($host_id) {
559 $payload = '{"query":"query($id: ID!) { auth { viewer { sites { one(id: $id) { ports { status ip tcp ignorePorts lastTest { time } } } } } } } ","variables":{"id":"' . $host_id . '"}}';
560
561 $response = self::sendRequest($payload, TRUE);
562
563 if (isset($response['data']['auth']['viewer']['sites']['one']['ports'])) {
564 return $response['data']['auth']['viewer']['sites']['one']['ports'];
565 }
566
567 return [];
568 }
569
570 /**
571 * Method to get all reports.
572 *
573 * @param string $host_id
574 * Host id on WebTotem.
575 * @param int $limit
576 * Limit on the number of records.
577 * @param string $cursor
578 * Mark for loading data.
579 *
580 * @return array
581 * Returns reports data.
582 */
583 public static function getAllReports($host_id, $limit = 10, $cursor = NULL) {
584 $cursor = ($cursor == NULL) ? 'null' : '"' . $cursor . '"';
585 $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 } } } } } }"}';
586 $response = self::sendRequest($payload, TRUE);
587
588 if (isset($response['data']['auth']['viewer']['reports']['list']['edges'])) {
589 return $response['data']['auth']['viewer']['reports']['list'];
590 }
591
592 return [];
593 }
594
595 /**
596 * Method to generate report.
597 *
598 * @param string $host_id
599 * Host id on WebTotem.
600 * @param int|array $days
601 * For what period data is needed.
602 * @param array $services
603 * User-specified module settings.
604 *
605 * @return string|bool
606 * Returns report download link.
607 */
608 public static function generateReport($host_id, $days, array $services) {
609 $period = WebTotem::getPeriod($days);
610 $language = WebTotem::getLanguage();
611
612 $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 . '" } } }';
613 $response = self::sendRequest($payload, TRUE);
614
615 if (isset($response['data']['auth']['viewer']['reports']['generate'])) {
616 return $response['data']['auth']['viewer']['reports']['generate'];
617 }
618
619 return FALSE;
620 }
621
622 /**
623 * Method to download report.
624 *
625 * @param string $id
626 * Assigned to the report.
627 *
628 * @return string|bool
629 * Returns report download link.
630 */
631 public static function downloadReport($id) {
632 $payload = '{"query": "query { auth { viewer { reports { download(id: \"' . $id . '\") } } } }"}';
633 $response = self::sendRequest($payload, TRUE);
634
635 if (isset($response['data']['auth']['viewer']['reports']['download'])) {
636 return $response['data']['auth']['viewer']['reports']['download'];
637 }
638
639 return FALSE;
640 }
641
642 /**
643 * Method to get configs data.
644 *
645 * @param string $host_id
646 * Host id on WebTotem.
647 *
648 * @return array|bool
649 * Returns configs data.
650 */
651 public static function getConfigs($host_id) {
652 $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 } } } } } } } "}';
653 $response = self::sendRequest($payload, TRUE);
654
655 if (isset($response['data']['auth']['viewer']['sites']['one']['configs'])) {
656 return $response['data']['auth']['viewer']['sites']['one']['configs'];
657 }
658
659 return FALSE;
660 }
661
662 /**
663 * Method to toggle modules config.
664 *
665 * @param string $service_id
666 * Service id that we enable or disable.
667 *
668 * @return string|bool
669 * Returns information whether the request was successful.
670 */
671 public static function toggleConfigs($service_id) {
672 $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 } } } } } "}';
673 $response = self::sendRequest($payload, TRUE);
674
675 if (isset($response['data']['auth']['configs']['toggle'])) {
676 return $response['data']['auth']['configs']['toggle'];
677 }
678
679 return FALSE;
680 }
681
682 /**
683 * Method to toggle modules notification.
684 *
685 * @param string $host_id
686 * Host id on WebTotem.
687 * @param string $service
688 * Service id in which we enable or disable notifications.
689 *
690 * @return string|bool
691 * Returns information whether the request was successful.
692 */
693 public static function toggleNotifications($host_id, $service) {
694 $payload = '{"query":"mutation{ auth{ sites{ toggleNotifications(siteId: \"' . $host_id . '\", service: ' . $service . ') } } }"}';
695 $response = self::sendRequest($payload, TRUE);
696
697 if (isset($response['data']['auth']['sites']['toggleNotifications'])) {
698 return $response;//['data']['auth']['sites']['toggleNotifications'];
699 }
700
701 return FALSE;
702 }
703
704 /**
705 * Method to get allow/deny ip list.
706 *
707 * @param string $host_id
708 * Host id on WebTotem.
709 *
710 * @return array|bool
711 * Returns ip allow/deny lists.
712 */
713 public static function getIpLists($host_id) {
714 $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 } } } } } } }"} ';
715 $response = self::sendRequest($payload, TRUE);
716
717 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall'])) {
718 return $response['data']['auth']['viewer']['sites']['one']['firewall'];
719 }
720
721 return [];
722 }
723
724 /**
725 * Method to add ip to allow/deny list.
726 *
727 * @param string $host_id
728 * Host id on WebTotem.
729 * @param string $ips
730 * Ip address list.
731 * @param string $list
732 * Allow or deny list.
733 *
734 * @return bool
735 * Returns information whether the request was successful.
736 */
737 public static function addIpToList($host_id, $ips, $list) {
738
739 if ($ips) {
740 $ips = WebTotem::convertIpListForApi($ips);
741 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "ips": ' . $ips . ', "color": "' . $list . '" } }, "query":"mutation($input: WafListInput!) { auth { sites { waf { addToList(input: $input){ status invalidIPs} } } } }"} ';
742 $response = self::sendRequest($payload, TRUE);
743
744 if (isset($response['data']['auth']['sites']['waf']['addToList'])) {
745 return $response['data']['auth']['sites']['waf']['addToList'];
746 }
747 }
748
749 return FALSE;
750 }
751
752 /**
753 * Method to remove ip from allow/deny list by id.
754 *
755 * @param string $id
756 * Id assignment to ip address.
757 *
758 * @return bool
759 * Returns information whether the request was successful.
760 */
761 public static function removeIpFromList($id) {
762 $payload = '{"variables":{ "id": "' . $id . '" },"query":"mutation($id: ID!) { auth { sites { waf { removeFromList(id: $id) } } } }"} ';
763 $response = self::sendRequest($payload, TRUE);
764
765 if (isset($response['data']['auth']['sites']['waf']['removeFromList'])) {
766 return $response['data']['auth']['sites']['waf']['removeFromList'];
767 }
768
769 return FALSE;
770 }
771
772 /**
773 * Method to get allow url list.
774 *
775 * @param string $host_id
776 * Host id on WebTotem.
777 *
778 * @return array
779 * Returns url allow lists.
780 */
781 public static function getAllowUrlList($host_id) {
782 $payload = '{"query":"query { auth { viewer { sites { one(id: \"' . $host_id . '\"){ firewall{ urlWhiteList{ id url createdAt } } } } } } }"} ';
783 $response = self::sendRequest($payload, TRUE);
784
785 if (isset($response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'])) {
786 return $response['data']['auth']['viewer']['sites']['one']['firewall']['urlWhiteList'];
787 }
788
789 return [];
790 }
791
792 /**
793 * Method to add url to allow list.
794 *
795 * @param string $host_id
796 * Host id on WebTotem.
797 * @param string $url
798 * User-specified url.
799 *
800 * @return bool|string
801 * Returns information whether the request was successful.
802 */
803 public static function addUrlToAllowList($host_id, $url) {
804 $payload = '{"variables":{ "input": { "siteId": "' . $host_id . '", "url": "' . $url . '" } }, "query":"mutation($input: WafUrlWhiteListInput!) { auth { sites { waf { addToUrlWhiteList(input: $input) } } } }"} ';
805 $response = self::sendRequest($payload, TRUE);
806
807 if (isset($response['data']['auth']['sites']['waf']['addToUrlWhiteList'])) {
808 return $response['data']['auth']['sites']['waf']['addToUrlWhiteList'];
809 }
810
811 return FALSE;
812 }
813
814 /**
815 * Method to remove url from allow list.
816 *
817 * @param string $id
818 * Id assignment to url address.
819 *
820 * @return bool|string
821 * Returns information whether the request was successful.
822 */
823 public static function removeUrlFromAllowList($id) {
824 $payload = '{"variables":{ "id": "' . $id . '" }, "query":"mutation($id: ID!) { auth { sites { waf { removeFromUrlWhiteList(id: $id) } } } }"} ';
825 $response = self::sendRequest($payload, TRUE);
826
827 if (isset($response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'])) {
828 return $response['data']['auth']['sites']['waf']['removeFromUrlWhiteList'];
829 }
830
831 return FALSE;
832 }
833
834 /**
835 * Method to get user's email.
836 *
837 * @return string
838 * Returns user's email.
839 */
840 public static function getEmail(){
841 $payload = '{"query":"query { auth { viewer { email __typename } __typename } }"}';
842 $response = self::sendRequest($payload, true);
843
844 return $response['data']['auth']['viewer']['email'];
845 }
846
847 /**
848 * Function sends GraphQL request to API server.
849 *
850 * @param string $payload
851 * Payload to be sent to API server.
852 * @param bool $token
853 * Whether a token is needed when sending a request.
854 * @param bool $repeat
855 * Required to avoid recursion.
856 *
857 * @return array
858 * Returns response from WebTotem API.
859 */
860 protected static function sendRequest($payload, $token = FALSE, $repeat = FALSE) {
861
862 $api_key = WebTotemOption::getOption('api_key');
863
864 // Checking whether a token is needed.
865 if ($token) {
866 $auth_token = WebTotemOption::getOption('auth_token');
867 $auth_token_expired = WebTotemOption::getOption('auth_token_expired');
868
869 // Checking whether the token has expired.
870 if ($auth_token_expired <= time() && !$repeat) {
871 $result = self::auth($api_key);
872 if ($result === 'success') {
873 return self::sendRequest($payload, $token, TRUE);
874 }
875 else {
876 if(isset($result['errors'])){
877 $message = WebTotem::messageForHuman($result['errors'][0]['message']);
878 WebTotemOption::setNotification('error', $message);
879 }
880 }
881 }
882 }
883
884 if (function_exists('wp_remote_post')) {
885
886 $args = [
887 'body' => $payload,
888 'timeout' => '60',
889 'sslverify' => false,
890 'headers' => [
891 'Content-Type:application/json',
892 'Content-Type' => 'application/json',
893 'Accept: application/json',
894 'source: WORDPRESS',
895 ],
896 ];
897
898 if (isset($auth_token)) {
899 $auth = "Bearer " . $auth_token;
900 $args['headers'] = array_merge($args['headers'], ["Authorization" => $auth]);
901 }
902
903 $response = wp_remote_post(WEBTOTEM_API_URL, $args);
904 $response = wp_remote_retrieve_body($response);
905 $response = json_decode($response, true);
906
907 }
908 else {
909 $error = 'WP_REMOTE_POST_NOT_EXIST';
910 }
911
912 // Checking if there are errors in the response.
913 if (isset($response['errors'][0]['message'])) {
914 $message = WebTotem::messageForHuman($response['errors'][0]['message']);
915 if (stripos($response['errors'][0]['message'], "INVALID_TOKEN") !== FALSE && !$repeat) {
916 $response = self::auth($api_key);
917 if ($response === 'success') {
918 return self::sendRequest($payload, $token, TRUE);
919 }
920 }
921 else {
922 if ($message !== FALSE) {
923 WebTotemOption::setNotification('error', $message); // for debug json_encode($payload).' '.
924 }
925 }
926 }
927
928 if (!empty($error)) {
929 WebTotemOption::setNotification('error', $error);
930 }
931
932 return $response;
933 }
934
935 }
936