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 app\models\entity; |
||
4 | |||
5 | use Yii; |
||
6 | use yii\base\NotSupportedException; |
||
7 | use yii\db\ActiveRecord; |
||
8 | use yii\web\IdentityInterface; |
||
9 | use yii\filters\RateLimitInterface; |
||
10 | use yii\behaviors\TimestampBehavior; |
||
11 | |||
12 | /** |
||
13 | * This is the model class for table "{{%user}}" |
||
14 | * |
||
15 | * @property integer $id |
||
16 | * @property string $email |
||
17 | * @property string $password |
||
18 | * @property string $password_reset_token |
||
19 | * @property string $email_confirm_token |
||
20 | * @property string $auth_key |
||
21 | * @property string $date_confirm |
||
22 | * @property string $date_create |
||
23 | * @property string $date_update |
||
24 | * @property string $date_login |
||
25 | * @property integer $ip |
||
26 | * @property string $role_name |
||
27 | * @property integer $status |
||
28 | * |
||
29 | * @property AuthItem $role |
||
30 | * @property UserProfile $profile |
||
31 | * @property UserProvider[] $providers |
||
32 | */ |
||
33 | class User extends \yii\db\ActiveRecord implements RateLimitInterface, IdentityInterface |
||
34 | { |
||
35 | const STATUS_DELETED = 0; |
||
36 | const STATUS_ACTIVE = 1; |
||
37 | const STATUS_BLOCKED = 2; |
||
38 | |||
39 | const ROLE_SUPERUSER = 'SuperUser'; |
||
40 | |||
41 | /** |
||
42 | * @var string |
||
43 | */ |
||
44 | public $passwordNew; |
||
45 | |||
46 | /** |
||
47 | * @inheritdoc |
||
48 | */ |
||
49 | 111 | public static function tableName() |
|
50 | { |
||
51 | 111 | return '{{%user}}'; |
|
52 | } |
||
53 | |||
54 | /** |
||
55 | * @inheritdoc |
||
56 | */ |
||
57 | 43 | public function attributeLabels() |
|
58 | { |
||
59 | return [ |
||
60 | 43 | 'id' => Yii::t('app', 'ID'), |
|
61 | 43 | 'email' => Yii::t('app', 'Email'), |
|
62 | 43 | 'password' => Yii::t('app', 'Password'), |
|
63 | 43 | 'date_create' => Yii::t('app', 'Date create'), |
|
64 | 43 | 'date_update' => Yii::t('app', 'Date update'), |
|
65 | 43 | 'date_login' => Yii::t('app', 'Last login'), |
|
66 | 43 | 'ip' => Yii::t('app', 'IP'), |
|
67 | 43 | 'role_name' => Yii::t('app', 'Role'), |
|
68 | 43 | 'status' => Yii::t('app', 'Status'), |
|
69 | 43 | ||
70 | 'passwordNew' => Yii::t('app', 'New password'), |
||
71 | 43 | ]; |
|
72 | } |
||
73 | |||
74 | /** |
||
75 | * @inheritdoc |
||
76 | */ |
||
77 | public function behaviors() |
||
78 | 74 | { |
|
79 | return [ |
||
80 | [ |
||
81 | 'class' => TimestampBehavior::class, |
||
82 | 74 | 'createdAtAttribute' => 'date_create', |
|
83 | 74 | 'updatedAtAttribute' => 'date_update', |
|
84 | 74 | 'value' => new \yii\db\Expression('NOW()'), |
|
85 | 74 | ], |
|
86 | ]; |
||
87 | } |
||
88 | |||
89 | /** |
||
90 | * @inheritdoc |
||
91 | */ |
||
92 | public function events() |
||
93 | { |
||
94 | return [ |
||
95 | ActiveRecord::EVENT_BEFORE_DELETE => 'beforeDelete', |
||
96 | ]; |
||
97 | } |
||
98 | |||
99 | public function transactions() |
||
100 | { |
||
101 | 9 | return [ |
|
102 | 'create' => self::OP_ALL, |
||
103 | 'update' => self::OP_ALL, |
||
104 | 9 | 'delete' => self::OP_ALL, |
|
105 | 9 | ]; |
|
106 | 9 | } |
|
107 | |||
108 | public function getRateLimit($request, $action) |
||
109 | { |
||
110 | return [Yii::$app->params['user.rateLimitMax'], Yii::$app->params['user.rateLimitTime']]; |
||
111 | } |
||
112 | |||
113 | 9 | public function loadAllowance($request, $action) |
|
114 | { |
||
115 | 9 | return [$this->allowance, $this->allowance_updated_at]; |
|
0 ignored issues
–
show
The property
allowance_updated_at does not exist on object<app\models\entity\User> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
116 | } |
||
117 | |||
118 | public function saveAllowance($request, $action, $allowance, $timestamp) |
||
119 | { |
||
120 | $this->allowance = $allowance; |
||
0 ignored issues
–
show
The property
allowance does not exist on object<app\models\entity\User> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
121 | 3 | $this->allowance_updated_at = $timestamp; |
|
0 ignored issues
–
show
The property
allowance_updated_at does not exist on object<app\models\entity\User> . Since you implemented __set , maybe consider adding a @property annotation.
Since your code implements the magic setter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
Since the property has write access only, you can use the @property-write annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property. ![]() |
|||
122 | $this->save(); |
||
123 | 3 | } |
|
124 | |||
125 | /** |
||
126 | * @return \yii\db\ActiveQuery |
||
127 | */ |
||
128 | public function getProfile() |
||
129 | 10 | { |
|
130 | return $this->hasOne(UserProfile::class, ['user_id' => 'id']); |
||
131 | 10 | } |
|
132 | |||
133 | /** |
||
134 | * @param array $attributes |
||
135 | */ |
||
136 | public function setProfile($attributes = []) |
||
137 | { |
||
138 | return $this->populateRelation('profile', new UserProfile($attributes)); |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * @return \yii\db\ActiveQuery |
||
143 | */ |
||
144 | public function getProviders() |
||
145 | 10 | { |
|
146 | return $this->hasMany(UserProvider::class, ['user_id' => 'id']); |
||
147 | 10 | } |
|
148 | |||
149 | /** |
||
150 | * @param array $attributes |
||
151 | */ |
||
152 | public function setProviders($attributes = []) |
||
153 | { |
||
154 | 80 | return $this->populateRelation('providers', [new UserProvider($attributes)]); |
|
155 | } |
||
156 | 80 | ||
157 | /** |
||
158 | * @return \yii\db\ActiveQuery |
||
159 | */ |
||
160 | public function getRole() |
||
161 | { |
||
162 | 9 | return $this->hasOne(AuthItem::class, ['name' => 'role_name']); |
|
163 | } |
||
164 | 9 | ||
165 | 9 | /** |
|
166 | 3 | * @inheritdoc |
|
167 | 3 | * @return \app\models\query\UserQuery The active query used by this AR class |
|
168 | 3 | */ |
|
169 | public static function find() |
||
170 | { |
||
171 | 3 | return new \app\models\query\UserQuery(get_called_class()); |
|
172 | } |
||
173 | |||
174 | /** |
||
175 | * @inheritdoc |
||
176 | 9 | */ |
|
177 | 1 | public function beforeSave($insert) |
|
178 | { |
||
179 | if (parent::beforeSave($insert)) { |
||
180 | 9 | if ($insert) { |
|
181 | $this->generateAuthKey(); |
||
182 | if (!Yii::$app instanceof \yii\console\Application) { |
||
183 | $this->ip = ip2long(Yii::$app->request->getUserIP()); |
||
184 | } |
||
185 | |||
186 | if ($this->profile === null) { |
||
187 | $this->setProfile(); |
||
188 | } |
||
189 | } |
||
190 | |||
191 | 9 | if (!empty($this->passwordNew)) { |
|
192 | $this->setPassword($this->passwordNew); |
||
193 | 9 | } |
|
194 | |||
195 | 9 | return true; |
|
196 | 7 | } |
|
197 | |||
198 | return false; |
||
199 | 9 | } |
|
200 | |||
201 | /** |
||
202 | * @inheritdoc |
||
203 | * @property \entity\UserProfile $profile |
||
204 | * @property \entity\UserProvider $providers |
||
205 | */ |
||
206 | 9 | public function afterSave($insert, $changedAttributes) |
|
207 | { |
||
208 | parent::afterSave($insert, $changedAttributes); |
||
209 | |||
210 | if ($this->profile !== null) { |
||
211 | $this->link('profile', $this->profile); |
||
212 | } |
||
213 | |||
214 | if ($this->providers !== null && count($this->providers)) { |
||
215 | foreach ($this->providers as $provider) { |
||
216 | 9 | if ($provider) { |
|
217 | 9 | $this->link('providers', $provider); |
|
218 | 9 | } |
|
219 | } |
||
220 | } |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * @inheritdoc |
||
225 | * @param boolean $runValidation |
||
226 | 6 | * @param array $attributeNames |
|
227 | * @return boolean |
||
228 | */ |
||
229 | 6 | public function save($runValidation = true, $attributeNames = null) |
|
230 | 6 | { |
|
231 | 6 | return $this->getDb()->transaction(function () use ($runValidation, $attributeNames) { |
|
232 | return parent::save($runValidation, $attributeNames); |
||
233 | }); |
||
234 | } |
||
235 | |||
236 | /** |
||
237 | * Get all statuses |
||
238 | * |
||
239 | * @param string[] |
||
240 | 6 | */ |
|
241 | public static function getStatuses(): array |
||
242 | 6 | { |
|
243 | 6 | return [ |
|
244 | self::STATUS_DELETED => Yii::t('app', 'Deleted'), |
||
245 | self::STATUS_BLOCKED => Yii::t('app', 'Locked'), |
||
246 | self::STATUS_ACTIVE => Yii::t('app', 'Active'), |
||
247 | ]; |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Get status name |
||
252 | * |
||
253 | * @return string |
||
254 | */ |
||
255 | public function getStatusName(): string |
||
256 | { |
||
257 | $statuses = self::getStatuses(); |
||
258 | return isset($statuses[$this->status]) ? $statuses[$this->status] : ''; |
||
259 | } |
||
260 | |||
261 | 6 | /** |
|
262 | * Whether the user is deleted |
||
263 | 6 | * |
|
264 | * @param bool |
||
265 | */ |
||
266 | public function isDeleted(): bool |
||
267 | { |
||
268 | return $this->status == self::STATUS_DELETED; |
||
269 | } |
||
270 | |||
271 | 30 | /** |
|
272 | * Whether the user is blocked |
||
273 | 30 | * |
|
274 | * @param bool |
||
275 | */ |
||
276 | public function isBlocked(): bool |
||
277 | { |
||
278 | return $this->status == self::STATUS_BLOCKED; |
||
279 | } |
||
280 | |||
281 | 10 | /** |
|
282 | * Whether the user is active |
||
283 | 10 | * |
|
284 | * @param bool |
||
285 | */ |
||
286 | public function isActive(): bool |
||
287 | { |
||
288 | return $this->status == self::STATUS_ACTIVE; |
||
289 | } |
||
290 | |||
291 | 15 | /** |
|
292 | * Whether the user is confirmed |
||
293 | 15 | * |
|
294 | * @param bool |
||
295 | */ |
||
296 | public function isConfirmed(): bool |
||
297 | { |
||
298 | return strtotime($this->date_confirm) > 0; |
||
299 | 2 | } |
|
300 | |||
301 | 2 | /** |
|
302 | 2 | * Whether the user is SuperUser |
|
303 | 2 | * |
|
304 | * @return bool |
||
305 | */ |
||
306 | public function isSuperUser(): bool |
||
307 | { |
||
308 | return $this->role_name === self::ROLE_SUPERUSER; |
||
309 | } |
||
310 | 8 | ||
311 | /** |
||
312 | 8 | * Set confirmed |
|
313 | 4 | */ |
|
314 | 4 | public function setConfirmed(): void |
|
315 | 4 | { |
|
316 | $this->email_confirm_token = null; |
||
317 | $this->date_confirm = new \yii\db\Expression('NOW()'); |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * Get status description |
||
322 | * |
||
323 | 28 | * @return string |
|
324 | */ |
||
325 | 28 | public function getStatusDescription(): string |
|
326 | { |
||
327 | if ($this->status == self::STATUS_BLOCKED) { |
||
328 | return Yii::t('app', 'Your account has been suspended'); |
||
329 | } elseif ($this->status == self::STATUS_DELETED) { |
||
330 | return Yii::t('app', 'Your account has been deleted'); |
||
331 | } |
||
332 | return Yii::t('app', 'Your account is activated'); |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * @inheritdoc |
||
337 | */ |
||
338 | public function getId() |
||
339 | { |
||
340 | return $this->id; |
||
341 | } |
||
342 | |||
343 | /** |
||
344 | * @inheritdoc |
||
345 | */ |
||
346 | public function getAuthKey() |
||
347 | 3 | { |
|
348 | return $this->auth_key; |
||
349 | 3 | } |
|
350 | 3 | ||
351 | /** |
||
352 | * @inheritdoc |
||
353 | */ |
||
354 | public function validateAuthKey($authKey) |
||
355 | { |
||
356 | return $this->getAuthKey() === $authKey; |
||
357 | } |
||
358 | 22 | ||
359 | /** |
||
360 | 22 | * Generates "remember me" authentication key |
|
361 | */ |
||
362 | public function generateAuthKey() |
||
363 | { |
||
364 | 22 | $this->auth_key = Yii::$app->security->generateRandomString(); |
|
365 | } |
||
366 | |||
367 | /** |
||
368 | * Validates password |
||
369 | * |
||
370 | * @param string $password Password to validate |
||
371 | * @return boolean If password provided is valid for current user |
||
372 | 6 | */ |
|
373 | public function validatePassword(string $password): bool |
||
374 | 6 | { |
|
375 | 6 | if (empty($this->password)) { |
|
376 | return false; |
||
377 | } |
||
378 | |||
379 | return Yii::$app->security->validatePassword($password, $this->password); |
||
380 | } |
||
381 | |||
382 | 1 | /** |
|
383 | * Set a new password |
||
384 | 1 | * |
|
385 | 1 | * @param string $password |
|
386 | */ |
||
387 | public function setPassword(string $password): void |
||
388 | { |
||
389 | $this->password = Yii::$app->security->generatePasswordHash($password); |
||
390 | 2 | } |
|
391 | |||
392 | 2 | /** |
|
393 | 2 | * Set new password reset token |
|
394 | * |
||
395 | * @param string $token |
||
396 | */ |
||
397 | public function setPasswordResetToken(string $token): void |
||
398 | { |
||
399 | $this->password_reset_token = $token; |
||
400 | 4 | } |
|
401 | |||
402 | 4 | /** |
|
403 | 4 | * Removes password reset token |
|
404 | 4 | */ |
|
405 | public function removePasswordResetToken(): void |
||
406 | { |
||
407 | $this->password_reset_token = null; |
||
408 | } |
||
409 | 20 | ||
410 | /** |
||
411 | 20 | * Set new confirm email token |
|
412 | * |
||
413 | * @param string $token |
||
414 | */ |
||
415 | public function setEmailConfirmToken(string $token): void |
||
416 | { |
||
417 | $this->email_confirm_token = $token; |
||
418 | $this->date_confirm = null; |
||
419 | } |
||
420 | |||
421 | public function getName() |
||
422 | { |
||
423 | return $this->profile->full_name; |
||
424 | } |
||
425 | 12 | ||
426 | /** |
||
427 | 12 | * @inheritdoc |
|
428 | 12 | */ |
|
429 | 12 | public static function findIdentity($id) |
|
430 | { |
||
431 | 12 | return static::findOne([$id]); |
|
0 ignored issues
–
show
The return type of
return static::findOne(array($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 .
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 ![]() |
|||
432 | } |
||
433 | |||
434 | /** |
||
435 | * @inheritdoc |
||
436 | */ |
||
437 | public static function findIdentityByAccessToken($token, $type = null) |
||
438 | { |
||
439 | throw new NotSupportedException('findIdentityByAccessToken is not implemented.'); |
||
440 | } |
||
441 | |||
442 | /** |
||
443 | * Update date login |
||
444 | */ |
||
445 | public function updateDateLogin(): void |
||
446 | { |
||
447 | $this->updateAttributes([ |
||
448 | 'date_login' => new \yii\db\Expression('NOW()'), |
||
449 | 'ip' => ip2long(Yii::$app->request->getUserIP()) |
||
450 | ]); |
||
451 | } |
||
452 | |||
453 | /** |
||
454 | * @return bool |
||
455 | */ |
||
456 | public function beforeDelete() |
||
457 | { |
||
458 | Yii::$app->authManager->revokeAll($this->id); |
||
459 | |||
460 | if ($this->profile !== null) { |
||
461 | $this->profile->delete(); |
||
462 | } |
||
463 | |||
464 | return true; |
||
465 | } |
||
466 | } |
||
467 |
Since your code implements the magic getter
_get
, this function will be called for any read access on an undefined variable. You can add the@property
annotation to your class or interface to document the existence of this variable.If the property has read access only, you can use the @property-read annotation instead.
Of course, you may also just have mistyped another name, in which case you should fix the error.
See also the PhpDoc documentation for @property.