PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/public/modules/user/model/User.php

https://github.com/redokes/Framework
PHP | 418 lines | 331 code | 49 blank | 38 comment | 47 complexity | 9a535e5fad5be9f1fa743cd94d7f3905 MD5 | raw file
  1. <?php
  2. class User_Model_User extends Redokes_Model_Model {
  3. public $tableClassName = 'User_Model_Db_User';
  4. public $requiredStringFields = array(
  5. 'email' => 'Email'
  6. );
  7. public function remember() {
  8. if ($this->row->userId == self::getMyId()) {
  9. // make sure whole row is loaded
  10. if (!strlen($this->row->password)) {
  11. $this->loadRow($this->row->userId);
  12. }
  13. // password is now triple salted. it is stored as a salt and we are double salting it
  14. $tripleSalt = $this->salt($this->salt($this->row->password));
  15. setcookie(md5('rememberEmail'), $this->row->email, time() + 60 * 60 * 24 * 7, '/');
  16. setcookie(md5('rememberPassword'), $tripleSalt, time() + 60 * 60 * 24 * 7, '/');
  17. }
  18. }
  19. public function loginFromCookie() {
  20. if (isset($_COOKIE[md5('rememberEmail')]) && isset($_COOKIE[md5('rememberPassword')])) {
  21. $email = $_COOKIE[md5('rememberEmail')];
  22. $select = $this->table->select()->where('email = ?', $email);
  23. $row = $this->table->fetchRow($select);
  24. if ($row) {
  25. // value in cookie is triple salted password
  26. // value in db is single salted. need to double salt
  27. if ($_COOKIE[md5('rememberPassword')] == $this->salt($this->salt($row->password))) {
  28. $this->row->email = $_COOKIE[md5('rememberEmail')];
  29. $this->row->password = $row->password;
  30. return $this->login(false);
  31. }
  32. }
  33. }
  34. return false;
  35. }
  36. public function loadSessionUser() {
  37. if (isset($_SESSION['user']) && isset($_SESSION['user']['userId'])) {
  38. $this->loadRow($_SESSION['user']['userId']);
  39. }
  40. }
  41. public function login($needToSalt = true) {
  42. // check if the password needs to be salted or if it is an unsalted password
  43. if ($needToSalt) {
  44. $this->row->password = $this->salt($this->row->password);
  45. }
  46. // try to load the user row with these credentials
  47. $this->loadRow(array(
  48. 'email' => $this->row->email,
  49. 'password' => $this->row->password
  50. ));
  51. // check if this was a successful user/pw combo
  52. if ($this->row) {
  53. $_SESSION['user'] = array(
  54. 'userId' => $this->row->userId,
  55. 'email' => $this->row->email
  56. );
  57. return true;
  58. }
  59. return false;
  60. }
  61. public function logout() {
  62. if (!$this->row->userId) {
  63. $this->loadSessionUser();
  64. }
  65. $_SESSION['user'] = array();
  66. setcookie(md5('rememberEmail'), false, time() - 60, '/');
  67. setcookie(md5('rememberPassword'), false, time() - 60, '/');
  68. }
  69. public function validate() {
  70. // make sure email is unique
  71. $query = "SELECT COUNT(*) total FROM user WHERE email = '{$this->row->email}' AND userId <> '{$this->row->userId}'";
  72. $row = $this->table->fetchRow($query);
  73. if ($row['total']) {
  74. $this->addError("Please choose a different email address. Email is already in use");
  75. }
  76. // if (!valid_email($this->row['email'])) {
  77. // $this->addError("Please enter a valid email address");
  78. // }
  79. if (strlen($this->row->password) < 5) {
  80. $this->addError("Password must be 5 characters or longer");
  81. }
  82. $confirmPassword = Redokes_Controller_Front::getInstance()->getParam('confirmPassword');
  83. if ($this->row->password != $confirmPassword) {
  84. $this->addError("Passwords don't match. Please confirm your password.");
  85. }
  86. parent::validate();
  87. return $this->errors;
  88. // don't let a non papercut user edit a papercut user
  89. // if ($this->row['userId']) {
  90. //
  91. // // check if edited user has papercut access
  92. // if (User_Class_User::hasAccess('papercut', 0, $this->row['userId'])) {
  93. //
  94. // // check if the user doing the editing has papercut access
  95. // if (!User_Class_User::hasAccess('papercut')) {
  96. // $this->addError('You do not have access to edit a Papercut user account');
  97. // }
  98. // }
  99. // }
  100. // make sure email is unique
  101. $query = "SELECT COUNT(*) total FROM user WHERE email = '{$this->row['email']}' AND userId <> '{$this->row['userId']}'";
  102. $rows = $db->fetchAll($query);
  103. $numRows = count($rows);
  104. if ($numRows) {
  105. if ($rows[0]['total']) {
  106. $this->addError("Please choose a different email address. Email is already in use");
  107. }
  108. }
  109. // check length
  110. if (!valid_email($this->row['email'])) {
  111. $this->addError("Please enter a valid email address");
  112. }
  113. if (!$this->row['userId']) {
  114. // make sure passwords match
  115. if ($this->row['password'] != $this->cpassword) {
  116. $this->addError("Please retype your password.");
  117. }
  118. if (strlen($this->row['password']) < 5) {
  119. $this->addError("Password must be atleast 5 characters.");
  120. }
  121. }
  122. // clean access ids
  123. $accessIds = array();
  124. for ($i = 0; $i < count($this->accessIds); $i++) {
  125. if (intval($this->accessIds[$i])) {
  126. $accessIds[] = intval($this->accessIds[$i]);
  127. }
  128. }
  129. $this->accessIds = $accessIds;
  130. // clean group ids
  131. $groupIds = array();
  132. for ($i = 0; $i < count($this->groupIds); $i++) {
  133. if (intval($this->groupIds[$i])) {
  134. $groupIds[] = intval($this->groupIds[$i]);
  135. }
  136. }
  137. $this->groupIds = $groupIds;
  138. return $this->errors;
  139. }
  140. public function beforeInsert() {
  141. $this->row->password = $this->salt($this->row->password);
  142. }
  143. function delete($doAudit = true) {
  144. return;
  145. $db = FrontController::getInstance()->getDbAdapter('sharedb');
  146. // remove access relation
  147. User_Class_UserAccess::clearUserAccess($this->row['userId']);
  148. // remove group relation
  149. User_Class_UserXGroup::clearGroups($this->row['userId']);
  150. // remove addresses
  151. $db->delete('user_address', 'userId = ' . $db->quote($this->row['userId']));
  152. parent::delete($doAudit);
  153. }
  154. public static function hasAccess($title, $primaryKey = 0, $userId = 0) {
  155. //$db = FrontController::getInstance()->getDbAdapter();
  156. return true;
  157. // sanitize data
  158. $primaryKey = intval($primaryKey);
  159. $title = trim($db->quote($title), "'");
  160. if (!$userId) {
  161. $userId = self::getMyId();
  162. }
  163. // get all access ids
  164. $accessToCheck = array(
  165. 'papercut',
  166. 'admin',
  167. $title
  168. );
  169. // add admin title to list (adding "herp" if looking for "herp.derp")
  170. $adminTitle = reset(explode('.', $title));
  171. if (strtolower($adminTitle) != strtolower($title)) {
  172. $accessToCheck[] = $adminTitle;
  173. }
  174. // if checking for admin access
  175. if ($title == 'admin') {
  176. $accessToCheck = array(
  177. 'papercut',
  178. 'admin'
  179. );
  180. }
  181. // if checking for papercut access
  182. if ($title == 'papercut') {
  183. $accessToCheck = array(
  184. 'papercut'
  185. );
  186. }
  187. $accessTitlesFound = array();
  188. $accessSql = array_to_sql($accessToCheck);
  189. $accessIds = array();
  190. $query = "SELECT * FROM site_access WHERE title IN ($accessSql)";
  191. $rows = $db->fetchAll($query);
  192. $numRows = count($rows);
  193. for ($i = 0; $i < $numRows; $i++) {
  194. $accessIds[] = $rows[$i]['accessId'];
  195. $accessTitlesFound[] = strtolower($rows[$i]['title']);
  196. }
  197. // commented this block for now..
  198. // access levels probably dont need to be created ever
  199. // on the access check.. just the access create
  200. //Make sure all access levels exist
  201. /*
  202. foreach ($accessToCheck as $accessTitle){
  203. if(!in_array(strtolower($accessTitle), $accessTitlesFound)){
  204. //Create this access level and add it to accessIds array
  205. $access = new User_Class_Access();
  206. $access->loadRow($accessTitle, 'title');
  207. if(!$access->row[$access->primaryKey]){
  208. $access->setRow(array(
  209. 'title' => $accessTitle
  210. ,'display' => ucfirst($accessTitle)
  211. ));
  212. $access->process();
  213. }
  214. $accessTitlesFound[] = strtolower($accessTitle);
  215. $accessIds[] = $access->row[$access->primaryKey];
  216. }
  217. }
  218. */
  219. if (count($accessIds)) {
  220. $accessIdsSql = implode(',', $accessIds);
  221. // check for permission
  222. $query = "SELECT COUNT(*) num FROM site_users_x_access WHERE userId = $userId AND primaryKey IN(0, $primaryKey) AND accessId IN ($accessIdsSql)";
  223. $rows = $db->fetchAll($query);
  224. $numRows = count($rows);
  225. // user has direct user permission so don't need group lookup
  226. if ($numRows) {
  227. if ($rows[0]['num']) {
  228. return true;
  229. }
  230. }
  231. }
  232. // look up users groups and permissions for the groups
  233. // get group ids
  234. $query = "SELECT groupId FROM site_users_x_groups WHERE userId = $userId";
  235. $rows = $db->fetchAll($query);
  236. $numRows = count($rows);
  237. if ($numRows) {
  238. $groupIds = array();
  239. for ($i = 0; $i < $numRows; $i++) {
  240. $groupIds[] = $rows[$i]['groupId'];
  241. }
  242. $groupIdsSql = implode(',', $groupIds);
  243. // check group permissions
  244. $query = "SELECT COUNT(*) num FROM site_users_groups_x_access WHERE groupId IN($groupIdsSql) AND primaryKey IN(0, $primaryKey) AND accessId IN ($accessIdsSql)";
  245. $rows = $db->fetchAll($query);
  246. $numRows = count($rows);
  247. if ($numRows) {
  248. if ($rows[0]['num']) {
  249. return true;
  250. }
  251. }
  252. }
  253. return false;
  254. }
  255. public function compareNewPassword($pw) {
  256. if ($this->salt($pw) == $this->row->password) {
  257. return true;
  258. }
  259. return false;
  260. }
  261. public function setNewPassword($pw) {
  262. $this->row->password = $this->salt($pw);
  263. $this->row->save();
  264. }
  265. public static function getMyId() {
  266. $userId = 0;
  267. if (isset($_SESSION['user'])) {
  268. if (isset($_SESSION['user']['userId'])) {
  269. $userId = $_SESSION['user']['userId'];
  270. }
  271. }
  272. return $userId;
  273. }
  274. public static function isLoggedIn() {
  275. if (self::getMyId()) {
  276. return true;
  277. }
  278. else {
  279. return false;
  280. }
  281. }
  282. public static function getMyEmail() {
  283. if (User_Model_User::getMyId()) {
  284. return $_SESSION['user']['email'];
  285. }
  286. }
  287. public static function notAuthorized() {
  288. return;
  289. redirect_to('/simon/index/unauthorized');
  290. }
  291. public static function requireAccess($title, $primaryKey = 0) {
  292. return;
  293. if (!self::hasAccess($title, $primaryKey)) {
  294. self::notAuthorized();
  295. }
  296. }
  297. public function authenticate($needToSalt = true) {
  298. if ($needToSalt) {
  299. $this->row->password = $this->salt($this->row->password);
  300. }
  301. $this->loadRow(array(
  302. 'email' => $this->row->email,
  303. 'password' => $this->row->password,
  304. 'confirmed' => 1
  305. ));
  306. if ($this->row->userId) {
  307. return true;
  308. }
  309. return false;
  310. }
  311. public function confirm($hash) {
  312. return;
  313. $userInvite = new Site_Class_UserInvite();
  314. $site = FrontController::getInstance()->getSite();
  315. $userInvite->loadRow(array(
  316. 'confirmationHash' => $hash,
  317. 'siteId' => $site->row['siteId']
  318. ));
  319. // if this is a valid invite for this site
  320. if ($userInvite->row['userInviteId'] && $userInvite->row['tsExpire'] >= time()) {
  321. $this->loadRow($userInvite->row['email'], 'email');
  322. $this->row['confirmed'] = 1;
  323. $this->update(false);
  324. // add site access
  325. $userSite = new Site_Class_UserSite();
  326. $userSite->setRow(array(
  327. 'userId' => $this->row['userId'],
  328. 'siteId' => $site->row['siteId']
  329. ));
  330. $userSite->process();
  331. $userInvite->delete();
  332. return true;
  333. }
  334. return false;
  335. }
  336. public function sendSignupEmail($hash) {
  337. return;
  338. // send the email
  339. $email = new Papercut_Email();
  340. $subject = 'Echo Bear site registration request';
  341. $siteUrl = 'http://' . $_SERVER['HTTP_HOST'];
  342. $inviteUrl = 'http://' . $_SERVER['HTTP_HOST'] . '/user/index/confirm/' . $hash;
  343. $content = 'You have request to create an account on ' . $siteUrl . '<br />';
  344. $content .= '<a href="'.$inviteUrl.'">Click here to set up your account</a>';
  345. $email->sendEmailTemplate($this->row['email'], $subject, $content);
  346. }
  347. public function sendInvite($isInvite = true) {
  348. if ($this->row->email) {
  349. return;
  350. $site = FrontController::getInstance()->getSite();
  351. $userInvite = new Site_Class_UserInvite();
  352. $userInvite->sendTo($this->row->email, $isInvite);
  353. }
  354. }
  355. }