PluginProbe
WebTotem Security / 2.1
WebTotem Security v2.1
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
← All changes | library/WT.php +321 -383 2.1.72.1 View file →
@@ -1,384 +1,322 @@
1 -<?php defined('ABSPATH') or die("Protected By WT!");
2 -
3 -
4 -class WTSEC_LIBRARY_WT
5 -{
6 - const URL = "https://api.wtotem.com/graphql";
7 -
8 - public static function auth($key)
9 - {
10 - $payload = '{"query":"mutation{\n guest{\n apiKeys{\n auth(apiKey:\"' . $key . '\"),{\n token{\n value,refreshToken,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' => '30',
22 - 'sslverify' => false,
23 - 'headers' => ['Content-Type:application/json', 'Content-Type' => 'application/json', 'source:WORDPRESS', 'Accept: 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 - $result = json_decode($response, true);
37 - if (isset($result['errors'][0]['message'])) {
38 - $message = self::diffMesageForHuman($result['errors'][0]['message']);
39 - if (stripos($result['errors'][0]['message'], "token") !== false && !$repeat) {
40 - $result = WTSEC_LIBRARY_WT::auth(wtsec_app()->get("api_key"));
41 - if (isset($result['data']['guest']['apiKeys']['auth']['token']['value'])) {
42 - $token_ = $result['data']['guest']['apiKeys']['auth']['token']['value'];
43 - WTSEC_LIBRARY_App::login($token_);
44 - return self::requestApi($payload, $token, true);
45 - } else {
46 - WTSEC_LIBRARY_App::logout();
47 - }
48 - } else {
49 - if ($message !== false) {
50 - WTSEC_LIBRARY_Session::setNotification("warning", $message);
51 - }
52 - }
53 - }
54 - return $result;
55 - }
56 -
57 - public static function diffMesageForHuman($message)
58 - {
59 - $definition = $message;
60 - $excepts = [
61 - "RESOURCE_NOT_FOUND", "DUPLICATE_HOST", "INVALID_CREDENTIALS", "INVALID_API_KEY", "Invalid token",
62 - ];
63 - if (in_array($message, $excepts)) {
64 - return false;
65 - }
66 - switch ($message) {
67 - case 'HOSTS_LIMIT_EXCEEDED':
68 - $definition = WTSEC_LIBRARY_Localization::lmsg('hosts_limit_exceed');
69 - break;
70 - case 'Invalid token':
71 - $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_token');
72 - break;
73 - case 'USER_ALREADY_REGISTERED':
74 - $definition = WTSEC_LIBRARY_Localization::lmsg('user_already_exist');
75 - break;
76 - case 'DUPLICATE_HOST':
77 - $definition = WTSEC_LIBRARY_Localization::lmsg('duplicate_host');
78 - break;
79 - case 'INVALID_DOMAIN_NAME':
80 - $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_domain_name');
81 - break;
82 - }
83 - return $definition;
84 - }
85 -
86 - //del
87 - public static function requestURL($url)
88 - {
89 - $args = [
90 - 'timeout' => '30',
91 - 'sslverify' => false,
92 - ];
93 - $response = wp_remote_get($url, $args);
94 - $httpcode = wp_remote_retrieve_response_code($response);
95 - if ($httpcode < 200) {
96 - WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server'));
97 - }
98 - $response = wp_remote_retrieve_body($response);
99 - return $response;
100 - }
101 -
102 -
103 - public static function getFileByUrl($url)
104 - {
105 - $args = [
106 - 'timeout' => '30',
107 - 'sslverify' => false,
108 - ];
109 - $response = wp_remote_get($url, $args);
110 - $httpcode = wp_remote_retrieve_response_code($response);
111 - if ($httpcode < 200) {
112 - WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server'));
113 - }
114 - $filename = null;
115 - $metas = explode(";",$response['headers']["content-disposition"]);
116 - foreach ($metas as $meta){
117 - if(stripos($meta,"filename") !== false){
118 - $filename = trim(str_replace(["filename=","=","\""],"",$meta));
119 - }
120 - }
121 - $response = wp_remote_retrieve_body($response);
122 - return ["body" => $response, "filename" => $filename];
123 - }
124 -
125 - public static function getOwnSite($attempt = false)
126 - {
127 - $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}"}';
128 -
129 - $result = self::requestApi($payload, true);
130 - if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
131 - //mutator
132 - foreach ($result['data']['auth']['viewer']['sites']['list']['edges'] as &$m) {
133 - if (isset($m['node']['hostname'])) {
134 - $m['node']['hostname'] = WTSEC_LIBRARY_Idn::idn_to_utf8($m['node']['hostname']);
135 -// if ($m['node']['id'] == "c2l0ZV8yNTg=") {
136 -// return $m['node'];
137 -// }
138 - if (self::isSiteUrl($m['node']['hostname'])) {
139 - return $m['node'];
140 - }
141 - }
142 - }
143 - $add_site = self::addSite(WTSEC_SITE_URL);
144 - if (isset($add_site['errors'])) {
145 - return $result['data']['node'] = [];
146 - } else {
147 - if (!$attempt) {
148 - return self::getOwnSite(true);
149 - }
150 - }
151 - }
152 - return [];
153 - }
154 -
155 - public static function isSiteUrl($url)
156 - {
157 - return WTSEC_LIBRARY_Idn::idn_to_utf8(WTSEC_SITE_URL) === $url;
158 - }
159 -
160 - public static function addSite($url)
161 - {
162 - $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"}';
163 - return self::requestApi($payload, true);
164 - }
165 -
166 - public static function getAllChecks($host_id)
167 - {
168 - $from = time() - (60 * 60 * 24);
169 - $to = time();
170 - $from_waf = time() - (60 * 60 * 24 * 7);
171 - $payload = '{"query":"query($id: ID!, $dateRange:DateRangeInput!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n ports{\n status\n ip\n tcp\n lastTest{\n time\n }\n }\n availability {\n status\n lastTest {\n time\n }\n responseTime\n downTime(dateRange: $dateRange)\n percent(dateRange: $dateRange)\n }\n deface {\n status\n lastTest {\n time\n }\n words\n count\n }\n domain {\n status\n registrar\n owner\n email\n createdDate\n expiredDate\n }\n ports {\n status\n lastTest {\n time\n }\n ip\n tcp\n country\n }\n ssl {\n status\n daysLeft\n expiryDate\n issueDate\n }\n reputation {\n status\n lastTest {\n time\n }\n virusList {\n viruses\n antiVirus\n }\n }\n firewall {\n lastTest { \n time\n } \n status\n chart(dateRange: $dateRange) {\n time\n attacks\n blocked\n }\n report(dateRange: $dateRange) {\n time\n attacks\n ip\n }\n }\n maliciousScript{\n lastTest{\n time\n }\n status\n }\n antivirus{\n status \n stats { \n changed\n deleted\n scaned\n infected\n error\n } \n lastTest { \n time\n } \n isFirstCheck\n }\n }\n }\n }\n }\n}","variables":{"id":"' . $host_id . '","dateRange":{"to":' . $to . ',"from":' . $from_waf . '}}}';
172 -// $payload = '{"query":"query($id: ID!, $dateRange:DateRangeInput!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n ports{\n status\n ip\n tcp\n lastTest{\n time\n }\n }\n availability {\n status\n lastTest {\n time\n }\n responseTime\n downTime(dateRange: $dateRange)\n percent(dateRange: $dateRange)\n }\n deface {\n status\n lastTest {\n time\n }\n words\n count\n }\n domain {\n status\n registrar\n owner\n email\n createdDate\n expiredDate\n }\n ports {\n status\n lastTest {\n time\n }\n ip\n tcp\n country\n }\n ssl {\n status\n daysLeft\n expiryDate\n issueDate\n }\n reputation {\n status\n lastTest {\n time\n }\n virusList {\n viruses\n antiVirus\n }\n }\n firewall {\n lastTest { \n time\n } \n status\n logs{\n edges\n{\n node{\n status\n country\n type\n}\n}\n}\n chart(dateRange: $dateRange) {\n time\n attacks\n blocked\n }\n report(dateRange: $dateRange) {\n time\n attacks\n ip\n }\n }\n maliciousScript{\n lastTest{\n time\n }\n status\n }\n antivirus{\n status \n stats { \n changed\n deleted\n scaned\n infected\n error\n } \n lastTest { \n time\n } \n isFirstCheck\n }\n }\n }\n }\n }\n}","variables":{"id":"' . $host_id . '","dateRange":{"to":' . $to . ',"from":' . $from_waf . '}}}';
173 - $response = self::requestApi($payload, true);
174 - if (isset($response['data']['auth']['viewer']['sites']['one'])) {
175 - return $response['data']['auth']['viewer']['sites']['one'];
176 - }
177 - return [];
178 - }
179 -
180 - public static function changeStatus($config_id, $host_id)
181 - {
182 - $payload = '{"query":"\n mutation {\n toggleServiceConfig(\n id: ' . $config_id . '\n userhostId: ' . $host_id . '\n ) {\n isActive\n }\n }\n "}';
183 - return self::requestApi($payload, true);
184 - }
185 -
186 - public static function serviceConnect($id, $service)
187 - {
188 - $payload = '{"query":"mutation {\n auth {\n agents{\n check(siteId:\"' . $id . '\",service:' . strtolower($service) . ',plugin:WORDPRESS)\n }\n }\n}\n"}';
189 - return self::requestApi($payload, true);
190 - }
191 -
192 - public static function generateFile($id, $service)
193 - {
194 - $payload = '{"query":"mutation {\n auth {\n agents{\n generate(siteId:\"' . $id . '\",service:' . strtolower($service) . '){\n agentName\n }\n }\n }\n}\n"}';
195 - return self::requestApi($payload, true);
196 - }
197 -
198 - public static function generateAmFile($id)
199 - {
200 - $payload = '{"operationName":null,"variables":{},"query":"mutation {\n auth {\n am {\n install(siteId: \"'.$id.'\")\n }\n }\n}\n"}';
201 - return self::requestApi($payload, true);
202 - }
203 -
204 - public static function checkStatus($id, $service)
205 - {
206 - $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"}';
207 - return self::requestApi($payload, true);
208 - }
209 -
210 - public static function getOptions($host_id)
211 - {
212 - $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}"}';
213 - return self::requestApi($payload, true);
214 - }
215 -
216 - public static function getAntivirus($host_id)
217 - {
218 - $payload = '{"operationName":null,"variables":{"id":"' . $host_id . '","avLogFilter":{"event":"infected","order":{"direction":"DESC","field":"time"},"pagination":{"first":20,"cursor":null}}},"query":"query ($id: ID!, $avLogFilter: AvLogFilter!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n id\n ... on Site {\n configs {\n ... on AvConfig {\n isActive\n id\n }\n }\n }\n antivirus {\n status\n log(avLogFilter: $avLogFilter) {\n edges {\n node {\n filePath\n matches\n event\n signatures\n time\n }\n }\n }\n lastTest {\n time\n }\n stats {\n changed\n deleted\n scaned\n infected\n }\n }\n }\n }\n }\n }\n}\n"}';
219 - return self::requestApi($payload, true);
220 - }
221 -
222 -
223 - public static function getFirewall($host_id)
224 - {
225 - $to = time();
226 - $from_waf = time() - (60 * 60 * 24 * 7);
227 - $payload = '{"operationName":"FirewallAttackLog","variables":{"dateRange":{"to":'.$to.',"from":'.$from_waf.'},"id":"'.$host_id.'","wafLogFilter":{"dateRange":{"to":'.$to.',"from":'.$from_waf.'},"order":{"direction":"DESC","field":"time"},"pagination":{"first":20,"cursor":null}}},"query":"query FirewallAttackLog($id: ID!, $wafLogFilter: WafLogFilter! ,$dateRange: DateRangeInput!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n firewall {\n lastTest{\n time\n }\n status\n ...FirewallLogFragment\n map(dateRange: $dateRange) { attacks, country } __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n}\n\nfragment FirewallLogFragment on Waf {\n logs(wafLogFilter: $wafLogFilter) {\n edges {\n cursor\n node {\n type\n blocked\n payload\n ip\n location {\n country {\n nameEn\n __typename\n }\n __typename\n }\n time\n request\n status\n country\n category\n __typename\n }\n __typename\n }\n pageInfo {\n endCursor\n hasNextPage\n __typename\n }\n __typename\n }\n __typename\n}\n"}';
228 - return self::requestApi($payload, true);
229 - }
230 -
231 -
232 -
233 - public static function getFirewallChart($host_id)
234 - {
235 - $to = time();
236 - $from_waf = time() - (60 * 60 * 24 * 7);
237 - $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": { "first": 20, "cursor": null }, "order": { "direction": "DESC", "field": "time" } } } }';
238 - return self::requestApi($payload, true);
239 - }
240 -
241 - public static function getStatusIcon($status)
242 - {
243 - $statuses = [
244 - "clean" => [
245 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.ok'),
246 - "color" => self::getColor("success"),
247 - "image" => "check-mark.svg"
248 - ],
249 - "pending" => [
250 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.pending'),
251 - "color" => self::getColor("grey"),
252 - "image" => "loading.svg"
253 - ],
254 - "expired" => [
255 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expired'),
256 - "color" => self::getColor("orange"),
257 - "image" => "warning.svg"
258 -
259 - ],
260 - "invalid" => [
261 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.invalid'),
262 - "color" => self::getColor("error"),
263 - "image" => "warning.svg"
264 - ],
265 - "no_cert" => [
266 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.no_cert'),
267 - "color" => self::getColor("orange"),
268 - "image" => "warning.svg"
269 - ],
270 - "error" => [
271 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.error'),
272 - "color" => self::getColor("error"),
273 - "image" => "warning.svg"
274 - ],
275 - "expires" => [
276 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires'),
277 - "color" => self::getColor("orange"),
278 - "image" => "warning.svg"
279 - ],
280 - "expires_today" => [
281 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires_today'),
282 - "color" => self::getColor("error"),
283 - "image" => "warning.svg"
284 - ],
285 - "down" => [
286 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.down'),
287 - "color" => self::getColor("error"),
288 - "image" => "warning.svg"
289 - ],
290 - "up" => [
291 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.up'),
292 - "color" => self::getColor("success"),
293 - "image" => "check-mark.svg"
294 - ],
295 - "infected" => [
296 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.infected'),
297 - "color" => self::getColor("error"),
298 - "image" => "warning.svg"
299 - ],
300 - "open_ports" => [
301 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.open'),
302 - "color" => self::getColor("orange"),
303 - "image" => "warning.svg"
304 - ],
305 - "deface" => [
306 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.deface'),
307 - "color" => self::getColor("error"),
308 - "image" => "warning.svg"
309 - ],
310 - "modified" => [
311 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.modified'),
312 - "color" => self::getColor("grey"),
313 - "image" => "warning.svg"
314 - ],
315 - "not_supported" => [
316 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.unsupported'),
317 - "color" => self::getColor("orange"),
318 - "image" => "warning.svg"
319 - ],
320 - "not_registered" => [
321 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_registered'),
322 - "color" => self::getColor("orange"),
323 - "image" => "warning.svg"
324 - ],
325 - "not_installed" => [
326 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_installed'),
327 - "color" => self::getColor("error"),
328 - "image" => "warning.svg"
329 - ],
330 - "working" => [
331 - "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.working'),
332 - "color" => self::getColor("success"),
333 - "image" => "check-mark.svg"
334 - ],
335 - ];
336 - if (isset($statuses[$status])) {
337 - return ["image" => $statuses[$status]["image"], "icon" => $statuses[$status]["color"]["icon"], "color" => $statuses[$status]["color"]["color"], "text" => "<span class='" . $statuses[$status]["color"]["color"] . "'>" . $statuses[$status]["text"] . "</span>"];
338 - } else {
339 - return ["image" => "warning.svg", "icon" => "ww-icon--status_unknow", "color" => "ww--status_unknow", "text" => "<span class='ww--status_unknow'>Unknown status</span>"];
340 - }
341 - }
342 -
343 - public static function getColor($type)
344 - {
345 - $types = [
346 - "green" => "is--status--ok",
347 - "red" => "is--status--error",
348 - "success" => "is--status--ok",
349 - "error" => "is--status--error",
350 - "orange" => "is--status--warning",
351 - "warning" => "is--status--warning",
352 - "grey" => "ww--status_unknow"
353 - ];
354 - $icon_types = [
355 - "green" => "ww-icon--status_ok",
356 - "red" => "ww-icon--status_error",
357 - "success" => "ww-icon--status_ok",
358 - "error" => "ww-icon--status_error",
359 - "orange" => "ww-icon--status_warning",
360 - "warning" => "ww-icon--status_warning",
361 - "grey" => "ww-icon--status_unknow"
362 - ];
363 - return ["icon" => $icon_types[$type], "color" => $types[$type]];
364 - }
365 -
366 - public static function getConfigId($configs)
367 - {
368 - $id = 0;
369 - $is_active = false;
370 - foreach ($configs as &$config) {
371 - if (!empty($config)) {
372 - $id = $config['id'];
373 - $is_active = $config['isActive'];
374 - break;
375 - }
376 - }
377 - return compact('id', 'is_active');
378 - }
379 -
380 - public static function getScore(){
381 - return self::requestURL("https://api.wtotem.com/site/score?url=".WTSEC_SITE_URL);
382 - }
383 -
1 +<?php defined('ABSPATH') or die("Protected By WT!");
2 +
3 +
4 +class WTSEC_LIBRARY_WT
5 +{
6 + const URL = "https://api.wtotem.com/graphql";
7 +
8 + public static function auth($key)
9 + {
10 + $payload = '{"query":"mutation{\n guest{\n apiKeys{\n auth(apiKey:\"' . $key . '\"),{\n token{\n value,refreshToken,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', 'Content-Type' => 'application/json', 'source:WORDPRESS', 'Accept: 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']['guest']['apiKeys']['auth']['token']['value'])) {
43 + $token_ = $result['data']['guest']['apiKeys']['auth']['token']['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_get($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($attempt = false)
109 + {
110 + $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}"}';
111 +
112 + $result = self::requestApi($payload, true);
113 + if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
114 + //mutator
115 + foreach ($result['data']['auth']['viewer']['sites']['list']['edges'] as &$m) {
116 + if (isset($m['node']['hostname'])) {
117 + $m['node']['hostname'] = WTSEC_LIBRARY_Idn::idn_to_utf8($m['node']['hostname']);
118 +// if ($m['node']['id'] == "c2l0ZV8yNTg=") {
119 +// return $m['node'];
120 +// }
121 + if (self::isSiteUrl($m['node']['hostname'])) {
122 + return $m['node'];
123 + }
124 + }
125 + }
126 + $add_site = self::addSite(WTSEC_SITE_URL);
127 + if (isset($add_site['errors'])) {
128 + return $result['data']['node'] = [];
129 + } else {
130 + if (!$attempt) {
131 + return self::getOwnSite(true);
132 + }
133 + }
134 + }
135 + return [];
136 + }
137 +
138 + public static function isSiteUrl($url)
139 + {
140 + return WTSEC_LIBRARY_Idn::idn_to_utf8(WTSEC_SITE_URL) === $url;
141 + }
142 +
143 + public static function addSite($url)
144 + {
145 + $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"}';
146 + return self::requestApi($payload, true);
147 + }
148 +
149 + public static function getAllChecks($host_id)
150 + {
151 + $from = time() - (60 * 60 * 24);
152 + $to = time();
153 + $from_waf = time() - (60 * 60 * 24 * 7);
154 + $payload = '{"query":"query($id: ID!, $dateRange:DateRangeInput!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n availability {\n status\n lastTest {\n time\n }\n responseTime\n downTime(dateRange: $dateRange)\n percent(dateRange: $dateRange)\n }\n deface {\n status\n lastTest {\n time\n }\n words\n count\n }\n domain {\n status\n registrar\n owner\n email\n createdDate\n expiredDate\n }\n ports {\n status\n lastTest {\n time\n }\n ip\n tcp\n country\n }\n ssl {\n status\n daysLeft\n expiryDate\n issueDate\n }\n reputation {\n status\n lastTest {\n time\n }\n virusList {\n viruses\n antiVirus\n }\n }\n firewall {\n lastTest { \n time\n } \n status\n chart(dateRange: $dateRange) {\n time\n attacks\n blocked\n }\n report(dateRange: $dateRange) {\n time\n attacks\n ip\n }\n }\n maliciousScript{\n lastTest{\n time\n }\n status\n }\n antivirus{\n status \n stats { \n changed\n deleted\n scaned\n infected\n error\n } \n lastTest { \n time\n } \n isFirstCheck\n }\n }\n }\n }\n }\n}","variables":{"id":"' . $host_id . '","dateRange":{"to":' . $to . ',"from":' . $from_waf . '}}}';
155 + $response = self::requestApi($payload, true);
156 + if (isset($response['data']['auth']['viewer']['sites']['one'])) {
157 + return $response['data']['auth']['viewer']['sites']['one'];
158 + }
159 + return [];
160 + }
161 +
162 + public static function changeStatus($config_id, $host_id)
163 + {
164 + $payload = '{"query":"\n mutation {\n toggleServiceConfig(\n id: ' . $config_id . '\n userhostId: ' . $host_id . '\n ) {\n isActive\n }\n }\n "}';
165 + return self::requestApi($payload, true);
166 + }
167 +
168 + public static function serviceConnect($id, $service)
169 + {
170 + $payload = '{"query":"mutation {\n auth {\n agents{\n check(siteId:\"' . $id . '\",service:' . strtolower($service) . ',plugin:WORDPRESS)\n }\n }\n}\n"}';
171 + return self::requestApi($payload, true);
172 + }
173 +
174 + public static function generateFile($id, $service)
175 + {
176 + $payload = '{"query":"mutation {\n auth {\n agents{\n generate(siteId:\"' . $id . '\",service:' . strtolower($service) . '){\n agentName\n }\n }\n }\n}\n"}';
177 + return self::requestApi($payload, true);
178 + }
179 +
180 + public static function checkStatus($id, $service)
181 + {
182 + $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"}';
183 + return self::requestApi($payload, true);
184 + }
185 +
186 + public static function getOptions($host_id)
187 + {
188 + $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}"}';
189 + return self::requestApi($payload, true);
190 + }
191 +
192 + public static function getAntivirus($host_id)
193 + {
194 + $from = time() - (60 * 60 * 24);
195 + $to = time();
196 + $from_waf = time() - (60 * 60 * 24 * 7);
197 + $payload = '{"operationName":null,"variables":{"id":"' . $host_id . '","avLogFilter":{"event":"infected","order":{"direction":"DESC","field":"time"},"pagination":{"first":10,"cursor":null},"dateRange":{"to":' . $to . ',"from":' . $from_waf . '}}},"query":"query ($id: ID!, $avLogFilter: AvLogFilter!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n id\n ... on Site {\n configs {\n ... on AvConfig {\n isActive\n id\n }\n }\n }\n antivirus {\n status\n log(avLogFilter: $avLogFilter) {\n edges {\n node {\n filePath\n matches\n event\n signatures\n time\n }\n }\n }\n lastTest {\n time\n }\n stats {\n changed\n deleted\n scaned\n infected\n }\n }\n }\n }\n }\n }\n}\n"}';
198 + return self::requestApi($payload, true);
199 + }
200 +
201 + public static function getStatusIcon($status)
202 + {
203 + $statuses = [
204 + "clean" => [
205 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.ok'),
206 + "color" => self::getColor("success")
207 + ],
208 + "pending" => [
209 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.pending'),
210 + "color" => self::getColor("grey")
211 + ],
212 + "expired" => [
213 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expired'),
214 + "color" => self::getColor("orange")
215 +
216 + ],
217 + "invalid" => [
218 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.invalid'),
219 + "color" => self::getColor("error")
220 + ],
221 + "no_cert" => [
222 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.no_cert'),
223 + "color" => self::getColor("orange")
224 + ],
225 + "error" => [
226 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.error'),
227 + "color" => self::getColor("error")
228 + ],
229 + "expires" => [
230 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires'),
231 + "color" => self::getColor("orange")
232 + ],
233 + "expires_today" => [
234 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires_today'),
235 + "color" => self::getColor("error")
236 + ],
237 + "down" => [
238 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.down'),
239 + "color" => self::getColor("error")
240 + ],
241 + "up" => [
242 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.up'),
243 + "color" => self::getColor("success")
244 + ],
245 + "infected" => [
246 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.infected'),
247 + "color" => self::getColor("error")
248 + ],
249 + "open_ports" => [
250 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.open'),
251 + "color" => self::getColor("orange")
252 + ],
253 + "deface" => [
254 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.deface'),
255 + "color" => self::getColor("error")
256 + ],
257 + "modified" => [
258 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.modified'),
259 + "color" => self::getColor("grey")
260 + ],
261 + "not_supported" => [
262 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.unsupported'),
263 + "color" => self::getColor("orange")
264 + ],
265 + "not_registered" => [
266 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_registered'),
267 + "color" => self::getColor("orange")
268 + ],
269 + "not_installed" => [
270 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_installed'),
271 + "color" => self::getColor("error")
272 + ],
273 + "working" => [
274 + "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.working'),
275 + "color" => self::getColor("success")
276 + ],
277 + ];
278 + if (isset($statuses[$status])) {
279 + return ["icon" => $statuses[$status]["color"]["icon"], "color" => $statuses[$status]["color"]["color"], "text" => "<span class='" . $statuses[$status]["color"]["color"] . "'>" . $statuses[$status]["text"] . "</span>"];
280 + } else {
281 + return ["icon" => "ww-icon--status_unknow", "color" => "ww--status_unknow", "text" => "<span class='ww--status_unknow'>Unknown status</span>"];
282 + }
283 + }
284 +
285 + public static function getColor($type)
286 + {
287 + $types = [
288 + "green" => "is--status--ok",
289 + "red" => "is--status--error",
290 + "success" => "is--status--ok",
291 + "error" => "is--status--error",
292 + "orange" => "is--status--warning",
293 + "warning" => "is--status--warning",
294 + "grey" => "ww--status_unknow"
295 + ];
296 + $icon_types = [
297 + "green" => "ww-icon--status_ok",
298 + "red" => "ww-icon--status_error",
299 + "success" => "ww-icon--status_ok",
300 + "error" => "ww-icon--status_error",
301 + "orange" => "ww-icon--status_warning",
302 + "warning" => "ww-icon--status_warning",
303 + "grey" => "ww-icon--status_unknow"
304 + ];
305 + return ["icon" => $icon_types[$type], "color" => $types[$type]];
306 + }
307 +
308 + public static function getConfigId($configs)
309 + {
310 + $id = 0;
311 + $is_active = false;
312 + foreach ($configs as &$config) {
313 + if (!empty($config)) {
314 + $id = $config['id'];
315 + $is_active = $config['isActive'];
316 + break;
317 + }
318 + }
319 + return compact('id', 'is_active');
320 + }
321 +
384 322 }