PluginProbe
WebTotem Security / 2.3.14
WebTotem Security v2.3.14
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
← All changes | library/WT.php +482 -451 1.02.3.14 View file →
@@ -1,451 +1,482 @@
1 -<?php defined('ABSPATH') or die("Protected By WT!");
2 -
3 -
4 -class WTSEC_LIBRARY_WT
5 -{
6 - const URL = "https://api.wtotem.com/v1/graphql";
7 -
8 - public static function auth($key)
9 - {
10 - $payload = '{"query":"mutation{\n apiServiceMutation{\n auth(apiKey:\"' . $key . '\"){\n value\n refreshToken\n expiresIn\n }\n }\n}\n\n"}';
11 - return self::requestApi($payload);
12 - }
13 -
14 - protected static function requestApi($payload, $token = false, $repeat = false)
15 - {
16 - if ($token) {
17 - $token = WTSEC_LIBRARY_App::getToken();
18 - }
19 - $args = [
20 - 'body' => $payload,
21 - 'timeout' => '15',
22 - 'sslverify' => false,
23 - 'headers' => ['Content-Type:application/json'],
24 - ];
25 - if (!is_null($token) && $token) {
26 - $authorization = "Bearer " . $token;
27 - $args['headers'] = array_merge($args['headers'], ["Authorization" => $authorization]);
28 - }
29 - $response = wp_remote_post(self::URL, $args);
30 - $httpcode = wp_remote_retrieve_response_code($response);
31 -
32 - if ($httpcode < 200) {
33 - WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server'));
34 - }
35 - $response = wp_remote_retrieve_body($response);
36 -
37 - $result = json_decode($response, true);
38 - if (isset($result['errors'][0]['message'])) {
39 - $message = self::diffMesageForHuman($result['errors'][0]['message']);
40 - if (stripos($result['errors'][0]['message'], "token") !== false && !$repeat) {
41 - $result = WTSEC_LIBRARY_WT::auth(wtsec_app()->get("api_key"));
42 - if (isset($result['data']['apiServiceMutation']['auth']['value'])) {
43 - $token_ = $result['data']['apiServiceMutation']['auth']['value'];
44 - WTSEC_LIBRARY_App::login($token_);
45 - return self::requestApi($payload, $token, true);
46 - } else {
47 - WTSEC_LIBRARY_App::logout();
48 - }
49 - } else {
50 - if ($message !== false) {
51 - WTSEC_LIBRARY_Session::setNotification("warning", $message);
52 - }
53 - }
54 - }
55 - return $result;
56 - }
57 -
58 - public static function diffMesageForHuman($message)
59 - {
60 - $definition = $message;
61 - $excepts = [
62 - "RESOURCE_NOT_FOUND", "DUPLICATE_HOST", "INVALID_CREDENTIALS", "INVALID_API_KEY", "Invalid token",
63 - ];
64 - if (in_array($message, $excepts)) {
65 - return false;
66 - }
67 - switch ($message) {
68 - case 'HOSTS_LIMIT_EXCEEDED':
69 - $definition = WTSEC_LIBRARY_Localization::lmsg('hosts_limit_exceed');
70 - break;
71 - case 'RESOURCE_NOT_FOUND':
72 - $definition = WTSEC_LIBRARY_Localization::lmsg('resource_not_found');
73 - break;
74 - case 'Invalid token':
75 - $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_token');
76 - break;
77 - case 'USER_ALREADY_REGISTERED':
78 - $definition = WTSEC_LIBRARY_Localization::lmsg('user_already_exist');
79 - break;
80 - case 'DUPLICATE_HOST':
81 - $definition = WTSEC_LIBRARY_Localization::lmsg('duplicate_host');
82 - break;
83 - case 'Agent does not exist or has been already verified':
84 - $definition = WTSEC_LIBRARY_Localization::lmsg('agent_does_not_exist_or_has_been_already_verified');
85 - break;
86 - case 'INVALID_DOMAIN_NAME':
87 - $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_domain_name');
88 - break;
89 - }
90 - return $definition;
91 - }
92 -
93 - public static function requestURL($url)
94 - {
95 - $args = [
96 - 'timeout' => '15',
97 - 'sslverify' => false,
98 - ];
99 - $response = wp_remote_post($url, $args);
100 - $httpcode = wp_remote_retrieve_response_code($response);
101 - if ($httpcode < 200) {
102 - WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server'));
103 - }
104 - $response = wp_remote_retrieve_body($response);
105 - return $response;
106 - }
107 -
108 - public static function getOwnSite()
109 - {
110 - $payload = '{"query":"{\n userHostsList{\n id\n hostname\n }\n}"}';
111 - $result = self::requestApi($payload, true);
112 - if (isset($result['data']['userHostsList'])) {
113 - //mutator
114 - foreach ($result['data']['userHostsList'] as &$m) {
115 - if (isset($m['hostname'])) {
116 - $m['hostname'] = WTSEC_LIBRARY_Idn::idn_to_utf8($m['hostname']);
117 - if (self::isSiteUrl($m['hostname'])) {
118 - return $result['data']['userHostsList'] = $m;
119 - break;
120 - }
121 - }
122 - }
123 - $add_site = self::addSite(WTSEC_SITE_URL);
124 - if (isset($add_site['errors'])) {
125 - return $result['data']['userHostsList'] = [];
126 - } else {
127 - return self::getOwnSite();
128 - }
129 - }
130 - return [];
131 - }
132 -
133 - public static function isSiteUrl($url)
134 - {
135 - return WTSEC_LIBRARY_Idn::idn_to_utf8(WTSEC_SITE_URL) === $url;
136 - }
137 -
138 - public static function addSite($url)
139 - {
140 - $payload = '{"query":"\n mutation($input: AddUserHostInput!) {\n addUserHost(input: $input) {\n id\n title\n hostname\n tags\n stack\n services {\n id\n name\n configs {\n id\n data\n isActive\n createdAt\n }\n }\n isActive\n createdAt\n }\n }\n ","variables":{"input":{"hostname":"' . $url . '","services":[{"id":1,"configs":[{"scheme":"http","port":80,"check_interval":1,"responsetime_threshold":30,"path":"/","http_errors":[400,401,402,403,404,500,501,502,503],"alert_after":0}]},{"id":2,"configs":[{"check_interval":5,"notify_expiry_day":true,"notify_expiry_month":true,"notify_expiry_week":true,"port":443}]},{"id":4,"configs":[{"check_interval":5,"path":"/","scheme":"http","port":80}]},{"id":5,"configs":[{"check_interval":5,"path":"/","scheme":"http","port":80}]},{"id":6,"configs":[{"check_interval":5,"path":"/","scheme":"http","port":80}]},{"id":7,"configs":[{"check_interval":5,"ports_udp":[18,19,53,27,29,31,71,74],"ports_tcp":[21,22,25,3306,5432,80,443,88,8000,8080]}]},{"id":9,"configs":[{"scheme":"http","port":80,"path":"/"}]},{"id":8,"configs":[{"check_interval":30,"scheme":"http","port":80,"path":"/"}]},{"id":3,"configs":[{"check_interval":60,"notify_expiry_day":true,"notify_expiry_month":true,"notify_expiry_week":true}]},{"id":10,"configs":[{"check_interval":30,"path":"/","scheme":"http","port":80}]}],"title":"' . $url . '"}}}';
141 - return self::requestApi($payload, true);
142 - }
143 -
144 - public static function getAllChecks($host_id)
145 - {
146 - $from = time() - (60 * 60 * 24);
147 - $to = time();
148 - $from_waf = time() - (60 * 60 * 24 * 7);
149 - $payload = '{"query":"query getAllChecks( $hostId:Int!, $dateRange: DateRangeInput!, $dateRangeWaf:DateRangeInput! ){\n waServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n isDown\n status\n average(dateRange: $dateRange)\n responseTime(dateRange: $dateRange)\n testsResults(dateRange: $dateRange)\n }\n sslServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n status\n issued\n expires\n daysLeft\n tls\n }\n decServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n email\n daysLeft\n created\n expires\n registrar\n owner\n status\n }\n avServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n lastTestId\n lastTestTime\n status\n count\n list\n }\n cmsServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n lastTestId\n lastTestTime\n status\n count\n list\n }\n dcServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n lastTestTime\n status\n count\n list\n }\n psServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n ip\n lastTestId\n lastTestTime\n status\n count\n openTCPs\n openUDPs\n }\n wafServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n lastTestTime\n status\n count\n countIP \n chart(dateRangeWaf:$dateRangeWaf){\n date\n count\n }\n }\n vcServiceChecks(userHostId:$hostId){\n config{\n id\n isActive\n }\n status\n list\n fileChangesCount\n errorsCount\n signaturesCount\n }\n \n}\n\n\n\n","variables":{"hostId":' . $host_id . ',"dateRange":{"from":' . $from . ',"to":' . $to . '},"dateRangeWaf":{"to":' . $to . ',"from":' . $from_waf . '}}}';
150 - return self::requestApi($payload, true);
151 - }
152 -
153 - public static function changeStatus($config_id, $host_id)
154 - {
155 - $payload = '{"query":"\n mutation {\n toggleServiceConfig(\n id: ' . $config_id . '\n userhostId: ' . $host_id . '\n ) {\n isActive\n }\n }\n "}';
156 - return self::requestApi($payload, true);
157 - }
158 -
159 - public static function serviceConnect($id, $service)
160 - {
161 - $payload = '{"query":"{ checkAgent(userHostId: ' . $id . ', service: ' . strtoupper($service) . ') }"}';
162 - return self::requestApi($payload, true);
163 - }
164 -
165 - public static function generateFile($id, $service)
166 - {
167 - $payload = '{"query":"{ generateAgent(userHostId: ' . $id . ', service: ' . strtoupper($service) . ') }"}';
168 - return self::requestApi($payload, true);
169 - }
170 -
171 - public static function checkStatus($id, $service)
172 - {
173 - $payload = '{"query":"{\n ' . strtolower($service) . 'ServiceChecks(userHostId:' . $id . '){\n status\n config{\n isActive\n id\n }\n }\n}"}';
174 - return self::requestApi($payload, true);
175 - }
176 -
177 - public static function getOptions($host_id)
178 - {
179 - $payload = '{"query":"query{\nuserHost(id:' . $host_id . '){\n id\n title\n hostname\n stack\n createdAt\n services {\n id\n name\n configs {\n id\n \tdata\n isActive\n }\n }\n }\n}"}';
180 - return self::requestApi($payload, true);
181 - }
182 -
183 - public static function getAntivirus($host_id)
184 - {
185 - $payload = '{"query":"query{\n vcServiceChecks(userHostId:' . $host_id . '){\n config{\n id,\n isActive\n }\n status\n list\n fileChangesCount\n errorsCount\n signaturesCount\n }\n}\n\n"}';
186 - return self::requestApi($payload, true);
187 - }
188 -
189 - public static function getStatusIcon($status, $service)
190 - {
191 - $color = '';
192 - $definition = '';
193 - switch ($service) {
194 - case 'wa':
195 - switch ((string)$status) {
196 - case '-1':
197 - $color = self::getColor("error");
198 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
199 - break;
200 - case '-200':
201 - $color = self::getColor("grey");
202 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
203 - break;
204 - case '0':
205 - $color = self::getColor("success");
206 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
207 - break;
208 - case '1':
209 - $color = self::getColor("error");
210 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.unavailable');
211 - break;
212 - }
213 - break;
214 - case 'ssl':
215 - switch ((string)$status) {
216 - case '-1':
217 - $color = self::getColor("grey");
218 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
219 - break;
220 - case '-200':
221 - $color = self::getColor("grey");
222 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
223 - break;
224 - case '0':
225 - $color = self::getColor("green");
226 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
227 - break;
228 - case '1':
229 - $color = self::getColor("red");
230 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.invalid');
231 - break;
232 - case '2':
233 - $color = self::getColor("red");
234 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.expired');
235 - break;
236 - case '3':
237 - $color = self::getColor("orange");
238 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.expires');
239 - break;
240 - case '4':
241 - $color = self::getColor("red");
242 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.expires_today');
243 - break;
244 - }
245 - break;
246 - case 'dec':
247 - switch ((string)$status) {
248 - case '-3':
249 - $color = self::getColor("grey");
250 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.not_registered');
251 - break;
252 - case '-2':
253 - $color = self::getColor("grey");
254 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.unsupported');
255 - break;
256 - case '-1':
257 - $color = self::getColor("grey");
258 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
259 - break;
260 - case '-200':
261 - $color = self::getColor("grey");
262 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
263 - break;
264 - case '0':
265 - $color = self::getColor("green");
266 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
267 - break;
268 - case '1':
269 - $color = self::getColor("orange");
270 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.expires');
271 - break;
272 - case '2':
273 - $color = self::getColor("orange");
274 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.expired');
275 - break;
276 - case '3':
277 - $color = self::getColor("red");
278 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.expires_today');
279 - break;
280 - }
281 - break;
282 - case 'av':
283 - switch ((string)$status) {
284 - case '-1':
285 - $color = self::getColor("grey");
286 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
287 - break;
288 - case '-200':
289 - $color = self::getColor("grey");
290 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
291 - break;
292 - case '0':
293 - $color = self::getColor("green");
294 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
295 - break;
296 - case '1':
297 - $color = self::getColor("red");
298 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.blacklisted');
299 - break;
300 - }
301 - break;
302 - case 'cms':
303 - switch ((string)$status) {
304 - case '-1':
305 - $color = self::getColor("grey");
306 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
307 - break;
308 - case '-200':
309 - $color = self::getColor("grey");
310 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
311 - break;
312 - case '0':
313 - $color = self::getColor("green");
314 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
315 - break;
316 - case '1':
317 - $color = self::getColor("red");
318 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.miner_detected');
319 - break;
320 - }
321 - break;
322 - case 'dc':
323 - switch ((string)$status) {
324 - case '-1':
325 - $color = self::getColor("grey");
326 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
327 - break;
328 - case '-200':
329 - $color = self::getColor("grey");
330 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
331 - break;
332 - case '0':
333 - $color = self::getColor("green");
334 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
335 - break;
336 - case '1':
337 - $color = self::getColor("red");
338 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.deface');
339 - break;
340 - case '2':
341 - $color = self::getColor("orange");
342 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.modified');
343 - break;
344 - }
345 - break;
346 - case 'ps':
347 - switch ((string)$status) {
348 - case '-1':
349 - $color = self::getColor("grey");
350 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
351 - break;
352 - case '-200':
353 - $color = self::getColor("grey");
354 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
355 - break;
356 - case '0':
357 - $color = self::getColor("green");
358 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
359 - break;
360 - case '1':
361 - $color = self::getColor("orange");
362 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.open');
363 - break;
364 - }
365 - break;
366 - case 'waf':
367 - switch ((string)$status) {
368 - case '-400':
369 - $color = self::getColor("red");
370 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.blocked');
371 - break;
372 - case '-300':
373 - $color = self::getColor("orange");
374 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.not_installed');
375 - break;
376 - case '-1':
377 - $color = self::getColor("grey");
378 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
379 - break;
380 - case '-200':
381 - $color = self::getColor("grey");
382 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
383 - break;
384 - case '0':
385 - $color = self::getColor("green");
386 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
387 - break;
388 - case '1':
389 - $color = self::getColor("red");
390 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.attacks_detected');
391 - break;
392 - }
393 - break;
394 - case 'vc':
395 - switch ((string)$status) {
396 - case '-400':
397 - $color = self::getColor("red");
398 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.blocked');
399 - break;
400 - case '-300':
401 - $color = self::getColor("orange");
402 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.not_installed');
403 - break;
404 - case '-1':
405 - $color = self::getColor("grey");
406 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.error');
407 - break;
408 - case '-200':
409 - $color = self::getColor("grey");
410 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.pending');
411 - break;
412 - case '0':
413 - $color = self::getColor("green");
414 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.ok');
415 - break;
416 - case '1':
417 - $color = self::getColor("orange");
418 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.file_changes');
419 - break;
420 - case '2':
421 - $color = self::getColor("red");
422 - $definition = WTSEC_LIBRARY_Localization::lmsg('statuses.signature_found');
423 - break;
424 - }
425 - break;
426 - }
427 - return ["icon" => $color["icon"], "color" => $color["color"], "text" => "<span class='" . $color["color"] . "'>" . $definition . "</span>"];
428 - }
429 -
430 - public static function getColor($type)
431 - {
432 - $types = [
433 - "green" => "is--status--ok",
434 - "red" => "is--status--error",
435 - "success" => "is--status--ok",
436 - "error" => "is--status--error",
437 - "orange" => "is--status--warning",
438 - "grey" => "ww--status_unknow"
439 - ];
440 - $icon_types = [
441 - "green" => "ww-icon--status_ok",
442 - "red" => "ww-icon--status_error",
443 - "success" => "ww-icon--status_ok",
444 - "error" => "ww-icon--status_error",
445 - "orange" => "ww-icon--status_warning",
446 - "grey" => "ww-icon--status_unknow"
447 - ];
448 - return ["icon" => $icon_types[$type], "color" => $types[$type]];
449 - }
450 -
451 -}
1 +<?php defined('ABSPATH') or die("Protected By WT!");
2 +
3 +
4 +class WTSEC_LIBRARY_WT
5 +{
6 +
7 + const URL = "https://api.wtotem.com/graphql";
8 +
9 + public static function auth($key)
10 + {
11 + $source = get_site_url();
12 + $payload = '{"query":"mutation{ guest{ apiKeys{ auth(apiKey:\"' . $key . '\", source:\"' . $source . '\"),{ token{ value,refreshToken,expiresIn } } } } }"}';
13 + return self::requestApi($payload);
14 + }
15 +
16 + protected static function requestApi($payload, $token = false, $repeat = false)
17 + {
18 + if ($token) {
19 + $token = WTSEC_LIBRARY_App::getToken();
20 + }
21 +
22 + $token_expired = wtsec_app()->get("token_expired");
23 +
24 + if($token_expired && $token_expired <= time()){
25 + $token_expired = wtsec_app()->get("token_expired");
26 + if($token_expired <= time()){
27 + $result = WTSEC_LIBRARY_WT::auth(wtsec_app()->get("api_key"));
28 + if (isset($result['data']['guest']['apiKeys']['auth']['token']['value'])) {
29 + $expiresIn = $result['data']['guest']['apiKeys']['auth']['token']['expiresIn'];
30 + wtsec_app()->set("token_expired", time() + $expiresIn - 60);
31 +
32 + $token_ = $result['data']['guest']['apiKeys']['auth']['token']['value'];
33 + WTSEC_LIBRARY_App::login($token_);
34 + return self::requestApi($payload, $token, true);
35 + } else {
36 + WTSEC_LIBRARY_App::logout();
37 + }
38 + }
39 + }
40 +
41 + $args = [
42 + 'body' => $payload,
43 + 'timeout' => '60',
44 + 'sslverify' => false,
45 + 'headers' => ['Content-Type:application/json', 'Content-Type' => 'application/json', 'source:WORDPRESS', 'Accept: application/json'],
46 + ];
47 + if (!is_null($token) && $token) {
48 + $authorization = "Bearer " . $token;
49 + $args['headers'] = array_merge($args['headers'], ["Authorization" => $authorization]);
50 + }
51 + $response = wp_remote_post(self::URL, $args);
52 + $httpcode = wp_remote_retrieve_response_code($response);
53 +
54 + if ($httpcode < 200) {
55 + WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server'));
56 + }
57 + $response = wp_remote_retrieve_body($response);
58 + $result = json_decode($response, true);
59 + if (isset($result['errors'][0]['message'])) {
60 + $message = self::diffMesageForHuman($result['errors'][0]['message']);
61 +
62 + if ($message !== false) {
63 + WTSEC_LIBRARY_Session::setNotification("warning", $message);
64 + }
65 + }
66 + return $result;
67 + }
68 +
69 + public static function diffMesageForHuman($message)
70 + {
71 + $definition = $message;
72 + $excepts = [
73 + "RESOURCE_NOT_FOUND", "DUPLICATE_HOST", "INVALID_CREDENTIALS", "INVALID_API_KEY", "Invalid token",
74 + ];
75 + if (in_array($message, $excepts)) {
76 + return false;
77 + }
78 + switch ($message) {
79 + case 'HOSTS_LIMIT_EXCEEDED':
80 + $definition = WTSEC_LIBRARY_Localization::lmsg('hosts_limit_exceed');
81 + break;
82 + case 'Invalid token':
83 + $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_token');
84 + break;
85 + case 'USER_ALREADY_REGISTERED':
86 + $definition = WTSEC_LIBRARY_Localization::lmsg('user_already_exist');
87 + break;
88 + case 'DUPLICATE_HOST':
89 + $definition = WTSEC_LIBRARY_Localization::lmsg('duplicate_host');
90 + break;
91 + case 'INVALID_DOMAIN_NAME':
92 + $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_domain_name');
93 + break;
94 + }
95 + return $definition;
96 + }
97 +
98 + //del
99 + public static function requestURL($url)
100 + {
101 + $args = [
102 + 'timeout' => '30',
103 + 'sslverify' => false,
104 + ];
105 + $response = wp_remote_get($url, $args);
106 + $httpcode = wp_remote_retrieve_response_code($response);
107 + if ($httpcode < 200) {
108 + WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server')." requestURL");
109 + }
110 + $response = wp_remote_retrieve_body($response);
111 + return $response;
112 + }
113 +
114 +
115 + public static function getFileByUrl($url, $fileName)
116 + {
117 + $url = $url.'/'.$fileName;
118 + $args = [
119 + 'timeout' => '30',
120 + 'sslverify' => false,
121 + ];
122 + $response = wp_remote_get($url, $args);
123 + $httpcode = wp_remote_retrieve_response_code($response);
124 + if ($httpcode < 200) {
125 + WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server')." getFileByUrl");
126 + }
127 +
128 + $response = wp_remote_retrieve_body($response);
129 + return ["body" => $response, "filename" => $fileName];
130 + }
131 +
132 +
133 + public static function getEmail(){
134 + $payload = '{"query":"query { auth { viewer { email __typename } __typename } }"}';
135 + $result = self::requestApi($payload, true);
136 +
137 + return $result['data']['auth']['viewer']['email'];
138 + }
139 +
140 + public static function getOwnSite($attempt = false)
141 + {
142 + $payload = '{"query":"query getSites { auth { viewer { sites { ...sites __typename } __typename } __typename }}fragment sites on SiteQueries { list(filter: {}) { edges { node { id hostname title ssl { status __typename } availability { status __typename } reputation { status __typename } ports { status __typename } deface { status __typename } domain { status __typename } antivirus { status __typename } firewall { status __typename } maliciousScript { stack { name __typename } __typename } __typename } __typename } __typename } __typename}"}';
143 +
144 + $result = self::requestApi($payload, true);
145 + if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
146 + //mutator
147 + foreach ($result['data']['auth']['viewer']['sites']['list']['edges'] as &$m) {
148 + if (isset($m['node']['hostname'])) {
149 + $m['node']['hostname'] = WTSEC_LIBRARY_Idn::idn_to_utf8($m['node']['hostname']);
150 +
151 + if (self::isSiteUrl($m['node']['hostname'])) {
152 + return $m['node'];
153 + }
154 + }
155 + }
156 + $add_site = self::addSite(WTSEC_SITE_URL);
157 + if (isset($add_site['errors'])) {
158 + return $result['data']['node'] = [];
159 + } else {
160 + if (!$attempt) {
161 + return self::getOwnSite(true);
162 + }
163 + }
164 + }
165 + return [];
166 + }
167 +
168 + public static function isSiteUrl($url)
169 + {
170 + return WTSEC_LIBRARY_Idn::idn_to_utf8(WTSEC_SITE_URL) === $url;
171 + }
172 +
173 + public static function addSite($url)
174 + {
175 + $payload = '{"variables":{"input":{"title":"' . $url . '","hostname":"' . $url . '","configs":{"scheme":"http","port":80,"wa":{},"dec":{},"ps":{}}}},"query":"mutation ($input: CreateSiteInput) {\n auth {\n sites {\n create(input: $input) {\n id\n hostname\n title\n __typename\n }\n __typename\n }\n __typename\n }\n}\n"}';
176 + return self::requestApi($payload, true);
177 + }
178 +
179 + public static function getAllChecks($host_id)
180 + {
181 + $from = time() - (60 * 60 * 24 * 7);
182 + $to = time();
183 + $from_waf = time() - (60 * 60 * 24 * 30);
184 + $language = WTSEC_LANGUAGE;
185 + $payload = '{"query":"query($id: ID!, $dateRange: DateRangeInput!, $language: Language!, $dateRangeWeek: DateRangeInput!, $wafLogFilter: WafLogFilter!) { auth { viewer { sites { one(id: $id) { ports { status ip tcp 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 scaned infected error } lastTest { time } isFirstCheck } } } } } }","variables":{"id":"' . $host_id . '","dateRange":{"to":' . $to . ',"from":' . $from_waf . '}, "dateRangeWeek":{"to":' . $to . ',"from":' . $from . '}, "wafLogFilter": {"order":{"direction":"DESC","field":"time"},"pagination":{"first":5,"cursor":null}}, "language":"'.$language.'"}}';
186 + $response = self::requestApi($payload, true);
187 + if (isset($response['data']['auth']['viewer']['sites']['one'])) {
188 + return $response['data']['auth']['viewer']['sites']['one'];
189 + }
190 + return [];
191 + }
192 +
193 + public static function getFirewall($host_id, $limit = 20, $cursor = null, $days = 365)
194 + {
195 + $from = (is_array($days)) ? $days['from'] : time() - (60 * 60 * 24 * $days);
196 + $to = (is_array($days)) ? $days['to'] : time();
197 + $cursor = ($cursor == null) ? 'null' : '"'.$cursor.'"';
198 +
199 + $payload = '{"operationName":"FirewallAttackLog","variables":{"dateRange":{"to":'.$to.',"from":'.$from.'},"id":"'.$host_id.'","wafLogFilter":{"dateRange":{"to":'.$to.',"from":'.$from.'},"order":{"direction":"DESC","field":"time"},"pagination":{"first":'.$limit.',"cursor":' . $cursor . '}}},"query":"query FirewallAttackLog($id: ID!, $wafLogFilter: WafLogFilter!, $dateRange: DateRangeInput!) { auth { viewer { sites { one(id: $id) { firewall { lastTest { time } settings{ gdn dosProtection dosLimit loginAttemptsProtection loginAttemptsLimit } status... FirewallLogFragment map(dateRange: $dateRange) { attacks, country } __typename } __typename } __typename } __typename } __typename } } fragment FirewallLogFragment on Waf { logs(wafLogFilter: $wafLogFilter) { edges { cursor node { type blocked payload ip location { country { nameEn __typename } __typename } time request status country category __typename } __typename } pageInfo { endCursor hasNextPage __typename } __typename } __typename }"}';
200 + $res = self::requestApi($payload, true);
201 +
202 + return $res;
203 + }
204 +
205 +
206 + public static function getAntivirus($host_id, $limit = 10, $cursor = null, $days = 365, $event = 'new')
207 + {
208 + $from = (is_array($days)) ? $days['from'] : time() - (60 * 60 * 24 * $days);
209 + $to = (is_array($days)) ? $days['to'] : time();
210 + $cursor = ($cursor == null) ? 'null' : '"' . $cursor . '"';
211 + $payload = '{"operationName":null,"variables":{"id":"' . $host_id . '","avLogFilter":{"event":"'.$event.'","dateRange":{"to":'.$to.',"from":'.$from.'},"order":{"direction":"DESC","field":"time"},"pagination":{"first":' . $limit . ',"cursor":' . $cursor . '}}},"query":"query ($id: ID!, $avLogFilter: AvLogFilter!) { auth { viewer { sites { one(id: $id) { id ... on Site { configs { ... on AvConfig { isActive id } } } antivirus { status log(avLogFilter: $avLogFilter) { edges { node { filePath matches event signatures time permissions permissionsChanged } } pageInfo { endCursor hasNextPage __typename } } lastTest { time } stats { changed deleted scaned infected } } } } } } }"}';
212 + return self::requestApi($payload, true);
213 + }
214 +
215 + public static function getFirewallChart($host_id, $days = 7)
216 + {
217 + $to = time();
218 + $from_waf = ($days <= 1) ? strtotime(date('Y-m-d 00:00:01')) : time() - (60 * 60 * 24 * $days);
219 +
220 + $payload = '{ "query":"query($id: ID!, $dateRange: DateRangeInput!, $wafLogFilter: WafLogFilter!) { auth { viewer { sites { one(id: $id) { firewall { lastTest { time } status logs(wafLogFilter: $wafLogFilter) { edges { node { status country type userAgent } } } chart(dateRange: $dateRange) { time attacks blocked } report(dateRange: $dateRange) { time attacks ip } } } } } } }", "operationName":null,"variables":{"id":"' . $host_id . '","dateRange":{"to":' . $to . ',"from":' . $from_waf . '}, "wafLogFilter": { "dateRange": { "from": ' .$from_waf. ', "to": ' .$to. ' }, "pagination": { "cursor": null }, "order": { "direction": "DESC", "field": "time" } } } }';
221 + $response = self::requestApi($payload, true);
222 + return $response['data']['auth']['viewer']['sites']['one']['firewall']['chart'];
223 + }
224 +
225 + public static function changeStatus($config_id, $host_id)
226 + {
227 + $payload = '{"query":"\n mutation {\n toggleServiceConfig(\n id: ' . $config_id . '\n userhostId: ' . $host_id . '\n ) {\n isActive\n }\n }\n "}';
228 + return self::requestApi($payload, true);
229 + }
230 +
231 + public static function serviceConnect($id, $service)
232 + {
233 + $payload = '{"query":"mutation {\n auth {\n agents{\n check(siteId:\"' . $id . '\",service:' . strtolower($service) . ',plugin:WORDPRESS)\n }\n }\n}\n"}';
234 + return self::requestApi($payload, true);
235 + }
236 +
237 + public static function generateFile($id, $service)
238 + {
239 + $payload = '{"query":"mutation {\n auth {\n agents{\n generate(siteId:\"' . $id . '\",service:' . strtolower($service) . '){\n agentName\n }\n }\n }\n}\n"}';
240 + return self::requestApi($payload, true);
241 + }
242 +
243 + public static function generateAmFile($id)
244 + {
245 + $payload = '{ "operationName":null, "variables":{}, "query":"mutation { auth { am { install(siteId: \"'.$id.'\"){ downloadLink, amFilename, wafFilename, avFilename } } } }"}';
246 + return self::requestApi($payload, true);
247 + }
248 +
249 + public static function deleteAm($id)
250 + {
251 + $payload = '{ "query":"mutation { auth { am { delete(siteId: \"'.$id.'\") } } }"}';
252 + return self::requestApi($payload, true);
253 + }
254 +
255 + public static function checkStatus($id, $service)
256 + {
257 + $payload = '{"operationName":null,"variables":{"id":"' . $id . '"},"query":"query ($id: ID!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n ... on Site {\n configs {\n ... on ' . $service . 'Config {\n isActive\n id\n }\n }\n }\n }\n }\n }\n }\n}\n"}';
258 + return self::requestApi($payload, true);
259 + }
260 +
261 +
262 + public static function getQuarantineList($host_id)
263 + {
264 + $payload = '{"query":"query{ auth{ viewer{ sites{ one(id:\"'.$host_id.'\"){ antivirus{ quarantine{ id path date } } } } } } } "}';
265 + return self::requestApi($payload, true);
266 + }
267 +
268 + public static function moveToQuarantine($host_id, $path)
269 + {
270 + $payload = '{"query":"mutation{ auth{ sites{ av{ moveToQuarantine(input:{ siteId:\"'.$host_id.'\", path:\"'.$path.'\" }) } } } } "}';
271 + return self::requestApi($payload, true);
272 + }
273 +
274 + public static function moveFromQuarantine($id)
275 + {
276 + $payload = '{"query":"mutation{ auth{ sites{ av{ moveFromQuarantine(id: \"'.$id.'\") } } } } "}';
277 + return self::requestApi($payload, true);
278 + }
279 +
280 + public static function reportsList($host_id, $limit = 10, $cursor = null)
281 + {
282 + $cursor = ($cursor == null) ? 'null' : '"' . $cursor . '"';
283 + $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 } } } } } }"}';
284 + return self::requestApi($payload, true);
285 + }
286 +
287 + public static function reportGenerate($host_id, $period, $services, $language = "en")
288 + {
289 + $from = (is_array($period)) ? $period['from'] : time() - (60 * 60 * 24 * $period);
290 + $to = (is_array($period)) ? $period['to'] : time();
291 + $payload = '{"query":"query ($input: GenerateReportInput) { auth { viewer { reports { generate(input: $input) } } } }", "variables":{ "input": { "siteId": "' . $host_id . '", "from": ' . $from . ', "to": ' . $to . ', "wa": '.$services['wa'].', "dc": '.$services['dc'].', "ps": '.$services['ps'].', "rc": '.$services['rc'].', "sc": '.$services['sc'].', "av": '.$services['av'].', "waf": '.$services['waf'].', "language": "'.$language.'" } } }';
292 +
293 + return self::requestApi($payload, true);
294 + }
295 +
296 + public static function reportDownload($id)
297 + {
298 + $payload = '{"query": "query { auth { viewer { reports { download(id: \"' . $id . '\") } } } }"}';
299 + return self::requestApi($payload, true);
300 + }
301 +
302 + public static function getConfigs($host_id)
303 + {
304 + $payload = '{"query":"query{ auth{ viewer{ sites{ one(id:\"'.$host_id.'\"){ configs{ ... on WaConfig { id service isActive } ... on AvConfig { id service isActive } ... on DcConfig { id service isActive } ... on DecConfig { id service isActive } ... on RcConfig { id service isActive } ... on CmsConfig { id service isActive } ... on PsConfig { id service isActive } ... on WafConfig { id service isActive } } } } } } } "}';
305 + return self::requestApi($payload, true);
306 + }
307 +
308 + public static function toggleConfigs($service_id)
309 + {
310 + $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 } } } } } "}';
311 + return self::requestApi($payload, true);
312 + }
313 +
314 + public static function wafSettings($host_id, $settings)
315 + {
316 + $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 } } } } }"}';
317 + return self::requestApi($payload, true);
318 + }
319 +
320 + public static function getServerStatusChart($host_id, $days = 7)
321 + {
322 + $to = time();
323 + $from = ($days <= 1) ? strtotime(date('Y-m-d 00:00:01')) : time() - (60 * 60 * 24 * $days);
324 +
325 + $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":' . $to . ',"from":' . $from . '} } }';
326 +
327 + $response = self::requestApi($payload, true);
328 + return $response['data']['auth']['viewer']['sites']['one']['serverStatus'];
329 + }
330 +
331 + public static function getStatusIcon($status)
332 + {
333 + $statuses = [
334 + "clean" => [
335 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.ok'),
336 + "color" => self::getColor("success"),
337 + "image" => "check-mark.svg"
338 + ],
339 + "pending" => [
340 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.pending'),
341 + "color" => self::getColor("grey"),
342 + "image" => "loading.svg"
343 + ],
344 + "pause" => [
345 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.pause'),
346 + "color" => self::getColor("grey"),
347 + "image" => "warning.svg"
348 + ],
349 + "expired" => [
350 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expired'),
351 + "color" => self::getColor("orange"),
352 + "image" => "warning.svg"
353 +
354 + ],
355 + "invalid" => [
356 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.invalid'),
357 + "color" => self::getColor("error"),
358 + "image" => "warning.svg"
359 + ],
360 + "no_cert" => [
361 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.no_cert'),
362 + "color" => self::getColor("orange"),
363 + "image" => "warning.svg"
364 + ],
365 + "error" => [
366 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.error'),
367 + "color" => self::getColor("error"),
368 + "image" => "warning.svg"
369 + ],
370 + "expires" => [
371 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires'),
372 + "color" => self::getColor("orange"),
373 + "image" => "warning.svg"
374 + ],
375 + "expires_today" => [
376 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires_today'),
377 + "color" => self::getColor("error"),
378 + "image" => "warning.svg"
379 + ],
380 + "down" => [
381 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.down'),
382 + "color" => self::getColor("error"),
383 + "image" => "warning.svg"
384 + ],
385 + "up" => [
386 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.up'),
387 + "color" => self::getColor("success"),
388 + "image" => "check-mark.svg"
389 + ],
390 + "infected" => [
391 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.infected'),
392 + "color" => self::getColor("error"),
393 + "image" => "warning.svg"
394 + ],
395 + "open_ports" => [
396 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.open'),
397 + "color" => self::getColor("orange"),
398 + "image" => "warning.svg"
399 + ],
400 + "deface" => [
401 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.deface'),
402 + "color" => self::getColor("error"),
403 + "image" => "warning.svg"
404 + ],
405 + "modified" => [
406 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.modified'),
407 + "color" => self::getColor("grey"),
408 + "image" => "warning.svg"
409 + ],
410 + "not_supported" => [
411 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.unsupported'),
412 + "color" => self::getColor("orange"),
413 + "image" => "warning.svg"
414 + ],
415 + "not_registered" => [
416 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_registered'),
417 + "color" => self::getColor("orange"),
418 + "image" => "warning.svg"
419 + ],
420 + "not_installed" => [
421 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_installed'),
422 + "color" => self::getColor("error"),
423 + "image" => "warning.svg"
424 + ],
425 + "working" => [
426 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.working'),
427 + "color" => self::getColor("success"),
428 + "image" => "check-mark.svg"
429 + ],
430 + ];
431 + if (isset($statuses[$status])) {
432 + $statuses[$status]['type'] = $status;
433 + $statuses[$status]["text"] = "<span data-status='$status' class='" . $statuses[$status]["color"]["color"] . "'>" . $statuses[$status]["text"] . "</span>";
434 + return $statuses[$status];
435 + } else {
436 + return ["image" => "warning.svg", "color" => "ww--status_unknow", "text" => "<span class='ww--status_unknow'>Unknown status</span>"];
437 + }
438 + }
439 +
440 + public static function getColor($type)
441 + {
442 + $types = [
443 + "green" => "is--status--ok",
444 + "red" => "is--status--error",
445 + "success" => "is--status--ok",
446 + "error" => "is--status--error",
447 + "orange" => "is--status--warning",
448 + "warning" => "is--status--warning",
449 + "grey" => "ww--status_unknow"
450 + ];
451 + $icon_types = [
452 + "green" => "ww-icon--status_ok",
453 + "red" => "ww-icon--status_error",
454 + "success" => "ww-icon--status_ok",
455 + "error" => "ww-icon--status_error",
456 + "orange" => "ww-icon--status_warning",
457 + "warning" => "ww-icon--status_warning",
458 + "grey" => "ww-icon--status_unknow"
459 + ];
460 + return ["icon" => $icon_types[$type], "color" => $types[$type]];
461 + }
462 +
463 + public static function getConfigId($configs)
464 + {
465 + $id = 0;
466 + $is_active = false;
467 + foreach ($configs as &$config) {
468 + if (!empty($config)) {
469 + $id = $config['id'];
470 + $is_active = $config['isActive'];
471 + break;
472 + }
473 + }
474 + return compact('id', 'is_active');
475 + }
476 +
477 + public static function getScore(){
478 + return self::requestURL("https://api.wtotem.com/site/score?url=".WTSEC_SITE_URL);
479 + }
480 +
481 +}
482 +