| @@ -2,13 +2,14 @@ | ||
| 2 | 2 | |
| 3 | 3 | |
| 4 | 4 | class WTSEC_LIBRARY_WT |
| 5 | 5 | { |
| 6 | + | |
| 6 | 7 | const URL = "https://api.wtotem.com/graphql"; |
| 7 | 8 | |
| 8 | 9 | public static function auth($key) |
| 9 | 10 | { |
| 10 | - $payload = '{"query":"mutation{\n guest{\n apiKeys{\n auth(apiKey:\"' . $key . '\"),{\n token{\n value,refreshToken,expiresIn\n }\n }\n }\n }\n}"}'; | |
| 11 | + $payload = '{"query":"mutation{ guest{ apiKeys{ auth(apiKey:\"' . $key . '\"),{ token{ value,refreshToken,expiresIn } } } } }"}'; | |
| 11 | 12 | return self::requestApi($payload); |
| 12 | 13 | } |
| 13 | 14 | |
| 14 | 15 | protected static function requestApi($payload, $token = false, $repeat = false) |
| @@ -17,9 +18,9 @@ | ||
| 17 | 18 | $token = WTSEC_LIBRARY_App::getToken(); |
| 18 | 19 | } |
| 19 | 20 | $args = [ |
| 20 | 21 | 'body' => $payload, |
| 21 | - 'timeout' => '30', | |
| 22 | + 'timeout' => '60', | |
| 22 | 23 | 'sslverify' => false, |
| 23 | 24 | 'headers' => ['Content-Type:application/json', 'Content-Type' => 'application/json', 'source:WORDPRESS', 'Accept: application/json'], |
| 24 | 25 | ]; |
| 25 | 26 | if (!is_null($token) && $token) { |
| @@ -92,9 +93,9 @@ | ||
| 92 | 93 | ]; |
| 93 | 94 | $response = wp_remote_get($url, $args); |
| 94 | 95 | $httpcode = wp_remote_retrieve_response_code($response); |
| 95 | 96 | if ($httpcode < 200) { |
| 96 | - WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server')); | |
| 97 | + WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server')." requestURL"); | |
| 97 | 98 | } |
| 98 | 99 | $response = wp_remote_retrieve_body($response); |
| 99 | 100 | return $response; |
| 100 | 101 | } |
| @@ -99,10 +100,11 @@ | ||
| 99 | 100 | return $response; |
| 100 | 101 | } |
| 101 | 102 | |
| 102 | 103 | |
| 103 | - public static function getFileByUrl($url) | |
| 104 | + public static function getFileByUrl($url, $fileName) | |
| 104 | 105 | { |
| 106 | + $url = $url.'/'.$fileName; | |
| 105 | 107 | $args = [ |
| 106 | 108 | 'timeout' => '30', |
| 107 | 109 | 'sslverify' => false, |
| 108 | 110 | ]; |
| @@ -108,19 +110,13 @@ | ||
| 108 | 110 | ]; |
| 109 | 111 | $response = wp_remote_get($url, $args); |
| 110 | 112 | $httpcode = wp_remote_retrieve_response_code($response); |
| 111 | 113 | if ($httpcode < 200) { |
| 112 | - WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server')); | |
| 114 | + WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server')." getFileByUrl"); | |
| 113 | 115 | } |
| 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 | - } | |
| 116 | + | |
| 121 | 117 | $response = wp_remote_retrieve_body($response); |
| 122 | - return ["body" => $response, "filename" => $filename]; | |
| 118 | + return ["body" => $response, "filename" => $fileName]; | |
| 123 | 119 | } |
| 124 | 120 | |
| 125 | 121 | public static function getOwnSite($attempt = false) |
| 126 | 122 | { |
| @@ -166,10 +162,10 @@ | ||
| 166 | 162 | public static function getAllChecks($host_id) |
| 167 | 163 | { |
| 168 | 164 | $from = time() - (60 * 60 * 24); |
| 169 | 165 | $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 . '}}}'; | |
| 166 | + $from_waf = time() - (60 * 60 * 24 * 30); | |
| 167 | + $payload = '{"query":"query($id: ID!, $dateRange: DateRangeInput!) { 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 } status chart(dateRange: $dateRange) { time attacks blocked } report(dateRange: $dateRange) { time attacks ip } } maliciousScript { lastTest { time } status } antivirus { status stats { changed deleted scaned infected error } lastTest { time } isFirstCheck } } } } } }","variables":{"id":"' . $host_id . '","dateRange":{"to":' . $to . ',"from":' . $from_waf . '}}}'; | |
| 172 | 168 | // $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 | 169 | $response = self::requestApi($payload, true); |
| 174 | 170 | if (isset($response['data']['auth']['viewer']['sites']['one'])) { |
| 175 | 171 | return $response['data']['auth']['viewer']['sites']['one']; |
| @@ -196,9 +192,9 @@ | ||
| 196 | 192 | } |
| 197 | 193 | |
| 198 | 194 | public static function generateAmFile($id) |
| 199 | 195 | { |
| 200 | - $payload = '{"operationName":null,"variables":{},"query":"mutation {\n auth {\n am {\n install(siteId: \"'.$id.'\")\n }\n }\n}\n"}'; | |
| 196 | + $payload = '{ "operationName":null, "variables":{}, "query":"mutation { auth { am { install(siteId: \"'.$id.'\"){ downloadLink, amFilename, wafFilename, avFilename } } } }"}'; | |
| 201 | 197 | return self::requestApi($payload, true); |
| 202 | 198 | } |
| 203 | 199 | |
| 204 | 200 | public static function checkStatus($id, $service) |
| @@ -206,36 +202,42 @@ | ||
| 206 | 202 | $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 | 203 | return self::requestApi($payload, true); |
| 208 | 204 | } |
| 209 | 205 | |
| 210 | - public static function getOptions($host_id) | |
| 206 | + public static function getAntivirus($host_id, $limit = 10, $cursor = null, $days = 365, $event = 'infected') | |
| 211 | 207 | { |
| 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}"}'; | |
| 208 | + $from = (is_array($days)) ? $days['begin'] : time() - (60 * 60 * 24 * $days); | |
| 209 | + $to = (is_array($days)) ? $days['end'] : 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 } } pageInfo { endCursor hasNextPage __typename } } lastTest { time } stats { changed deleted scaned infected } } } } } } }"}'; | |
| 213 | 212 | return self::requestApi($payload, true); |
| 214 | 213 | } |
| 215 | 214 | |
| 216 | - public static function getAntivirus($host_id) | |
| 215 | + public static function getOptions($host_id) | |
| 217 | 216 | { |
| 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"}'; | |
| 217 | + $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}"}'; | |
| 219 | 218 | return self::requestApi($payload, true); |
| 220 | 219 | } |
| 221 | 220 | |
| 222 | - | |
| 223 | - public static function getFirewall($host_id) | |
| 221 | + public static function getFirewall($host_id, $limit = 20, $cursor = null, $days = 365) | |
| 224 | 222 | { |
| 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 | - } | |
| 223 | + $from = (is_array($days)) ? $days['begin'] : time() - (60 * 60 * 24 * $days); | |
| 224 | + $to = (is_array($days)) ? $days['end'] : time(); | |
| 225 | + $cursor = ($cursor == null) ? 'null' : '"'.$cursor.'"'; | |
| 230 | 226 | |
| 227 | + $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 } 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 }"}'; | |
| 228 | + $res = self::requestApi($payload, true); | |
| 231 | 229 | |
| 230 | + return $res; | |
| 231 | + } | |
| 232 | 232 | |
| 233 | - public static function getFirewallChart($host_id) | |
| 233 | + public static function getFirewallChart($host_id, $days = 7) | |
| 234 | 234 | { |
| 235 | 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" } } } }'; | |
| 236 | + $from_waf = ($days <= 1) ? strtotime(date('Y-m-d 00:00:01')) : time() - (60 * 60 * 24 * $days); | |
| 237 | + | |
| 238 | + $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" } } } }'; | |
| 239 | + | |
| 238 | 240 | return self::requestApi($payload, true); |
| 239 | 241 | } |
| 240 | 242 | |
| 241 | 243 | public static function getStatusIcon($status) |
| @@ -380,5 +382,6 @@ | ||
| 380 | 382 | public static function getScore(){ |
| 381 | 383 | return self::requestURL("https://api.wtotem.com/site/score?url=".WTSEC_SITE_URL); |
| 382 | 384 | } |
| 383 | 385 | |
| 384 | -} | |
| 386 | +} | |
| 387 | + | |