1<?php 2class helper_plugin_twofactorsmsappliance extends Twofactor_Auth_Module { 3 /** 4 * If the user has a valid email address in their profile, then this can be used. 5 */ 6 public function canUse($user = null){ 7 return ($this->_settingExists("verified", $user)); 8 } 9 10 /** 11 * This module can not provide authentication functionality at the main login screen. 12 */ 13 public function canAuthLogin() { 14 return false; 15 } 16 17 /** 18 * This user will need to supply a phone number and their cell provider. 19 */ 20 public function renderProfileForm(){ 21 $elements = array(); 22 // Provide an input for the phone number. 23 $phone = $this->_settingGet("phone", ''); 24 $elements[] = form_makeTextField('smsappliance_phone', $phone, $this->getLang('phone'), '', 'block', array('size'=>'50')); 25 26 // If the phone number has not been verified, then do so here. 27 if ($phone) { 28 if (!$this->_settingExists("verified")) { 29 // Render the HTML to prompt for the verification/activation OTP. 30 $elements[] = '<span>'.$this->getLang('verifynotice').'</span>'; 31 $elements[] = form_makeTextField('smsappliance_verify', '', $this->getLang('verifymodule'), '', 'block', array('size'=>'50', 'autocomplete'=>'off')); 32 $elements[] = form_makeCheckboxField('smsappliance_send', '1', $this->getLang('resendcode'),'','block'); 33 } 34 // Render the element to remove the phone since it exists. 35 $elements[] = form_makeCheckboxField('smsappliance_disable', '1', $this->getLang('killmodule'), '', 'block'); 36 } 37 return $elements; 38 } 39 40 /** 41 * Process any user configuration. 42 */ 43 public function processProfileForm(){ 44 global $INPUT; 45 $phone = $INPUT->str('smsappliance_phone', ''); 46 //msg($phone); 47 if ($INPUT->bool('smsappliance_disable', false) || $phone === '') { 48 // Delete the phone number. 49 $this->_settingDelete("phone"); 50 // Delete the verified setting. Otherwise the system will still expect the user to login with OTP. 51 $this->_settingDelete("verified"); 52 return true; 53 } 54 $oldphone = $this->_settingGet("phone", ''); 55 if ($oldphone) { 56 if ($INPUT->bool('smsappliance_send', false)) { 57 return 'otp'; 58 } 59 $otp = $INPUT->str('smsappliance_verify', ''); 60 if ($otp) { // The user will use SMS. 61 $checkResult = $this->processLogin($otp); 62 // If the code works, then flag this account to use SMS Gateway. 63 if ($checkResult == false) { 64 return 'failed'; 65 } 66 else { 67 $this->_settingSet("verified", true); 68 return 'verified'; 69 } 70 } 71 } 72 73 $changed = null; 74 if (preg_match('/^[0-9]{5,}$/',$phone) != false) { 75 if ($phone != $oldphone) { 76 if ($this->_settingSet("phone", $phone)== false) { 77 msg("TwoFactor: Error setting phone.", -1); 78 } 79 // Delete the verification for the phone number if it was changed. 80 $this->_settingDelete("verified"); 81 return 'deleted'; 82 } 83 } 84 85 // If the data changed and we have everything needed to use this module, send an otp. 86 if ($changed === true && $this->_settingExists("phone")) { 87 $changed = 'otp'; 88 } 89 return $changed; 90 } 91 92 /** 93 * This module can send messages. 94 */ 95 public function canTransmitMessage(){ 96 return true; 97 } 98 99 /** 100 * Transmit the message via email to the address on file. 101 */ 102 public function transmitMessage($subject, $message, $force = false){ 103 if (!$this->canUse() && !$force) { return false; } 104 $number = $this->_settingGet("phone", null); 105 if (!$number) { 106 // If there is no phone number, then fail. 107 return false; 108 } 109 $url = str_replace('$phone', $number, $this->getConf('url')); 110 $url = str_replace('$msg', rawurlencode($message), $url); 111 // Deliver the message and capture the results. 112 $result = file_get_contents($url); 113 // TODO: How do we verify success? 114 return true; 115 } 116 117 /** 118 * This module uses the default authentication. 119 */ 120 //public function processLogin($code); 121}