1: <?php
2:
3: /*****************************************************************************************
4: * X2Engine Open Source Edition is a customer relationship management program developed by
5: * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
6: *
7: * This program is free software; you can redistribute it and/or modify it under
8: * the terms of the GNU Affero General Public License version 3 as published by the
9: * Free Software Foundation with the addition of the following permission added
10: * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11: * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
12: * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13: *
14: * This program is distributed in the hope that it will be useful, but WITHOUT
15: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16: * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17: * details.
18: *
19: * You should have received a copy of the GNU Affero General Public License along with
20: * this program; if not, see http://www.gnu.org/licenses or write to the Free
21: * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22: * 02110-1301 USA.
23: *
24: * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
25: * California 95067, USA. or at email address [email protected].
26: *
27: * The interactive user interfaces in modified source and object code versions
28: * of this program must display Appropriate Legal Notices, as required under
29: * Section 5 of the GNU Affero General Public License version 3.
30: *
31: * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32: * these Appropriate Legal Notices must retain the display of the "Powered by
33: * X2Engine" logo. If the display of the logo is not reasonably feasible for
34: * technical reasons, the Appropriate Legal Notices must display the words
35: * "Powered by X2Engine".
36: *****************************************************************************************/
37:
38: /**
39: * The data needed to identity a user.
40: *
41: * It contains the authentication method that checks if the provided data can
42: * identity the user.
43: * @package application.components
44: */
45: class UserIdentity extends CUserIdentity {
46:
47: const ERROR_DISABLED = 3;
48:
49: private $_id;
50: private $_name;
51: private $_userModel;
52:
53: public function authenticate($google = false) {
54: $user = $this->getUserModel();
55: $isRealUser = $user instanceof User;
56:
57: if ($isRealUser) {
58: $this->username = $user->username;
59: if ((integer) $user->status === User::STATUS_INACTIVE) {
60: $this->errorCode = self::ERROR_DISABLED;
61: return false;
62: }
63: }
64:
65: if (!$isRealUser) { // username not found
66: $this->errorCode = self::ERROR_USERNAME_INVALID;
67: } elseif ($google) { // Completely bypasses password-based authentication
68: $this->errorCode = self::ERROR_NONE;
69: $this->_id = $user->id;
70: return true;
71: } else {
72: if ($user->status == 0) {
73: // User has been disabled
74: $this->errorCode = self::ERROR_DISABLED;
75: return false;
76: }
77: $reEncrypt = false;
78: $isValid = false;
79: if(PasswordUtil::validatePassword($this->password, $user->password)){
80: $isValid = true;
81: } else if (PasswordUtil::slowEquals(md5($this->password), $user->password)){
82: //Oldest format
83: $isValid = true;
84: $reEncrypt = true;
85: } else if (PasswordUtil::slowEquals(crypt($this->password, '$5$rounds=32678$' . $user->password), '$5$rounds=32678$' . $user->password)){
86: //Old format
87: $isValid = true;
88: $reEncrypt = true;
89: }
90: if($isValid){
91: $this->errorCode = self::ERROR_NONE;
92: $this->_id = $user->id;
93: if ($reEncrypt) {
94: $user->password = PasswordUtil::createHash($this->password);
95: $user->update(array('password'));
96: }
97: }else{
98: $this->errorCode = self::ERROR_PASSWORD_INVALID;
99: }
100: }
101:
102: return $this->errorCode === self::ERROR_NONE;
103: }
104:
105: public function getId() {
106: return $this->_id;
107: }
108:
109: public function getUserModel() {
110: if (!isset($this->_userModel)) {
111: $this->_userModel = User::model()->findByAlias($this->username);
112: }
113: return $this->_userModel;
114: }
115:
116: }
117: