user = $user; $this->pass = $pass; $this->server = $server; if ($this->secret) { $this->secret = $secret; $this->set2Fa(); } } /** * Include the ot class so we can generate a valid token for 2FA */ protected function set2Fa() { require 'otphp/lib/otphp.php'; $totp = new \OTPHP\TOTP($this->secret); $this->token = $totp->now(); } public function __get($name) { switch (strtolower($name)) { case 'get': $this->httpMethod = 'GET'; break; case 'post': $this->httpMethod = 'POST'; break; case 'api2': $this->setApi('api2'); break; case 'uapi': $this->setApi('uapi'); break; default: $this->scope = $name; } return $this; } /** * Set the api to use for connections. * @param $api * @return $this * @throws Exception */ protected function setApi($api) { $this->api = $api; $this->setMethod(); return $this; } /** * Function to set the method used to communicate with the chosen api. * @return $this * @throws Exception */ protected function setMethod() { switch ($this->api) { case 'uapi': $this->method = '/execute/'; break; case 'api2': $this->method = '/json-api/cpanel/'; break; default: throw new Exception('$this->api is not set or is incorrectly set. The only available options are \'uapi\' or \'api2\''); } return $this; } /** * Magic __toSting() method, allows us to return the result as raw json * @return mixed */ public function __toString() { return $this->json; } /** * Magic __call method, will translate all function calls to object to API requests * @param $name - name of the function * @param $arguments - an array of arguments * @return mixed * @throws Exception */ public function __call($name, $arguments) { if (count($arguments) < 1 || !is_array($arguments[0])) $arguments[0] = []; $this->json = $this->APIcall($name, $arguments[0]); return json_decode($this->json); } /** * @param $name * @param $arguments * @return bool|mixed * @throws Exception */ protected function APIcall($name, $arguments) { $this->auth = base64_encode($this->user . ":" . $this->pass); $this->type = $this->ssl == 1 ? "https://" : "http://"; $this->requestUrl = $this->type . $this->server . ':' . $this->port . $this->method; switch ($this->api) { case 'uapi': $this->requestUrl .= ($this->scope != '' ? $this->scope . "/" : '') . $name . '?'; break; case 'api2': if ($this->scope == '') { throw new Exception('Scope must be set.'); } $this->requestUrl .= '?cpanel_jsonapi_user=' . $this->user . '&cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=' . $this->scope . '&cpanel_jsonapi_func=' . $name . '&'; break; default: throw new Exception('$this->api is not set or is incorrectly set. The only available options are \'uapi\' or \'api2\''); } if($this->httpMethod == 'GET') { $this->requestUrl .= http_build_query($arguments); } if($this->httpMethod == 'POST'){ $this->postData = $arguments; } return $this->curl_request($this->requestUrl); } /** * @param $url * @return bool|mixed */ protected function curl_request($url) { $httpHeaders = array("Authorization: Basic " . $this->auth); //If we have a token then send that with the request for 2FA. if ($this->token) { $httpHeaders[] = "X-CPANEL-OTP: " . $this->token; } $ch = curl_init(); if($this->httpMethod == 'POST'){ $httpHeaders[] = "Content-type: multipart/form-data"; curl_setopt($ch,CURLOPT_POSTFIELDS, $this->postData); } curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeaders); curl_setopt($ch, CURLOPT_TIMEOUT, 100020); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); $content = $this->curl_exec_follow($ch, $this->maxredirect); $this->eno = curl_errno($ch); $this->emes = curl_error($ch); curl_close($ch); return $content; } /** * @param $ch * @param null $maxredirect * @return bool|mixed */ protected function curl_exec_follow($ch, &$maxredirect = null) { // we emulate a browser here since some websites detect // us as a bot and don't let us do our job $user_agent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5)" . " Gecko/20041107 Firefox/1.0"; curl_setopt($ch, CURLOPT_USERAGENT, $user_agent); $mr = $maxredirect === null ? 5 : intval($maxredirect); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0); curl_setopt($ch, CURLOPT_MAXREDIRS, $mr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); return curl_exec($ch); } /** * Function to get the last request made * @return mixed */ public function getLastRequest() { return $this->requestUrl; } /** * Function to return the error if there was one, or FALSE if not. * @return array|bool */ public function getError() { if (!empty($this->eno)) { return ['no' => $this->eno, 'message' => $this->emes]; } return FALSE; } }