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); |
||
0 ignored issues
–
show
The return type of
return static::findOne($id); (yii\db\ActiveRecordInterface|array|null ) is incompatible with the return type declared by the interface yii\web\IdentityInterface::findIdentity of type yii\web\IdentityInterface|null .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
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.