This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace yii2mod\user\models; |
||
4 | |||
5 | use Yii; |
||
6 | use yii\base\NotSupportedException; |
||
7 | use yii\behaviors\TimestampBehavior; |
||
8 | use yii\db\ActiveRecord; |
||
9 | use yii\helpers\ArrayHelper; |
||
10 | use yii\web\IdentityInterface; |
||
11 | use yii2mod\user\models\enums\UserStatus; |
||
12 | use yii2mod\user\traits\EventTrait; |
||
13 | |||
14 | /** |
||
15 | * Class UserModel |
||
16 | * |
||
17 | * @property int $id |
||
18 | * @property string $username |
||
19 | * @property string $password_hash |
||
20 | * @property string $password_reset_token |
||
21 | * @property string $email |
||
22 | * @property string $auth_key |
||
23 | * @property int $status |
||
24 | * @property int $created_at |
||
25 | * @property int $updated_at |
||
26 | * @property int $last_login |
||
27 | * @property string $password write-only password |
||
28 | */ |
||
29 | class UserModel extends ActiveRecord implements IdentityInterface |
||
30 | { |
||
31 | use EventTrait; |
||
32 | |||
33 | /** |
||
34 | * Event is triggered before creating a user. |
||
35 | * Triggered with \yii2mod\user\events\CreateUserEvent. |
||
36 | */ |
||
37 | const BEFORE_CREATE = 'beforeCreate'; |
||
38 | |||
39 | /** |
||
40 | * Event is triggered after creating a user. |
||
41 | * Triggered with \yii2mod\user\events\CreateUserEvent. |
||
42 | */ |
||
43 | const AFTER_CREATE = 'afterCreate'; |
||
44 | |||
45 | /** |
||
46 | * @var string plain password |
||
47 | */ |
||
48 | public $plainPassword; |
||
49 | |||
50 | /** |
||
51 | * @inheritdoc |
||
52 | */ |
||
53 | public static function tableName() |
||
54 | { |
||
55 | return '{{%user}}'; |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * @inheritdoc |
||
60 | */ |
||
61 | View Code Duplication | public function rules() |
|
0 ignored issues
–
show
|
|||
62 | { |
||
63 | return [ |
||
64 | [['username', 'email'], 'required'], |
||
65 | ['email', 'unique', 'message' => Yii::t('yii2mod.user', 'This email address has already been taken.')], |
||
66 | ['username', 'unique', 'message' => Yii::t('yii2mod.user', 'This username has already been taken.')], |
||
67 | ['username', 'string', 'min' => 2, 'max' => 255], |
||
68 | ['email', 'email'], |
||
69 | ['email', 'string', 'max' => 255], |
||
70 | ['plainPassword', 'string', 'min' => 6], |
||
71 | ['plainPassword', 'required', 'on' => 'create'], |
||
72 | ['status', 'default', 'value' => UserStatus::ACTIVE], |
||
73 | ['status', 'in', 'range' => UserStatus::getConstantsByName()], |
||
74 | ]; |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * @inheritdoc |
||
79 | */ |
||
80 | public function attributeLabels() |
||
81 | { |
||
82 | return [ |
||
83 | 'username' => Yii::t('yii2mod.user', 'Username'), |
||
84 | 'email' => Yii::t('yii2mod.user', 'Email'), |
||
85 | 'status' => Yii::t('yii2mod.user', 'Status'), |
||
86 | 'created_at' => Yii::t('yii2mod.user', 'Registration time'), |
||
87 | 'last_login' => Yii::t('yii2mod.user', 'Last login'), |
||
88 | 'plainPassword' => Yii::t('yii2mod.user', 'Password'), |
||
89 | ]; |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * @inheritdoc |
||
94 | */ |
||
95 | public function behaviors() |
||
96 | { |
||
97 | return [ |
||
98 | TimestampBehavior::class, |
||
99 | ]; |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Create user |
||
104 | * |
||
105 | * @return null|UserModel the saved model or null if saving fails |
||
106 | * |
||
107 | * @throws \Exception |
||
108 | */ |
||
109 | public function create() |
||
110 | { |
||
111 | $transaction = $this->getDb()->beginTransaction(); |
||
112 | |||
113 | try { |
||
114 | $event = $this->getCreateUserEvent($this); |
||
115 | $this->trigger(self::BEFORE_CREATE, $event); |
||
116 | |||
117 | $this->setPassword($this->plainPassword); |
||
118 | $this->generateAuthKey(); |
||
119 | |||
120 | if (!$this->save()) { |
||
121 | $transaction->rollBack(); |
||
122 | |||
123 | return null; |
||
124 | } |
||
125 | |||
126 | $this->trigger(self::AFTER_CREATE, $event); |
||
127 | |||
128 | $transaction->commit(); |
||
129 | |||
130 | return $this; |
||
131 | } catch (\Exception $e) { |
||
132 | $transaction->rollBack(); |
||
133 | Yii::warning($e->getMessage()); |
||
134 | throw $e; |
||
135 | } |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * @inheritdoc |
||
140 | */ |
||
141 | public static function findIdentity($id) |
||
142 | { |
||
143 | return static::findOne($id); |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * @inheritdoc |
||
148 | */ |
||
149 | public static function findIdentityByAccessToken($token, $type = null) |
||
150 | { |
||
151 | throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Finds user (with active status) by username |
||
156 | * |
||
157 | * @param string $username |
||
158 | * |
||
159 | * @return static|null |
||
160 | */ |
||
161 | public static function findByUsername($username) |
||
162 | { |
||
163 | return static::findOne(['username' => $username, 'status' => UserStatus::ACTIVE]); |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Finds user by email |
||
168 | * |
||
169 | * @param $email |
||
170 | * |
||
171 | * @return null|static |
||
172 | */ |
||
173 | public static function findByEmail($email) |
||
174 | { |
||
175 | return static::findOne(['email' => $email]); |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Finds user by password reset token |
||
180 | * |
||
181 | * @param string $token password reset token |
||
182 | * |
||
183 | * @return static|null |
||
184 | */ |
||
185 | public static function findByPasswordResetToken($token) |
||
186 | { |
||
187 | if (!static::isPasswordResetTokenValid($token)) { |
||
188 | return null; |
||
189 | } |
||
190 | |||
191 | return static::findOne([ |
||
192 | 'password_reset_token' => $token, |
||
193 | 'status' => UserStatus::ACTIVE, |
||
194 | ]); |
||
195 | } |
||
196 | |||
197 | /** |
||
198 | * Finds out if password reset token is valid |
||
199 | * |
||
200 | * @param string $token password reset token |
||
201 | * |
||
202 | * @return bool |
||
203 | */ |
||
204 | public static function isPasswordResetTokenValid($token) |
||
205 | { |
||
206 | if (empty($token)) { |
||
207 | return false; |
||
208 | } |
||
209 | |||
210 | $timestamp = (int) substr($token, strrpos($token, '_') + 1); |
||
211 | $expire = ArrayHelper::getValue(Yii::$app->params, 'user.passwordResetTokenExpire', 3600); |
||
212 | |||
213 | return $timestamp + $expire >= time(); |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * @inheritdoc |
||
218 | */ |
||
219 | public function getId() |
||
220 | { |
||
221 | return $this->getPrimaryKey(); |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * @inheritdoc |
||
226 | */ |
||
227 | public function getAuthKey() |
||
228 | { |
||
229 | return $this->auth_key; |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * @inheritdoc |
||
234 | */ |
||
235 | public function validateAuthKey($authKey) |
||
236 | { |
||
237 | return $this->getAuthKey() === $authKey; |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * Validates password |
||
242 | * |
||
243 | * @param string $password password to validate |
||
244 | * |
||
245 | * @return bool if password provided is valid for current user |
||
246 | */ |
||
247 | public function validatePassword($password) |
||
248 | { |
||
249 | return Yii::$app->getSecurity()->validatePassword($password, $this->password_hash); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Generates password hash from password and sets it to the model |
||
254 | * |
||
255 | * @param string $password |
||
256 | */ |
||
257 | public function setPassword($password) |
||
258 | { |
||
259 | $this->password_hash = Yii::$app->getSecurity()->generatePasswordHash($password); |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * Generates "remember me" authentication key |
||
264 | */ |
||
265 | public function generateAuthKey() |
||
266 | { |
||
267 | $this->auth_key = Yii::$app->getSecurity()->generateRandomString(); |
||
268 | } |
||
269 | |||
270 | /** |
||
271 | * Generates new password reset token |
||
272 | */ |
||
273 | public function generatePasswordResetToken() |
||
274 | { |
||
275 | $this->password_reset_token = Yii::$app->getSecurity()->generateRandomString() . '_' . time(); |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * Removes password reset token |
||
280 | */ |
||
281 | public function removePasswordResetToken() |
||
282 | { |
||
283 | $this->password_reset_token = null; |
||
284 | } |
||
285 | |||
286 | /** |
||
287 | * @param $lastLogin |
||
288 | */ |
||
289 | public function setLastLogin($lastLogin) |
||
290 | { |
||
291 | $this->last_login = $lastLogin; |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Update last login |
||
296 | */ |
||
297 | public function updateLastLogin() |
||
298 | { |
||
299 | $this->updateAttributes(['last_login' => time()]); |
||
300 | } |
||
301 | |||
302 | /** |
||
303 | * Resets password. |
||
304 | * |
||
305 | * @param string $password |
||
306 | * |
||
307 | * @return bool |
||
308 | */ |
||
309 | public function resetPassword($password) |
||
310 | { |
||
311 | $this->setPassword($password); |
||
312 | |||
313 | return $this->save(true, ['password_hash']); |
||
314 | } |
||
315 | } |
||
316 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.