PluginProbe
WebTotem Security / 2.4.9
WebTotem Security v2.4.9
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.9, at lib/API.php

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