PageRenderTime 103ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/Model/User.php

https://github.com/martyish/ppi-framework
PHP | 332 lines | 206 code | 33 blank | 93 comment | 31 complexity | 3f87ad6f5c81523617be89435221cfef MD5 | raw file
  1. <?php
  2. /**
  3. * @version 1.0
  4. * @author Paul Dragoonis <dragoonis@php.net>
  5. * @license http://opensource.org/licenses/mit-license.php MIT
  6. * @copyright Digiflex Development
  7. * @package Model
  8. * @link www.ppiframework.com
  9. */
  10. class PPI_Model_User extends APP_Model_Application {
  11. public $_encryptionAlgorithm = 'sha1';
  12. // @todo - Make sure this is default but config overridden
  13. private $_usernameField = 'email';
  14. // @todo - Make sure this is default but config overridden
  15. private $_passwordField = 'password';
  16. private $_iTableName;
  17. private $_iTableIndex;
  18. function __construct($p_iTableName = "", $p_iTableIndex = "", $p_sBdbInfo = "", $p_iUserID = 0) {
  19. global $oConfig;
  20. $this->_iTableName = $p_iTableName;
  21. $this->_iTableIndex = $p_iTableIndex;
  22. parent::__construct($p_iTableName, $p_iTableIndex, $p_sBdbInfo, $p_iUserID);
  23. // encryption algorithm override
  24. if(isset($oConfig->system->encryptionAlgorithm)) {
  25. $this->_encryptionAlgorithm = $oConfig->system->encryptionAlgorith;
  26. }
  27. }
  28. // ----------------------- User Register ---------------------
  29. function putRecord(array $aData) {
  30. $oConfig = PPI_Helper::getConfig();
  31. // If its an insert
  32. if(!array_key_exists($this->_iTableIndex, $aData)) {
  33. $plainPass = $aData['password'];
  34. if(!array_key_exists($oConfig->system->usernameField, $aData)) {
  35. throw new PPI_Exception('Unable to locate username field when creating user');
  36. }
  37. $aData['active'] = isset($oConfig->system->defaultUserActive) && $oConfig->system->defaultUserActive != false ? 1 : 0;
  38. $aData['created'] = time();
  39. $aData['activation_code'] = base64_encode(time());
  40. // ----- Password Stuff ----
  41. if(isset($aData['salt'])) {
  42. $sSalt = $aData['salt'];
  43. unset($aData['salt']);
  44. // If no salt has been set then we get it from the config.
  45. } else {
  46. $sSalt = $oConfig->system->userAuthSalt;
  47. }
  48. if(empty($sSalt)) {
  49. throw new PPI_Exception('No salt found when trying to register user');
  50. }
  51. $aData['password'] = $this->encryptPassword($sSalt, $aData['password']);
  52. // If no role_id has been set, lets set it from the config.
  53. if(!isset($aData['role_id'])) {
  54. if(!isset($oConfig->system->defaultUserRole)) {
  55. throw new PPI_Exception('Missing config value system.defaultUserRole');
  56. }
  57. $aData['role_id'] = PPI_Model_Helper::getRoleIDFromName($oConfig->system->defaultUserRole);
  58. }
  59. } else {
  60. //if password is being passed in for re-set, we need to encrypt it
  61. if(isset($aData['password'], $aData['salt'])) {
  62. $aData['password'] = $this->encryptPassword($aData['salt'], $aData['password']);
  63. unset($aData[$oConfig->system->usernameField]);
  64. unset($aData['salt']);
  65. }
  66. }
  67. return parent::putRecord($aData);
  68. // set the system log here
  69. // send acitvation email here
  70. //$oEmail = new PPI_Model_Email();
  71. /*$oEmail->setTemplate('User Registration', array(
  72. 'site_name' => $oConfig->site_name,
  73. 'username' => $aData[$oConfig->usernameField],
  74. 'password' => $plainPass
  75. ))->sendMail();*/
  76. }
  77. function activate($iUserID, $sActivationCode) {
  78. }
  79. /**
  80. * Update a users password
  81. * @param integer $p_iUserID The User ID we wish to update
  82. * @param string $p_sPassword The plaintext password to update
  83. * @return boolean
  84. */
  85. function updatePassword($p_iUserID, $p_sPassword) {
  86. // If we were able to get user details
  87. $aUser = $this->find($p_iUserID);
  88. if(!empty($aUser)) {
  89. $oConfig = $this->getConfig();
  90. // Using the username field from the config.
  91. $usernameField = $oConfig->system->usernameField;
  92. // Get the salt from the config
  93. $salt = $oConfig->system->userAuthSalt;
  94. if(empty($salt)) {
  95. throw new PPI_Exception('Unable to update password. No salt found in config value: system.userAuthSalt');
  96. }
  97. // We update the users record.
  98. $this->putRecord(array(
  99. $this->getPrimaryKey() => $p_iUserID,
  100. 'salt' => $salt,
  101. 'password' => $p_sPassword
  102. ));
  103. return true;
  104. }
  105. return false;
  106. }
  107. // ----------------- Authentication Functions -----------------
  108. /**
  109. * Login function for the user, passing the username and password.
  110. * @param string $username The username (the value of the usernameField from the config)
  111. * @param string $password The plaintext password
  112. * @return boolean
  113. */
  114. function login($username, $password) {
  115. $oConfig = $this->getConfig();
  116. $user = $this->fetch($oConfig->system->usernameField . ' = ' . $this->quote($username));
  117. if(!empty($user)) {
  118. if($this->encryptPassword($oConfig->system->userAuthSalt, $password) === $user['password']) {
  119. if(array_key_exists('password', $user)) {
  120. unset($user['password']);
  121. }
  122. $user['role_name'] = PPI_Helper_User::getRoleNameFromID($user['role_id']);
  123. $user['role_name_nice'] = PPI_Helper_User::getRoleNameNice($user['role_name']);
  124. $this->getSession()->setAuthData($user);
  125. return true;
  126. }
  127. }
  128. return false;
  129. }
  130. /**
  131. * Log the user out. Wipe all the session data
  132. */
  133. function logout() {
  134. $this->getSession()->removeAll();
  135. }
  136. /**
  137. * Verify if the user is logged in or not
  138. * @return boolean
  139. */
  140. function isLoggedIn() {
  141. return (count($this->getSession()->getAuthData()) > 0);
  142. }
  143. function getRoleGroups() {
  144. global $oConfig;
  145. if(is_array($oConfig->system->roleMapping)) {
  146. return $oConfig->system->roleMapping;
  147. } else {
  148. return (array) $oConfig->system->roleMapping;
  149. }
  150. }
  151. function getRoleType($p_iRoleID) {
  152. $aGroups = $this->getRoleGroups();
  153. foreach ($aGroups as $key => $val) {
  154. if ($val == $p_iRoleID) {
  155. return $key;
  156. }
  157. }
  158. return 'unknown';
  159. }
  160. function getRoleID($p_sRoleType) {
  161. $aGroups = $this->getRoleGroups();
  162. if(in_array($p_sRoleType, $aGroups)) {
  163. foreach($aGroups as $key => $val) {
  164. if($aGroups[$key] == $p_sRoleType) {
  165. return $key;
  166. }
  167. }
  168. }
  169. return false;
  170. }
  171. function getID($where) {
  172. $select = $this->select()
  173. ->from('users')
  174. ->where($where);
  175. $rows = $select->getList($select)->fetchAll();
  176. return (count($rows) > 0) ? $rows[0][$this->_iTableIndex] : 0;
  177. }
  178. /**
  179. * Generate a new password
  180. *
  181. * @param string $password The plaintext password
  182. * @return string
  183. */
  184. function encryptNewPassword($password) {
  185. $oReg = $this->getRegistry();
  186. if(!$oReg->exists('PPI_Model_User::hash_algos')) {
  187. $algos = hash_algos();
  188. $oReg->set('PPI_Model_User::hash_algos', $algos);
  189. }
  190. if(!isset($algos)) {
  191. $algos = $oReg->get('PPI_Model_User::hash_algos');
  192. }
  193. $algo = $this->_encryptionAlgorithm;
  194. if(!in_array($algo, $algos)) {
  195. throw new PPI_Exception('Unable to use algorithm: ' . $algo . 'not supported in list of: ' . implode(', ', $algos));
  196. }
  197. $oConfig = $this->getConfig();
  198. $salt = (!empty($oConfig->system->userAuthSalt)) ? $oConfig->system->userAuthSalt : '';
  199. return $this->encryptPassword($salt, $password);
  200. }
  201. /**
  202. * Encrypt + salt the users password.
  203. * @param string $salt The salt
  204. * @param string $password The plaintext password
  205. */
  206. function encryptPassword($salt, $password) {
  207. return $salt . hash($this->_encryptionAlgorithm, $salt . $password);
  208. }
  209. /**
  210. * Verify the username against the password
  211. *
  212. * @param string $username The username
  213. * @param string $password The password
  214. * @return boolean
  215. */
  216. function checkPassword($username, $password) {
  217. $user = $this->fetch($this->getConfig()->system->usernameField . ' = ' . $this->quote($username));
  218. if(!empty($user)) {
  219. return ($this->encryptPassword(substr($user['password'], 0, 12), $password) === $user['password']);
  220. }
  221. return false;
  222. }
  223. /**
  224. * Setter for the algorithm
  225. * @param string $algorithm The algorithm function
  226. */
  227. function setAlgorithm($algorithm) {
  228. $this->_encryptionAlgorithm = $algorithm;
  229. }
  230. /**
  231. * Get the current algorithm set
  232. * @return string
  233. */
  234. function getAlgorithm() {
  235. return $this->_encryptionAlgorithm;
  236. }
  237. /**
  238. * Send the password recovery email to the user.
  239. * @param string $p_sEmail The Email Address
  240. * @param string $p_sSubject The Subject
  241. * @param string $p_sMessage The Message
  242. * @return boolean
  243. */
  244. function sendRecoverEmail($p_aUser, $p_sSubject = '', $p_sMessage = '') {
  245. $oConfig = $this->getConfig();
  246. if($p_sSubject === '') {
  247. $p_sSubject = 'Password recovery';
  248. }
  249. $sRecoveryCode = base64_encode(time());
  250. if($p_sMessage === '') {
  251. $p_sMessage = "Hi, {$p_aUser['first_name']}\n\nYou have requested a password recovery and your password has now been reset.\nPlease click the following verification link to reset your password.\n";
  252. $p_sMessage .= $oConfig->system->base_url . 'user/recover/' . urlencode($sRecoveryCode);
  253. }
  254. $oEmail = new PPI_Model_Email_Advanced();
  255. $oEmail->Subject = $p_sSubject;
  256. $oEmail->SetFrom($oConfig->system->adminEmail, $oConfig->system->adminName);
  257. $oEmail->AddAddress($p_aUser['email']);
  258. $oEmail->AltBody = $p_sMessage;
  259. $oEmail->MsgHTML($p_sMessage);
  260. // If the email sent successfully,
  261. if($oEmail->Send()) {
  262. $oUser = new APP_Model_User();
  263. $sPrimaryKey = $oUser->getPrimaryKey();
  264. // Lets update the users record with their recovery_code
  265. $oUser->putRecord(array(
  266. 'recovery_code' => $sRecoveryCode,
  267. $sPrimaryKey => $p_aUser[$sPrimaryKey]
  268. ));
  269. return true;
  270. }
  271. return false;
  272. }
  273. /**
  274. * Incomplete
  275. * @todo everything
  276. * @param string $p_sRecoverCode Recovery code
  277. */
  278. function verifyRecoverCode($p_sRecoverCode) {
  279. $p_sRecoverCode = base64_decode(urldecode($p_sRecoverCode));
  280. }
  281. /**
  282. * The formbuilder structure for the Password Recovery module.
  283. * @return array The form structure
  284. */
  285. function getRecoverFormStructure() {
  286. $structure = array(
  287. 'fields' => array(
  288. 'email' => array('type' => 'text', 'label' => 'Email address')
  289. ),
  290. 'rules' => array(
  291. 'email' => array(
  292. array('type' => 'required', 'message' => 'You must enter a valid email address'),
  293. array('type' => 'email', 'message' => 'You must enter a valid email address')
  294. )
  295. )
  296. );
  297. return $structure;
  298. }
  299. }