lib/Controller/AuthorApiController.php
b7854c4e
 <?php
 /**
  * @copyright 2021 Double Bastion LLC <www.doublebastion.com>
  *
  * @author Double Bastion LLC
  *
  * @license GNU AGPL version 3 or any later version
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  * License as published by the Free Software Foundation; either
  * version 3 of the License, or any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  *
  * You should have received a copy of the GNU Affero General Public
  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 declare(strict_types=1);
 
 namespace OCA\PaxFax\Controller;
 
 use OCP\AppFramework\ApiController;
 use OCP\IRequest;
 use OCP\AppFramework\Http\DataResponse;
 use OCP\AppFramework\OCSController;
 use OCP\IUserSession;
 use OCP\AppFramework\Controller;
 use OCP\Files\IAppData;
 use OCA\PaxFax\Service\PaxfaxService;
 use OCP\AppFramework\App;
 use OCP\Files\NotPermittedException;
 use OCP\Files\Folder;
 use OC\Files\Filesystem;
 use OC\Files\View;
 use \ReflectionClass;
 use OCP\Notification;
 use OCP\Notification\INotification;
 use OCP\Notification\IManager;
 use OCP\Notification\IAction;
 use \DateTime;
 
 use Phaxio;
 use Phaxio\OperationResult;
 use Phaxio\Error\AuthenticationException;
 use Phaxio\Error\NotFoundException;
 use Phaxio\Error\InvalidRequestException;
 use Phaxio\Error\RateLimitException;
 use Phaxio\Error\APIConnectionException;
 use Phaxio\Error\GeneralException;
 
 
 class AuthorApiController extends ApiController {
 
     private $service;
     private $userId;
     private $folder;
     private $filesystem;
     private $view;
     private $userSession;
 
     public function __construct($appName, IRequest $request, IUserSession $userSession, PaxfaxService $service, Folder $folder, Filesystem $filesystem, $userId, View $view) {
         parent::__construct(
                 $appName,
                 $request,
                 'PUT, POST, GET, DELETE, PATCH',
                 'Authorization, Content-Type, Accept',
                 1728000);
 
         $this->service = $service;
         $this->userId = $userId;
         $this->folder = $folder;
         $this->filesystem = $filesystem;
         $this->view = $view;
         $this->userSession = $userSession;
     }
 
     /**
      * @NoAdminRequired
      */
     public function object_to_array($obj) {
         if(is_object($obj)) $obj = (array)$this->dismount($obj);
         if(is_array($obj)) {
            $new = array();
            foreach($obj as $key => $val) {
                $new[$key] = $this->object_to_array($val);
            }
         }
         else $new = $obj;
         return $new;
     }
 
     /**
      * @NoAdminRequired
      */
     public function dismount($object) {
         $reflectionClass = new ReflectionClass(get_class($object));
         $array = array();
         foreach ($reflectionClass->getProperties() as $property) {
            $property->setAccessible(true);
            $array[$property->getName()] = $property->getValue($object);
            $property->setAccessible(false);
         }
         return $array;
     }
 
     /**
      * @NoAdminRequired
      */
     public function isValidCallbackRequest($token, $url = null, $postParameters = null, $uploadedFiles = null, $signature = null) {
 
 	if (!$url) {
 	    $url = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
 	}
 
 	if (!$postParameters) {
 	    $postParameters = $_REQUEST;
 	}
 
 	if (!$uploadedFiles) {
 	    $uploadedFiles = $_FILES;
 	}
 
 	if (!$signature) {
 	    $signature = $_SERVER['HTTP_X_PHAXIO_SIGNATURE'];
 	}
 
 	// Sort the array by keys
 	ksort($postParameters);
 
 	// Append the data array to the url string, with no delimiters
 	foreach ($postParameters as $key => $value) {
 		 $url .= $key . $value;
 	}
 
 	foreach ($uploadedFiles as $key => $value) {
 		 $url .= $key . sha1_file($value['tmp_name']);
 	}
 
 	$hmac = hash_hmac("sha1", $url, $token);
 	return $signature == $hmac;
     }
 
     /**
      * @NoAdminRequired
      * @NoCSRFRequired
      */
     public function receivefaxphaxio() {
 
        $phaxiosignature = $_SERVER['HTTP_X_PHAXIO_SIGNATURE'];
 
        $thisapicred = $this->service->getapicredentials($this->userId);
        $phaxiowhtoken = $thisapicred[2];
        $phaxiorecURL = $thisapicred[3];
 
        // Verify Phaxio's signature
        $signverify = $this->isValidCallbackRequest($phaxiowhtoken, $phaxiorecURL, null, null, $phaxiosignature);
 
        if ($signverify) {
 
            $fileContent = file_get_contents($_FILES['file']['tmp_name']);
            $fileNameinit = $_FILES['file']['name'];
 
            $fldate = date("Y-m-d_H-i-s_").gettimeofday()["usec"];
 
            $gmtind = "UTC " . date('P');
            $flmsdateinit = date("Y-m-d  H:i:s");
            $flmsdate = $flmsdateinit . " " . $gmtind;
 
            $fileNamesec = array_reverse(explode(".", $fileNameinit));
            $filenameext = $fileNamesec[0];
            array_shift($fileNamesec);
 
            $fileName = implode("", $fileNamesec);
 
            $faxid = str_replace("Fax-", "", $fileName);
 
            $apiMode = 'live';
 
            $apiKeys[$apiMode] = $thisapicred[0];
            $apiSecrets[$apiMode] = $thisapicred[1];
 
            $apiHost = 'https://api.phaxio.com/v2.1/';
 
            $phaxio = new Phaxio($apiKeys[$apiMode], $apiSecrets[$apiMode], $apiHost);
 
 
            try {
                       $phaxioresultreq = $phaxio->doRequest("GET", 'faxes/' . $faxid);
 
                       $fromnmbrtoarr = $this->object_to_array($phaxioresultreq);
 
                       $phaxiofromraw = $fromnmbrtoarr['data']['from_number'];
                       $phaxiotoraw  = $fromnmbrtoarr['data']['to_number'];
                       $phaxiofromnumber = str_replace("+", "", $phaxiofromraw);
                       $phaxiotonumber = str_replace("+", "", $phaxiotoraw);
                       $errortype = 'there are no errors';
 
            } catch (InvalidRequestException $e) {
                       $phaxiofromnumber = 'null';
                       $errortype = 'invalid request error';
            } catch (AuthenticationException $e) {
                       $phaxiofromnumber = 'null';
                       $errortype = 'authentication error';
            } catch (APIConnectionException $e) {
                       $phaxiofromnumber = 'null';
                       $errortype = 'API connection error';
            } catch (RateLimitException $e) {
                       $phaxiofromnumber = 'null';
                       $errortype = 'rate limit error';
            } catch (NotFoundException $e) {
                       $phaxiofromnumber = 'null';
                       $errortype = 'not found error';
            } catch (GeneralException $e) {
                       $phaxiofromnumber = 'null';
                       $errortype = 'undefined error';
            }
 
            if ($this->folder->nodeExists('Pax_Fax/faxes_received') == false) {
                $this->folder->newFolder('Pax_Fax/faxes_received');
            }
 
            if ($this->folder->nodeExists('Pax_Fax/faxes_received_failed') == false) {
                $this->folder->newFolder('Pax_Fax/faxes_received_failed');
            }
 
            $targetfile = "/Pax_Fax/faxes_received/" . $fileName . "_" . $phaxiofromnumber . "_" . $phaxiotonumber  . "_" . $fldate . "." . $filenameext;
 
            $target = $this->folder->newFile($targetfile);
 
            $target->putContent($fileContent);
 
            // Move failed received faxes to the 'faxes_received_failed' folder
            if ($filenameext == '') {
 
                $newtargetfl =  "/Pax_Fax/faxes_received_failed/" . $fileName . "_" . $phaxiofromnumber . "_" . $phaxiotonumber . "_" . $fldate . "." . $filenameext;
                $targetact = $this->folder->newFile($newtargetfl);
 
                $targetact->putContent($fileContent);
 
                $failedfl = "/Pax_Fax/faxes_received/" . $fileName . "_" . $phaxiofromnumber . "_" . $phaxiotonumber . "_" . $fldate . "." . $filenameext;
                $removefailed = $this->filesystem->unlink($failedfl);
            }
 
            // Send notifications
            $nameofhost = exec("hostname");
            $getnextnotify = $thisapicred[4];
            $useremailaddr = $thisapicred[5];
 
            if ($filenameext != '') {
                $targetflname = $targetfile;
                $targettrim = "/Pax_Fax/faxes_received/";
                $validfaxparam = "fax";
                $setsubject = "New fax received";
            } else {
                $targetflname = $newtargetfl;
                $targettrim = "/Pax_Fax/faxes_received_failed/";
                $validfaxparam = "failed fax";
                $setsubject = "New failed fax received";
            }
 
            if ($useremailaddr != '') {
 
                $subject = $setsubject;
                $message = "Hello! <br><br> You have received a new ".$validfaxparam." on ".$flmsdate." .<br> The new ".$validfaxparam." file is '".$targetflname."' . <br><br>____________<br><br> Yours, <br> Pax Fax <br> A fax application for Nextcloud <br> Host: '".$nameofhost."' <br>";
 
                $messagefin = chunk_split(base64_encode($message));
 
                $headers = "MIME-Version: 1.0" . "\r\n";
                $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
                $headers .= "Content-Transfer-Encoding: base64" . "\r\n";
 
                // Set the email sender
                $headers .= "From: " . $useremailaddr . "\r\n";
                $headers .= "Reply-To: " . $useremailaddr . "\r\n";
 
                mail($useremailaddr, $subject, $messagefin, $headers);
            }
 
            if ($getnextnotify != 0 ) {
 
                $notify = exec("php ./occ notification:generate ".$this->userId." 'Pax Fax has received a new fax !' -l 'The new fax can be found in the \"".$targettrim."\" folder.'");
           }
 
        } else { return "access denied"; }
 
     }
 
 }