PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/public/codeCore/Classes/php/User.php

https://github.com/IAmCorbin/MooKit
PHP | 371 lines | 227 code | 14 blank | 130 comment | 49 complexity | 1a72f0f8c051ec585debaf79c38f8e21 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * contains User Class
  4. * @package MooKit
  5. */
  6. /**
  7. * User Class
  8. *
  9. * User manipulation class ( Add / Edit / Delete / Retrieve )
  10. *
  11. * @author Corbin Tarrant
  12. * @copyright Febuary 20th, 2010
  13. * @link http://www.IAmCorbin.net
  14. * @package MooKit
  15. */
  16. class User {
  17. /** @var DB_MySQLi $DB database object */
  18. var $DB = NULL;
  19. /** @var string $json_status stores the status (success/error) of user manipulation, and any other data to be sent back to javascript */
  20. var $json_status = NULL;
  21. /** @var int $user_id users's id */
  22. var $user_id = NULL;
  23. /** @var string $nameFirst user's first name */
  24. var $nameFirst = NULL;
  25. /** @var string $namelast user's last name */
  26. var $nameLast = NULL;
  27. /** @var string $alias user's alias */
  28. var $alias = NULL;
  29. /** @var string $email user's email */
  30. var $email = NULL;
  31. /** @var string $registered date and time user registered */
  32. var $registered = NULL;
  33. /** @var string $lastLogin date and time user last logged in */
  34. var $lastLogin = NULL;
  35. /** @var string $ip_address user's ip address */
  36. var $ip_address = NULL;
  37. /** @var int $access_level user's access_level */
  38. var $access_level = NULL;
  39. /**
  40. * Constructor
  41. *
  42. * Filters input and adds or authenticates a user with the database
  43. *
  44. *@param array $userInput array filled with filtered user input : if creating a new user pass keys{ alias, nameFirst, nameLast, password, vpassword, email }, if authenticating an existing user pass keys{ alias, password, vpassword }
  45. *@param bool $newUser switch to create a new user or retrieve an existing one
  46. *@param function $newUserCallback function that will be called if a new user is successfully added
  47. */
  48. function __construct($userInput, $newUser = TRUE, $newUserCallback = NULL) {
  49. //make sure $userInput is an array
  50. if(!is_array($userInput)) {
  51. $this->json_status = json_encode(array('status'=>'E_MISSING_DATA'));
  52. return;
  53. }
  54. //establish database connection
  55. $this->DB = new DB_MySQLi;
  56. if($newUser) {
  57. //check for valid passed data
  58. if(!array_keys_exist(array('alias','nameFirst','nameLast','password','email'),$userInput)) {
  59. $this->json_status = json_encode(array('status'=>'E_MISSING_DATA'));
  60. return;
  61. }
  62. //filter input
  63. $inputFilter = new Filters;
  64. //Validate User Input
  65. $filteredInput['alias'] = $inputFilter->text($userInput['alias'], true); //also strip whitespace
  66. $filteredInput['alias'] = $inputFilter->alphnum_($filteredInput['alias']); //only allow alphanumeric or underscore for alias
  67. $filteredInput['nameFirst'] = $inputFilter->text($userInput['nameFirst'],true); //also strip whitespace
  68. $filteredInput['nameLast'] = $inputFilter->text($userInput['nameLast'],true); //also strip whitespace
  69. $filteredInput['password'] = $inputFilter->text($userInput['password']);
  70. $filteredInput['vpassword'] = $inputFilter->text($userInput['vpassword']);
  71. $filteredInput['email'] = $inputFilter->email($userInput['email']);
  72. //Check for matching passwords
  73. if($filteredInput['password'] != $filteredInput['vpassword']) {
  74. $this->json_status = json_encode(array('status'=>"E_BADPASS",'alias'=>$filteredInput['alias'],'nameFirst'=>$filteredInput['nameFirst'],'nameLast'=>$filteredInput['nameLast'],'email'=>$filteredInput['email']));
  75. return;
  76. }
  77. //Check for Filter Errors
  78. if($errors = $inputFilter->ERRORS()) {
  79. //Filter Error - Send back filteredInput so user can correct and resend
  80. $this->json_status = json_encode(array('status'=>"E_FILTERS",'alias'=>$filteredInput['alias'],'nameFirst'=>$filteredInput['nameFirst'],'nameLast'=>$filteredInput['nameLast'],'email'=>$filteredInput['email']));
  81. return;
  82. }
  83. //attempt to add this user
  84. if($userStatus = $this->addNew($filteredInput['alias'],$filteredInput['password'],$filteredInput['nameFirst'],$filteredInput['nameLast'],$filteredInput['email'])) {
  85. //Fire New User Callback if it was passed
  86. if(is_callable($newUserCallback)) {
  87. //echo "is_callable : true";
  88. call_user_func($newUserCallback);
  89. }
  90. }
  91. } else {
  92. //check for valid passed data
  93. if(!array_keys_exist(array('alias','password'),$userInput)) {
  94. $this->json_status = json_encode(array('status'=>'E_MISSING_DATA'));
  95. return;
  96. }
  97. //filter input
  98. $inputFilter = new Filters;
  99. //Validate User Input
  100. $filteredInput['alias'] = $inputFilter->text($userInput['alias'], true); //also strip whitespace
  101. $filteredInput['alias'] = $inputFilter->alphnum_($filteredInput['alias']); //only allow alphanumeric or underscore for alias
  102. $filteredInput['password'] = $inputFilter->text($userInput['password']);
  103. //Check for Filter Errors
  104. if($errors = $inputFilter->ERRORS()) {
  105. //Filter Error - Send back filteredInput so user can correct and resend
  106. $this->json_status = json_encode(array('status'=>"E_FILTERS",'alias'=>$filteredInput['alias']));
  107. return;
  108. }
  109. //get user's registration time
  110. $user = $this->DB->get_row("SELECT `registered` FROM `users` WHERE `alias`=? LIMIT 1;",
  111. 's',array($filteredInput['alias']));
  112. if(is_object($user) && isset($user->registered)) {
  113. //store user's registration DATETIME
  114. $this->regTime = $user->registered;
  115. } else { //user was not found
  116. $this->json_status = json_encode(array('status'=>'E_NOAUTH','alias'=>$filteredInput['alias']));
  117. return false;
  118. }
  119. //encrypt sent password
  120. $encPass = $this->encryptPassword($filteredInput['password'],$this->regTime);
  121. //attempt to retrieve this user
  122. if($this->retrieve($filteredInput['alias'],$encPass)) {
  123. //set authenticated session variables
  124. $this->AUTH();
  125. //update last login time in database to now
  126. $this->updateLastLogin();
  127. return true;
  128. } else {
  129. $this->NOAUTH();
  130. $this->json_status = json_encode(array('status'=>'E_NOAUTH'));
  131. return false;
  132. }
  133. }
  134. }
  135. /**
  136. * Add a new user to the database
  137. * @param string $alias new user's alias
  138. * @param string $password new user's password
  139. * @param string $nameFirst new user's first name
  140. * @param string $nameLast new user's last name
  141. * @param string $email new user's email address
  142. *
  143. */
  144. public function addNew($alias,$password,$nameFirst,$nameLast,$email) {
  145. //check database for duplicate username
  146. $user = $this->DB->get_row("SELECT `alias` FROM `users` WHERE `alias`=? OR `email`=? LIMIT 1;",
  147. 'ss', array($alias,$email));
  148. if(is_object($user) && isset($user->alias)) {
  149. $this->json_status = json_encode(array('status'=>'E_DUPLICATE','alias'=>$alias,'nameFirst'=>$nameFirst,'nameLast'=>$nameLast,'email'=>$email));
  150. return false;
  151. }
  152. //set user's registration time as the current time
  153. $regTime = date('Y-m-d H:i:s');
  154. //get user's IP
  155. $ip_address = $_SERVER['REMOTE_ADDR'];
  156. //generate encrypted password
  157. $encPass = $this->encryptPassword($password,$regTime);
  158. //add new user to database
  159. if($this->DB->insert("INSERT INTO `users`(`alias`,`nameFirst`,`nameLast`,`password`,`email`,`registered`,`ip_address`)
  160. VALUES(?,?,?,?,?,?,INET_ATON(?));",
  161. 'sssssss',array($alias,$nameFirst,$nameLast,$encPass,$email,$regTime,$ip_address))) {
  162. $this->json_status = json_encode(array('status'=>'1'));
  163. return true;
  164. } else {
  165. $this->json_status = json_encode(array('status'=>'E_INSERT'));
  166. return false;
  167. }
  168. }
  169. /**
  170. * Retrieve a user's information from the database and store to object variables
  171. * @param string $alias user's alias
  172. * @param string $pass user's encrypted password
  173. */
  174. public function retrieve($alias, $encPass) {
  175. //grab user data from database
  176. $user = $this->DB->get_row("SELECT `user_id`,`alias`,`nameFirst`,`nameLast`,`email`,`lastLogin`,INET_NTOA(ip_address) as ip_address,`access_level`
  177. FROM `users` WHERE `alias`=? AND `password`=?;",
  178. 'ss',array($alias,$encPass));
  179. if(!is_object($user)) {
  180. $this->json_status = json_encode(array('status'=>'E_NOAUTH'));
  181. return false;
  182. }
  183. //set User data
  184. $this->user_id = $user->user_id;
  185. $this->alias = $user->alias;
  186. $this->nameFirst = $user->nameFirst;
  187. $this->nameLast = $user->nameLast;
  188. $this->email = $user->email;
  189. $this->lastLogin = $user->lastLogin;
  190. $this->ip_address = $user->ip_address;
  191. $this->access_level = $user->access_level;
  192. //success
  193. $this->json_status = json_encode(array('status'=>'1'));
  194. return true;
  195. }
  196. /**
  197. * Update user's lastLogin datetime
  198. * @return bool
  199. */
  200. public function updateLastLogin() {
  201. if($this->DB->update("UPDATE `users` SET `lastLogin`='".date('Y-m-d H:i:s')."' WHERE `alias`=?;",
  202. 's',array($this->alias)))
  203. return true;
  204. else
  205. return false;
  206. }
  207. /**
  208. * SELECT users from the database WHERE LIKE $alias
  209. * @param string $alias The aliases to search for ( LIKE '%$alias%' )
  210. * @param string $rType the return type for the users
  211. * @returns mixed the requested database return type
  212. */
  213. public static function get($alias, $rType="object") {
  214. $DB = new DB_MySQLi;
  215. if(isset($alias)) {
  216. $inputFilter = new Filters;
  217. $alias = $inputFilter->text($alias,true);
  218. //set return columns based on access level
  219. $access_level = Security::clearance();
  220. if($access_level & ACCESS_ADMIN)
  221. $columns = "`user_id`, `alias`,`nameFirst`,`nameLast`,`email`,`access_level`";
  222. else if($access_level & ACCESS_CREATE)
  223. $columns = "`user_id`, `alias`, `nameFirst`,`nameLast`";
  224. $results = $DB->get_rows("SELECT $columns FROM `users` WHERE `alias` LIKE CONCAT('%',?,'%') LIMIT 20;",
  225. 's',array($alias), $rType);
  226. } else {
  227. $results = $DB->get_rows("SELECT $columns FROM `users` LIMIT 20;",NULL,NULL,$rType);
  228. }
  229. return $results;
  230. }
  231. /**
  232. * Delete a user from the Database
  233. * @param int $user_id The user to delete
  234. * @return status
  235. */
  236. public static function delete($user_id) {
  237. //check for valid input and return error if not valid
  238. $inputFilter = new Filters;
  239. $user_id = $inputFilter->number($user_id);
  240. if($inputFilter->ERRORS()) return json_encode(array('status'=>"E_FILTER"));
  241. //establish database connection
  242. $DB = new DB_MySQLi;
  243. //delete user
  244. $DB->delete("DELETE FROM `users` WHERE `user_id`=?;",
  245. 'i',array($user_id));
  246. //close the database connection
  247. $DB->close();
  248. return json_encode(array('status'=>$DB->STATUS));
  249. }
  250. /**
  251. * Increase the access level of a user
  252. * @param int $user_id The user to increase access for
  253. * @return json_status with updated access level and title
  254. */
  255. public static function accessInc($user_id) {
  256. $status = "1";
  257. $inputFilter = new Filters;
  258. $user_id = $inputFilter->number($user_id);
  259. if($inputFilter->ERRORS()) return json_encode(array('status'=>"E_FILTERS"));
  260. //connect to Database
  261. $DB = new DB_MySQLi;
  262. //get current access_level
  263. if(!$user = $DB->get_row("SELECT `access_level` FROM `users` WHERE `user_id`=?;",
  264. 'i',array($user_id)))
  265. return json_encode(array('status'=>"E_ID"));
  266. $access_level = $user->access_level;
  267. //set new access level if below ADMIN ACCESS
  268. if($access_level & ACCESS_ADMIN) {
  269. //already an admin, can't reaise access any higher
  270. return json_encode(array('status'=>'0'));
  271. } else {
  272. if($access_level & ACCESS_CREATE) {
  273. //if user was a Creator, set to Admin
  274. $newAccess = $access_level | ACCESS_ADMIN;
  275. } else {
  276. if($access_level & ACCESS_BASIC) {
  277. //if user was Basic, set to Creator
  278. $newAccess = $access_level | ACCESS_CREATE;
  279. } else {
  280. if($access_level == ACCESS_NONE)
  281. //if user was unauthorized, set to BASIC ACCESS
  282. $newAccess = $access_level | ACCESS_BASIC;
  283. }
  284. }
  285. //update user's access level
  286. $DB->update("UPDATE `users` SET `access_level`=? WHERE `user_id`=?;",
  287. 'ii',array($newAccess,$user_id));
  288. }
  289. return json_encode(array('status'=>$status,'access'=>$newAccess,'title'=>getHumanAccess($newAccess)));
  290. }
  291. /**
  292. * Decrease the access level of a user
  293. * @param int $user_id The user to increase access for
  294. * @return json_status with updated access level and title
  295. */
  296. public static function accessDec($user_id) {
  297. $status = "1";
  298. $inputFilter = new Filters;
  299. $user_id = $inputFilter->number($user_id);
  300. if($inputFilter->ERRORS()) return json_encode(array('status'=>"E_FILTERS"));
  301. //connect to Database
  302. $DB = new DB_MySQLi;
  303. //get current access_level
  304. if(!$user = $DB->get_row("SELECT `access_level` FROM `users` WHERE `user_id`=?;",
  305. 'i',array($user_id)))
  306. return json_encode(array('status'=>"E_ID"));
  307. $access_level = $user->access_level;
  308. //set new access level if current is above 0
  309. if($access_level == ACCESS_NONE) {
  310. return json_encode(array('status'=>'0'));
  311. } else {
  312. if($access_level & ACCESS_ADMIN) {
  313. $newAccess = $access_level ^= ACCESS_ADMIN;
  314. } else {
  315. if($access_level & ACCESS_CREATE) {
  316. $newAccess = $access_level ^= ACCESS_CREATE;
  317. } else {
  318. if($access_level == ACCESS_BASIC)
  319. $newAccess = $access_level ^= ACCESS_BASIC;
  320. }
  321. }
  322. //update user's access level
  323. $status = $DB->update("UPDATE `users` SET `access_level`=? WHERE `user_id`=?;",
  324. 'ii',array($newAccess,$user_id));
  325. }
  326. echo json_encode(array('status'=>$status,'access'=>$newAccess,'title'=>getHumanAccess($newAccess)));
  327. }
  328. /**
  329. * Encrypt a password
  330. *@param string $pass password to encrypt
  331. *@param string $regTime the user's registration time
  332. *@return string encrypted password
  333. */
  334. public function encryptPassword($pass,$regTime) {
  335. //create salt from the sha1 of the user's registration time
  336. $salt = sha1($regTime);
  337. //md5 encrypt the salt+password, then sha1 that whole thing and return the encrypted password
  338. return sha1(md5($salt.$pass));
  339. }
  340. /** Set Authorized Session Variables */
  341. public function AUTH() {
  342. $_SESSION['auth'] = 1;
  343. $_SESSION['alias'] = $this->alias;
  344. $_SESSION['user_id'] = $this->user_id;
  345. $_SESSION['ip'] = $this->ip_address;
  346. $_SESSION['access_level'] = $this->access_level;
  347. }
  348. /** Removed Authorized Session Variables */
  349. public static function NOAUTH() {
  350. unset($_SESSION['auth']); //remove authentication
  351. unset($_SESSION['alias']); //unset username
  352. unset($_SESSION['user_id']); //unset user_id
  353. unset($_SESSION['ip']); //unset ip address
  354. unset($_SESSION['access_level']); //unset access_level
  355. }
  356. }
  357. ?>