1: <?php defined('_JOOS_CORE') or exit();
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17: class modelUsers extends joosModel
18: {
19: 20: 21: 22:
23: public $id;
24:
25: 26: 27: 28:
29: public $user_name;
30:
31: 32: 33: 34:
35: public $user_name_canonikal;
36:
37: 38: 39: 40:
41: public $real_name;
42:
43: 44: 45: 46:
47: public $email;
48:
49: 50: 51: 52:
53: public $openid;
54:
55: 56: 57: 58:
59: public $password;
60:
61: 62: 63: 64:
65: public $state;
66:
67: 68: 69: 70:
71: public $register_date;
72:
73: 74: 75: 76:
77: public $lastvisit_date;
78:
79: 80: 81: 82:
83: public $activation;
84:
85: 86: 87: 88:
89: public $bad_auth_count;
90: private static $user_instance;
91:
92: public function __construct()
93: {
94: parent::__construct('#__users', 'id');
95: }
96:
97: 98: 99: 100: 101:
102: public static function instance()
103: {
104: if (self::$user_instance === NULL) {
105:
106: $sessionCookieName = joosSession::session_cookie_name();
107: $sessioncookie = (string) joosRequest::cookies($sessionCookieName);
108:
109:
110: $token = new modelUsersTokens;
111:
112: $session = new modelUsersSession;
113: if ($sessioncookie && strlen($sessioncookie) == 32 && $sessioncookie != '-' && $session->load(joosSession::session_cookie_value($sessioncookie))) {
114: if ($session->user_id > 0) {
115: $user = new self;
116: $user->load($session->user_id);
117: self::$user_instance = $user;
118: } else {
119: self::$user_instance = self::get_guest();
120: }
121: } elseif ($token->check_auth_token()) {
122:
123:
124: $r = $token->create_session();
125:
126:
127: if ($r) {
128:
129: $user = new self;
130: $user->load($token->get_last_user_id());
131: self::$user_instance = $user;
132: } else {
133:
134: self::$user_instance = self::get_guest();
135: }
136: } else {
137: self::$user_instance = new self;
138: }
139: }
140:
141: return self::$user_instance;
142: }
143:
144: 145: 146: 147:
148: private static function get_guest()
149: {
150: $guest = new stdClass();
151: $guest->id = 0;
152: $guest->user_name = 'Гость';
153:
154: return $guest;
155: }
156:
157: public function check()
158: {
159: $this->filter();
160:
161: $query = "SELECT id FROM #__users WHERE user_name = " . $this->_db->get_quoted($this->user_name) . " AND id != " . (int) $this->id;
162: $xid = $this->_db->set_query($query)->load_result();
163: if ($xid && $xid != $this->id) {
164: $this->_error = 'Логин уже зарегистрирован';
165:
166: return false;
167: }
168:
169: $query = "SELECT id FROM #__users WHERE email = " . $this->_db->get_quoted($this->email) . " AND id != " . (int) $this->id;
170: $xid = $this->_db->set_query($query)->load_result();
171: if ($xid && $xid != $this->id) {
172: $this->_error = 'Email уже зарегистрирован';
173:
174: return false;
175: }
176:
177: if (!$this->validate()) {
178: $messages = $this->get_validation_error_messages();
179: foreach ($messages as $message) {
180: $this->_error .= $messages === false ? : implode('<br />', $message);
181: }
182:
183: return false;
184: }
185:
186: return true;
187: }
188:
189: protected function before_store()
190: {
191:
192: $this->update_password();
193:
194:
195: $this->user_name_canonikal = joosText::to_canonical($this->user_name);
196: }
197:
198: 199: 200: 201: 202:
203: protected function after_insert()
204: {
205:
206: $extra = new modelUsersExtra;
207: $extra->create($this->id);
208:
209: return true;
210: }
211:
212: protected function get_validate_rules()
213: {
214: return array(array('user_name', 'required', 'message' => 'Не указан логин пользователя'), array('user_name', 'string:5..50', 'message' => 'Длина логина быть от :min до :max символов'),
215: );
216: }
217:
218: 219: 220: 221: 222: 223: 224: 225: 226:
227: public static function check_password($input_password, $real_password)
228: {
229:
230: list($hash, $salt) = explode(':', $real_password);
231:
232: $cryptpass = md5($input_password . $salt);
233:
234:
235: if ($hash != $cryptpass) {
236: return false;
237: }
238:
239: return true;
240: }
241:
242: 243: 244: 245: 246: 247: 248: 249:
250: public static function prepare_password($password)
251: {
252: $salt = joosRandomizer::hash(16);
253: $crypt = md5($password . $salt);
254:
255: return $crypt . ':' . $salt;
256: }
257:
258: private function update_password()
259: {
260: if (!$this->id) {
261: $this->password = self::prepare_password($this->password);
262: $this->register_date = JCURRENT_SERVER_TIME;
263: } else {
264: $new_password = joosRequest::post('new_password', false);
265: if ($new_password) {
266: $this->password = self::prepare_password($new_password);
267: }
268: }
269: }
270:
271: 272: 273: 274:
275: public static function current()
276: {
277:
278: return joosCore::is_admin() ? joosCoreAdmin::user() : self::instance();
279: }
280:
281: 282: 283: 284: 285: 286: 287: 288: 289:
290: public static function login($user_name, $password = false, array $params = array())
291: {
292: $params += array('redirect' => true);
293:
294: $return = (string) joosRequest::param('return');
295: if ($return && !(strpos($return, 'com_registration') || strpos($return, 'com_login'))) {
296:
297: } elseif (isset($_SERVER['HTTP_REFERER'])) {
298: $return = $_SERVER['HTTP_REFERER'];
299: } else {
300: $return = JPATH_SITE;
301: }
302:
303: $user = new modelUsers;
304: $user->user_name = $user_name;
305: $user->find();
306:
307:
308: if (!$user->id) {
309: if (isset($params['return'])) {
310: return json_encode(array('error' => 'Такого пользователя нет'));
311: } else {
312: joosRoute::redirect($return, 'Такого пользователя нет');
313: }
314: }
315:
316:
317: if ($user->state == 0) {
318: if (isset($params['return'])) {
319: return json_encode(array('error' => _LOGIN_BLOCKED));
320: } else {
321: joosRoute::redirect($return, _LOGIN_BLOCKED);
322: }
323: }
324:
325:
326: if (!self::check_password($password, $user->password)) {
327: if (isset($params['return'])) {
328: return json_encode(array('error' => _LOGIN_INCORRECT));
329: } else {
330: joosRoute::redirect($return, _LOGIN_INCORRECT);
331: }
332: }
333:
334:
335: $session = new modelUsersSession;
336: $session->time = time();
337: $session->guest = 0;
338: $session->user_name = $user->user_name;
339: $session->user_id = $user->id;
340: $session->is_admin = 0;
341:
342: $session->generate_id();
343:
344: $session->store();
345:
346:
347: $sessionCookieName = joosSession::session_cookie_name();
348:
349: setcookie($sessionCookieName, $session->get_cookie(), false, '/', JPATH_COOKIE);
350:
351:
352: $query = "DELETE FROM #__users_session WHERE is_admin=0 AND session_id != " . $session->_db->get_quoted($session->session_id) . " AND user_id = " . (int) $user->id;
353: joosDatabase::instance()->set_query($query)->query();
354:
355:
356: $user->lastvisit_date = JCURRENT_SERVER_TIME;
357: $user->store();
358:
359: $token = new modelUsersTokens;
360: $token->generate_token($user->id);
361:
362: if (isset($params['return'])) {
363: return json_encode(array('user' => $user));
364: } else {
365: joosRoute::redirect($return);
366: }
367: }
368:
369: public static function logout()
370: {
371:
372: $sessionCookieName = joosSession::session_cookie_name();
373:
374: $sessioncookie = (string) joosRequest::cookies($sessionCookieName);
375:
376:
377: $sessionValueCheck = joosSession::session_cookie_value($sessioncookie);
378:
379: $lifetime = time() - 86400;
380: setcookie($sessionCookieName, ' ', $lifetime, '/', JPATH_COOKIE);
381:
382: $token = new modelUsersTokens;
383: $token->logout_me();
384:
385: $query = "DELETE FROM #__users_session WHERE session_id = " . joosDatabase::instance()->get_quoted($sessionValueCheck);
386:
387: return joosDatabase::instance()->set_query($query)->query();
388: }
389:
390:
391: public static function is_loged()
392: {
393: return (bool) modelUsers::current()->id != false;
394: }
395:
396: }
397:
398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410:
411: class modelUsersExtra extends joosModel
412: {
413: 414: 415:
416: public $user_id;
417:
418: 419: 420:
421: public $gender;
422:
423: 424: 425:
426: public $about;
427:
428: 429: 430:
431: public $location;
432:
433: 434: 435:
436: public $contacts;
437:
438: 439: 440:
441: public $birth_date;
442:
443: 444: 445:
446: public $interests;
447:
448: public function __construct()
449: {
450: parent::__construct('#__users_extra', 'user_id');
451: }
452:
453: public function check()
454: {
455: $this->filter(array('about'));
456:
457: return true;
458: }
459:
460: public function create($user_id)
461: {
462: $this->user_id = $user_id;
463: $this->_db->insert_object('#__users_extra', $this);
464: }
465:
466: }
467:
468: 469: 470: 471: 472: 473: 474: 475: 476: 477: 478: 479:
480: class modelUsersSession extends joosModel
481: {
482: 483: 484: 485:
486: public $session_id;
487:
488: 489: 490: 491:
492: public $user_name;
493:
494: 495: 496: 497:
498: public $time;
499:
500: 501: 502: 503:
504: public $guest;
505:
506: 507: 508: 509:
510: public $user_id;
511:
512: 513: 514: 515:
516: public $is_admin;
517:
518: 519: 520:
521: public function __construct()
522: {
523: parent::__construct('#__users_session', 'session_id');
524: }
525:
526: public function generate_id()
527: {
528: $failsafe = 20;
529: $randnum = 0;
530:
531: while ($failsafe--) {
532:
533: $randnum = joosRandomizer::hash(32);
534: $new_session_id = joosSession::session_cookie_value($randnum);
535:
536: $session_obj = new modelUsersSession;
537: $session_obj->session_id = $new_session_id;
538: if (!$session_obj->find()) {
539: break;
540: }
541:
542: }
543: $this->_session_cookie = $randnum;
544: $this->session_id = $new_session_id;
545: }
546:
547: public function get_cookie()
548: {
549: return $this->_session_cookie;
550: }
551:
552: }
553:
554: 555: 556: 557: 558: 559: 560: 561: 562: 563: 564: 565: 566: 567:
568: class modelUsersTokens extends joosModel
569: {
570: 571: 572: 573:
574: public $token;
575:
576: 577: 578: 579:
580: public $user_id;
581:
582: 583: 584: 585:
586: public $updated_at;
587:
588: 589: 590: 591:
592: public $user_related;
593:
594:
595: private static $_token_name = 'joostoken';
596: private static $_session_ttl = joosDateTime::WEEK;
597: private $_search_token_result;
598: private $_last_user_id;
599:
600: 601: 602:
603:
604: public function __construct()
605: {
606: parent::__construct('#__users_tokens', 'id');
607:
608:
609: $this->_search_token_result = NULL;
610: $this->_last_user_id = NULL;
611: }
612:
613: 614: 615:
616: public function generate_token($user_id)
617: {
618: $token_string = md5(joosRandomizer::hash(32) . $user_id . JCURRENT_SERVER_TIME);
619:
620:
621: $obj = new self;
622: $obj->user_id = (int) $user_id;
623: $obj->token = $token_string;
624:
625:
626: $obj->user_related = md5($this->get_related_string());
627: $obj->store();
628:
629:
630: joosCookie::set(self::$_token_name, $token_string, array('expires' => time() + self::$_session_ttl,));
631:
632: return true;
633: }
634:
635: 636: 637: 638:
639: private function get_related_string()
640: {
641: return sprintf('%s-%s-%s-%s', JPATH_COOKIE, joosRequest::server('HTTP_ACCEPT_ENCODING'), joosRequest::server('HTTP_USER_AGENT'), joosRequest::server('HTTP_ACCEPT_LANGUAGE'));
642: }
643:
644: 645: 646: 647: 648:
649: public function check_auth_token()
650: {
651: $user_token = joosCookie::get(self::$_token_name, false);
652:
653:
654: if ($user_token == false) {
655: return false;
656: }
657:
658:
659: $database = joosDatabase::instance();
660: $database->set_query("SELECT t.*,u.user_name FROM #__users_tokens AS t INNER JOIN #__users AS u ON u.id=t.user_id WHERE t.token=" . $database->get_quoted($user_token));
661: $result = $database->load_object_list();
662:
663:
664: if (0 == count($result)) {
665:
666:
667: joosCookie::delete(self::$_token_name);
668:
669: return false;
670: }
671:
672:
673: $result = $result[0];
674: if ($result->user_related != md5($this->get_related_string())) {
675:
676:
677: return false;
678: }
679:
680:
681: $this->_search_token_result = $result;
682:
683: return true;
684: }
685:
686: 687: 688: 689:
690: public function create_session()
691: {
692: if (!$this->_search_token_result) {
693: return false;
694: }
695:
696: $session = new modelUsersSession;
697: $session->time = time();
698: $session->guest = 0;
699: $session->user_name = $this->_search_token_result->user_name;
700: $session->user_id = $this->_search_token_result->user_id;
701: $session->is_admin = 0;
702:
703:
704: $session->generate_id();
705:
706:
707: if (!$session->store()) {
708: return false;
709: }
710:
711:
712: $sessionCookieName = joosSession::session_cookie_name();
713:
714:
715: joosCookie::set($sessionCookieName, $session->get_cookie(), array('expires' => '+1 day'
716: ));
717:
718:
719: $query = "UPDATE #__users_tokens SET updated_at = '" . JCURRENT_SERVER_TIME . "' WHERE token=" . joosDatabase::instance()->get_quoted($this->_search_token_result->token);
720: joosDatabase::instance()->set_query($query)->query();
721:
722:
723: $this->_last_user_id = $this->_search_token_result->user_id;
724:
725:
726: $this->delete_old_tokens();
727:
728: return true;
729: }
730:
731: 732: 733: 734:
735: public function get_last_user_id()
736: {
737: return $this->_last_user_id;
738: }
739:
740: 741: 742: 743:
744: private function delete_old_tokens()
745: {
746: if (rand(1, 10) == 4) {
747: return;
748: }
749:
750: $past = time() - self::$_session_ttl;
751: $query = "DELETE FROM #__users_tokens WHERE updated_at < '" . (int) $past . "'";
752: joosDatabase::instance()->set_query($query)->query();
753: }
754:
755: 756: 757: 758:
759: public function logout_me()
760: {
761: $user_token = joosCookie::get(self::$_token_name, false);
762: if (!$user_token) {
763: return;
764: }
765:
766:
767: joosCookie::delete(self::$_token_name);
768:
769:
770: $query = "DELETE FROM #__users_tokens WHERE token=" . joosDatabase::instance()->get_quoted($user_token);
771:
772: return joosDatabase::instance()->set_query($query)->query();
773: }
774:
775: }
776: