lib/Controller/AuthorApiController.php
ff5abb81
 <?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\SMSRelentless\Controller;
 
 use OCP\AppFramework\ApiController;
 use OCP\IRequest;
 use OCA\SMSRelentless\Service\SmsrelentlessService;
 use OCP\AppFramework\Http\DataResponse;
 use OCP\AppFramework\OCSController;
 use OCP\IUserSession;
 use OCP\IConfig;
 use \DateTime;
 use OCP\AppFramework\Controller;
 use OCP\Files\IAppData;
 use OCP\AppFramework\App;
 use OCP\Files\NotPermittedException;
 use \ReflectionClass;
 use OCP\Notification;
 use OCP\Notification\INotification;
 use OCP\Notification\IManager;
 use OCP\Notification\IAction;
 use Plivo\RestClient;
 use Plivo\Util\signatureValidation;
 use Twilio\Rest\TwilioClient;
 
 
 class AuthorApiController extends ApiController {
 
     private $service;
     private $userId;
     private $config;
 
     public function __construct($appName, IRequest $request, SmsrelentlessService $service, $userId, IConfig $config) {
         parent::__construct(
             $appName,
             $request,
             'PUT, POST, GET, DELETE, PATCH',
             'Authorization, Content-Type, Accept',
             1728000);
 
         $this->service = $service;
         $this->userId = $userId;
         $this->config = $config;
     }
 
 
     /**
      * @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 verifyHeader($receiveddata, $signature_header, $timestamp, $public_key = '', $tolerance = null ) {
         // Typecast timestamp to int for comparisons
         $timestamp = (int)$timestamp;
 
         // Check if timestamp is within tolerance
         if (($tolerance > 0) && (\abs(\time() - $timestamp) > $tolerance)) {
              return false;
         } else {
 
             // Convert base64 string to bytes for sodium crypto functions
             $public_key_bytes = base64_decode($public_key);
             $signature_header_bytes = base64_decode($signature_header);
 
             // Construct a message to test against the signature header using the timestamp and payload
             $constructed_string = $timestamp . '|' . $receiveddata;
 
             if (!\sodium_crypto_sign_verify_detached($signature_header_bytes, $constructed_string, $public_key_bytes)) {
                 return false;
             } else {
                 return true;
             }
         }
     }
 
 
     /**
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
     public function recdeliveryreptel() {
 
        $request = file_get_contents("php://input");
        $recdata = json_decode($request, TRUE);
 
        $delsmswebhookurl = $recdata["data"]["payload"]["webhook_url"];
        $ncuserfortelnyxdel = $this->service->getuserbyteldelrwhurl($delsmswebhookurl);
 
        if ($ncuserfortelnyxdel != '' && $ncuserfortelnyxdel != null && $ncuserfortelnyxdel != 'undefined') {
 
 	       $messageid = $recdata["data"]["payload"]["id"];
 
 	       $network = $recdata["data"]["payload"]["to"][0]["carrier"];
 	       $messageprice = $recdata["data"]["payload"]["cost"]["amount"];
 	       $deliverystatus = $recdata["data"]["payload"]["to"][0]["status"];
 
 	       $goterrorinit = $recdata["data"]["payload"]["errors"];
 
 	       if (!empty($goterrorinit)) {
 		   $retrievedtitle = $recdata["data"]["payload"]["errors"][0]["title"];
 		   $retrievedcode = $recdata["data"]["payload"]["errors"][0]["code"];
 		   $messagestatus = "(Error " . $retrievedcode . ") " . $retrievedtitle;
 	       } else {
 		   $messagestatus = "Success ! The message has been successfully accepted for delivery.";
 	       }
 
 	       return $this->service->updatedeliverystatustel($ncuserfortelnyxdel, $messageid, $network, $messageprice, $messagestatus, $deliverystatus); 
 
        } else { return "access denied"; }
 
     }
 
 
     /**
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
     public function recdeliveryrepnex() {
 
        $plivodrurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
 
        $ncuserforplivodel = $this->service->getuserbyplivodelrwhurl($plivodrurl);
 
        if ($ncuserforplivodel != '' && $ncuserforplivodel != null && $ncuserforplivodel != 'undefined') {
 
 	       $networkcode = "";
 	       $mStatus = ""; 
 
 	       if (isset($_REQUEST["MessageUUID"])) { $messageid = $_REQUEST["MessageUUID"]; } else { $messageid = ''; }
 	       if (isset($_REQUEST["MCC"]) && isset($_REQUEST["MNC"])) { $networkcode = $_REQUEST["MCC"] . " " . $_REQUEST["MNC"]; } else { $networkcode = ''; }
 	       if (isset($_REQUEST["TotalAmount"])) { $messageprice = $_REQUEST["TotalAmount"]; } else { $messageprice = ''; }
 	       if (isset($_REQUEST["ErrorCode"]) && $_REQUEST["ErrorCode"] == "") {
                    $mStatus = "Success ! The message has been successfully accepted for delivery.";
                } elseif (isset($_REQUEST["ErrorCode"]) && $_REQUEST["ErrorCode"] != "") {
                    $mStatus = "Error " . $_REQUEST["ErrorCode"]; 
                } else { $mStatus = ''; }
 
 	       if (isset($_REQUEST["Status"])) { $deliverystatus = $_REQUEST["Status"]; }
 
 	       return $this->service->updatedeliverystatusnex($ncuserforplivodel, $messageid, $networkcode, $messageprice, $mStatus, $deliverystatus);
 
        } else { return "access denied"; }
 
     }
 
 
     /**
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
     public function recdeliveryreptwil() {
 
        $twildrurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
 
        $ncuserfortwildel = $this->service->getuserbytwildelrwhurl($twildrurl);
 
        if ($ncuserfortwildel != '' && $ncuserfortwildel != null && $ncuserfortwildel != 'undefined') {
 
            $messageid = $_REQUEST["SmsSid"];
            $deliverystatus = $_REQUEST["SmsStatus"];
 
            $credentialstw = $this->service->getapicredentials($ncuserfortwildel);
            $sidtw = $credentialstw[15];
            $tokentw = $credentialstw[16];
 
            if ($messageid != null) {
 
                $msdetails = json_decode(file_get_contents("https://".$sidtw.":".$tokentw."@api.twilio.com/2010-04-01/Accounts/".$sidtw."/Messages/".$messageid.".json"));
                $errorMessage = $msdetails->error_message;
                $errorCode = $msdetails->error_code;
 
                if ($errorCode == null) { 
                    $mStatus = 'Success ! The message has been successfully accepted for delivery.'; 
                } else { $mStatus = 'Error ' . $errorCode . '. Message: ' . $errorMessage; }
 
                $messagepricepre = $msdetails->price;
                $messageprice = str_replace("-", "", $messagepricepre);
                $networkcode = '';
 
 	       return $this->service->updatedeliverystatustwil($ncuserfortwildel, $messageid, $networkcode, $messageprice, $mStatus, $deliverystatus);
 
            } else { return; }
 
        } else { return "access denied"; }
 
     }
 
 
     /**
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
     public function receivesmstel() {
 
        $signature = $_SERVER['HTTP_TELNYX_SIGNATURE_ED25519'];
        $timestamp = $_SERVER['HTTP_TELNYX_TIMESTAMP'];
 
        $receivereq = file_get_contents('php://input');
 
        $recmesdata = json_decode($receivereq, TRUE);
 
        $recsmswebhookurl = $recmesdata["data"]["payload"]["webhook_url"];
 
        $ncuserfortelnyx = $this->service->getuserbytelrecwhurl($recsmswebhookurl);
 
        $credentials = $this->service->getapicredentials($ncuserfortelnyx);
 
        $telpubkey = $credentials[1];
 
        // Verify message signature
        $signatureverify = $this->verifyHeader($receivereq, $signature, $timestamp, $telpubkey, $tolerance = 30);
 
        if ($signatureverify) {
 
           if ($ncuserfortelnyx != '' && $ncuserfortelnyx != null && $ncuserfortelnyx != 'undefined') {
 
 	       $messagetexttel = $recmesdata["data"]["payload"]["text"];
 
 	       $messageid = $recmesdata["data"]["payload"]["id"];
 
 	       $messagedate = date("Y-m-d H:i:s");
 
 	       $messagefrom = $recmesdata["data"]["payload"]["from"]["phone_number"];
 
 	       $messageto = "Telnyx: " . $recmesdata["data"]["payload"]["to"][0]["phone_number"];
 
 	       $recmessagearr = [$messageid, $messagedate, $messagefrom, $messageto, $messagetexttel];
 
 	       $this->service->insertrecsms($ncuserfortelnyx, $recmessagearr);
 
 	       // Send notifications
 	       $nameofhost = exec("hostname");
 
 	       $telsmsapicred = $this->service->getapicredentials($ncuserfortelnyx);
 	       $telnotify = $telsmsapicred[12];
 	       $emailaddress = $telsmsapicred[13];
 	       $includemessageinemail = $telsmsapicred[14];
 
 	       if ($telnotify != 0 ) {
 		   $notifytel = exec("php ./occ notification:generate ".$ncuserfortelnyx." 'SMS Relentless has received a new SMS message !' -l 'You can read the new message by going to SMS Relentless and clicking on the Received SMS Messages button.'");
 
 	       }
 
 	       if ($emailaddress != '') {
 
 		   $gmtind = "UTC " . date('P');
 		   $smsdateinit = date("Y-m-d  H:i:s");
 		   $smsdate = $smsdateinit . " " . $gmtind;
 
 		   $subject = "New SMS message received";
 
                    $messagetextnltel = str_replace("\n", "<br>", $messagetexttel);
 
 		   if ($includemessageinemail == 0) {
 		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." .<br> You can check the new message by going to 'SMS Relentless' > 'Received SMS Messages'. <br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
 		   } else {
 		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." :<br><br><br> Message ID: ".$messageid." <br> Message Date: ".$messagedate." <br> From: ".$messagefrom." <br> To: ".$messageto."<br> Message Text: <br><br><b>".$messagetextnltel."</b><br><br>____________<br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
 		   }
 
 		   $headers = "MIME-Version: 1.0" . "\r\n";
 		   $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
 
 		   // Set the email sender
 		   $headers .= "From: " . $emailaddress . "\r\n";
 		   $headers .= "Reply-To: " . $emailaddress . "\r\n";
 
 		   mail($emailaddress, $subject, $message, $headers);
 	       }
 
 	       return http_response_code(200);
 
           } else { return "access denied"; }
 
        } else { return "access denied"; }
     }
 
 
     /**
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
     public function receivesmsnex() {
 
        $plivosignature = $_SERVER['HTTP_X_PLIVO_SIGNATURE_V2'];
        $plivononce = $_SERVER["HTTP_X_PLIVO_SIGNATURE_V2_NONCE"];
 
        $plivorecurl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
 
        $ncuserforplivo = $this->service->getuserbyplivorecwhurl($plivorecurl);
 
        $smsapicred = $this->service->getapicredentials($ncuserforplivo);
 
        $plivoauthtoken = $smsapicred[6];
 
        $baseplivourlinit = explode("?", $plivorecurl);   
        $baseplivoURI = $baseplivourlinit[0];
 
        // Verify message signature
        $SigValidation = new signatureValidation();
        $signverify = $SigValidation->validateSignature($baseplivoURI, $plivononce, $plivosignature, $plivoauthtoken);
 
        if ($signverify) {
 
            if ($ncuserforplivo != '' && $ncuserforplivo != null && $ncuserforplivo != 'undefined') {
 
 	       $messageid = $_REQUEST["MessageUUID"];
 
 	       $messagedate = date("Y-m-d H:i:s");
 
 	       $messagefrom = "+" . $_REQUEST['From'];
 	       $messageto = "Plivo: +" . $_REQUEST['To'];
 
 	       $messagetextnex = $_REQUEST['Text'];
 
 	       $recmessagearr = [$messageid, $messagedate, $messagefrom, $messageto, $messagetextnex];
 
                $this->service->insertrecsms($ncuserforplivo, $recmessagearr);
 
 	       // Send notifications
 	       $nameofhost = exec("hostname");
 
 	       $nextnotify = $smsapicred[12];
 	       $emailaddress = $smsapicred[13];
 	       $includemessageinemail = $smsapicred[14];
 
 	       if ($nextnotify != 0 ) {
 		   $notifynext = exec("php ./occ notification:generate ".$ncuserforplivo." 'SMS Relentless has received a new SMS message !' -l 'You can read the new message by going to SMS Relentless and clicking on the Received SMS Messages button.'");
 	       }
 
 	       if ($emailaddress != '') {
 
 		   $gmtind = "UTC " . date('P');
 		   $smsdateinit = date("Y-m-d  H:i:s");
 		   $smsdate = $smsdateinit . " " . $gmtind;
 
 		   $subject = "New SMS message received";
 
                    $messagetextnlnex = str_replace("\n", "<br>", $messagetextnex);
 
 		   if ($includemessageinemail == 0) {
 		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." .<br> You can check the new message by going to 'SMS Relentless' > 'Received SMS Messages'. <br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
 		   } else {
 		       $message = "Hello, <br><br> You have received a new message on ".$smsdate." :<br><br><br> Message ID: ".$messageid." <br> Message Date: ".$messagedate." <br> From: ".$messagefrom." <br> To: ".$messageto."<br> Message Text: <br><br><b>".$messagetextnlnex."</b><br><br>____________<br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
 		   }
 
 		   $headers = "MIME-Version: 1.0" . "\r\n";
 		   $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
 
 		   // Set the email sender
 		   $headers .= "From: " . $emailaddress . "\r\n";
 		   $headers .= "Reply-To: " . $emailaddress . "\r\n";
 
 		   mail($emailaddress, $subject, $message, $headers);
 	       }
 
 	       return http_response_code(200);
 
            } else { return "access denied"; }
 
        } else { return "access denied"; }
     }
 
     /**
      * @NoAdminRequired
      * @NoCSRFRequired
      * @PublicPage
      */
     public function receivesmstwil() {
 
        $twilsignature = $_SERVER['HTTP_X_TWILIO_SIGNATURE'];
 
        $basepath = $this->config->getSystemValue('overwrite.cli.url');
        $twilrecurl = $basepath."/apps/sms_relentless/api/recsmstwil";
 
        $ncuserfortwil = $this->service->getuserbytwilrecwhurl($twilrecurl);
 
        $smsapicred = $this->service->getapicredentials($ncuserfortwil);
        $authToken = $smsapicred[16];
 
        $postVars = [
 		"AccountSid" => $_POST["AccountSid"],
 		"ApiVersion" => $_POST["ApiVersion"],
 		"Body" => $_POST["Body"],
 		"From" => $_POST["From"],
 		"FromCity" => $_POST["FromCity"],
 		"FromCountry" => $_POST["FromCountry"],
 		"FromState" => $_POST["FromState"],
 		"FromZip" => $_POST["FromZip"],
 		"MessageSid" => $_POST["MessageSid"],
 		"MessagingServiceSid" => $_POST["MessagingServiceSid"],
 		"NumMedia" => $_POST["NumMedia"],
 		"NumSegments" => $_POST["NumSegments"],
 		"ReferralNumMedia" => $_POST["ReferralNumMedia"],
 		"SmsMessageSid" => $_POST["SmsMessageSid"],
 		"SmsSid" => $_POST["SmsSid"],
 		"SmsStatus" => $_POST["SmsStatus"],
 		"To" => $_POST["To"],
 		"ToCity" => $_POST["ToCity"],
 		"ToCountry" => $_POST["ToCountry"],
 		"ToState" => $_POST["ToState"],
 		"ToZip" => $_POST["ToZip"]
        ];
 
        // Verify message signature
        $validator = new \Twilio\Security\RequestValidator($authToken);
 
        $valid = $validator->validate($twilsignature, $twilrecurl, $postVars);
 
        if ($valid) {
 
 	       if ($ncuserfortwil != '' && $ncuserfortwil != null && $ncuserfortwil != 'undefined') {
 
 		       $messageid = $_POST['MessageSid'];
 
 		       $messagedate = date("Y-m-d H:i:s");
 
 		       $messagefrom = $_POST['From'];
 
 		       $messageto = "Twilio: " . $_POST['To'];
 
 		       $messagetexttw = $_POST['Body'];
 
 		       $recmessagearr = [$messageid, $messagedate, $messagefrom, $messageto, $messagetexttw];
 
 		       $this->service->insertrecsms($ncuserfortwil, $recmessagearr);
 
 		       // Send notifications
 		       $nameofhost = exec("hostname");
 
 		       $twilnotify = $smsapicred[12];
 		       $emailaddress = $smsapicred[13];
 		       $includemessageinemail = $smsapicred[14];
 
 		       if ($twilnotify != 0 ) {
 			   $notifynext = exec("php ./occ notification:generate ".$ncuserfortwil." 'SMS Relentless has received a new SMS message !' -l 'You can read the new message by going to SMS Relentless and clicking on the Received SMS Messages button.'");
 		       }
 
 		       if ($emailaddress != '') {
 
 			   $gmtind = "UTC " . date('P');
 			   $smsdateinit = date("Y-m-d  H:i:s");
 			   $smsdate = $smsdateinit . " " . $gmtind;
 
 			   $subject = "New SMS message received";
 
                            $messagetextnltw = str_replace("\n", "<br>", $messagetexttw);
 
 			   if ($includemessageinemail == 0) {
 			       $message = "Hello, <br><br> You have received a new message on ".$smsdate." .<br> You can check the new message by going to 'SMS Relentless' > 'Received SMS Messages'. <br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
 			   } else {
 			       $message = "Hello, <br><br> You have received a new message on ".$smsdate." :<br><br><br> Message ID: ".$messageid." <br> Message Date: ".$messagedate." <br> From: ".$messagefrom." <br> To: ".$messageto."<br> Message Text: <br><br><b>".$messagetextnltw."</b><br><br>____________<br><br> Yours, <br> SMS Relentless <br> An SMS application for Nextcloud <br> Host: '".$nameofhost."' <br>";
 			   }
 
 			   $headers = "MIME-Version: 1.0" . "\r\n";
 			   $headers .= "Content-type: text/html; charset=UTF-8" . "\r\n";
 
 			   // Set the email sender
 			   $headers .= "From: " . $emailaddress . "\r\n";
 			   $headers .= "Reply-To: " . $emailaddress . "\r\n";
 
 			   mail($emailaddress, $subject, $message, $headers);
 		       }
 
 		       return http_response_code(200);
 
 	       } else { return "access denied"; }
 
        } else { return "access denied"; }
 
     }
 
 }