PluginProbe
WebTotem Security / 2.4.10
WebTotem Security v2.4.10
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.10, at lib/API.php

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