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 | /** |
||
4 | * _ __ __ _____ _____ ___ ____ _____ |
||
5 | * | | / // // ___//_ _// || __||_ _| |
||
6 | * | |/ // /(__ ) / / / /| || | | | |
||
7 | * |___//_//____/ /_/ /_/ |_||_| |_| |
||
8 | * @link https://vistart.me/ |
||
9 | * @copyright Copyright (c) 2016 - 2017 vistart |
||
10 | * @license https://vistart.me/license/ |
||
11 | */ |
||
12 | |||
13 | namespace rhosocial\user\console\controllers; |
||
14 | |||
15 | use Faker\Factory; |
||
16 | use rhosocial\base\helpers\Timezone; |
||
17 | use rhosocial\user\User; |
||
18 | use rhosocial\user\Profile; |
||
19 | use yii\console\Controller; |
||
20 | use yii\console\Exception; |
||
21 | use Yii; |
||
22 | use yii\helpers\Console; |
||
23 | |||
24 | /** |
||
25 | * The simple operations associated with User. |
||
26 | * |
||
27 | * @version 1.0 |
||
28 | * @author vistart <[email protected]> |
||
29 | */ |
||
30 | class UserController extends Controller |
||
31 | { |
||
32 | public $userClass; |
||
33 | |||
34 | public $defaultAction = 'show'; |
||
35 | |||
36 | /** |
||
37 | * Check and get valid User. |
||
38 | * @return User |
||
39 | * @throws Exception throw if User is not an instance inherited from `\rhosocial\user\User`. |
||
40 | */ |
||
41 | protected function checkUserClass() |
||
42 | { |
||
43 | $userClass = $this->userClass; |
||
44 | if (!class_exists($userClass)) { |
||
45 | throw new Exception('User Class Invalid.'); |
||
46 | } |
||
47 | if (!((new $userClass()) instanceof User)) { |
||
48 | throw new Exception('User Class(' . $userClass . ') does not inherited from `\rhosocial\user\User`.'); |
||
49 | } |
||
50 | return $userClass; |
||
51 | } |
||
52 | |||
53 | /** |
||
54 | * Get user from database. |
||
55 | * @param User|string|integer $user User ID. |
||
56 | * @return User |
||
57 | * @throws Exception |
||
58 | */ |
||
59 | protected function getUser($user) |
||
60 | { |
||
61 | $userClass = $this->checkUserClass(); |
||
62 | if (is_numeric($user)) { |
||
63 | $user = $userClass::find()->id($user)->one(); |
||
64 | } elseif (is_string($user) && strlen($user)) { |
||
65 | $user = $userClass::find()->guid($user)->one(); |
||
66 | } |
||
67 | if (!$user || $user->getIsNewRecord()) { |
||
0 ignored issues
–
show
|
|||
68 | throw new Exception('User Not Registered.'); |
||
69 | } |
||
70 | return $user; |
||
0 ignored issues
–
show
The return type of
return $user; (yii\db\ActiveRecord|array|string ) is incompatible with the return type documented by rhosocial\user\console\c...UserController::getUser of type rhosocial\user\User .
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 ![]() |
|||
71 | } |
||
72 | |||
73 | /** |
||
74 | * Register new User. |
||
75 | * @param string $password Password. |
||
76 | * @param string $nickname If profile contains this property, this parameter is required. |
||
77 | * @param string $firstName If profile contains this property, this parameter is required. |
||
78 | * @param string $lastName If profile contains this propery, this parameter is required. |
||
79 | * @return int |
||
80 | * @throws Exception |
||
81 | */ |
||
82 | public function actionRegister($password, $nickname = null, $firstName = null, $lastName = null) |
||
83 | { |
||
84 | $userClass = $this->checkUserClass(); |
||
85 | |||
86 | $user = new $userClass(['password' => $password]); |
||
87 | /* @var $user User */ |
||
88 | $profile = $user->createProfile([ |
||
89 | 'nickname' => $nickname, |
||
90 | 'first_name' => $firstName, |
||
91 | 'last_name' => $lastName, |
||
92 | ]); |
||
93 | /* @var $profile Profile */ |
||
94 | try { |
||
95 | is_null($profile) ? $user->register(): $user->register([$profile]); |
||
96 | } catch (\Exception $ex) { |
||
97 | throw new Exception($ex->getMessage()); |
||
98 | } |
||
99 | echo "User Registered:\n"; |
||
100 | return $this->actionShow($user); |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * Deregister user. |
||
105 | * @param User|string|integer $user The user to be deregistered. |
||
106 | * @return int |
||
107 | */ |
||
108 | public function actionDeregister($user) |
||
109 | { |
||
110 | $user = $this->getUser($user); |
||
111 | if ($user->deregister()) { |
||
112 | echo "User (" . $user->getID() . ") Deregistered.\n"; |
||
113 | return static::EXIT_CODE_NORMAL; |
||
114 | } |
||
115 | return static::EXIT_CODE_ERROR; |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Show User Information. |
||
120 | * @param User|string|integer $user User ID. |
||
121 | * @param boolean $guid Show GUID? |
||
122 | * @param boolean $passHash Show PasswordH Hash? |
||
123 | * @param boolean $accessToken Show Access Token? |
||
124 | * @param boolean $authKey Show Authentication Key? |
||
125 | * @return int |
||
126 | */ |
||
127 | public function actionShow($user, $guid = false, $passHash = false, $accessToken = false, $authKey = false) |
||
128 | { |
||
129 | $user = $this->getUser($user); |
||
130 | echo Yii::t('app', 'User') . " (" . $user->getID() . "), " . Yii::t('app', 'registered at') . " (" . $user->getCreatedAt() . ")" |
||
131 | . ($user->getCreatedAt() == $user->getUpdatedAt() ? "" : ", " . Yii::t('app', 'last updated at') . " (" . $user->getUpdatedAt() . ")") .".\n"; |
||
132 | if ($guid) { |
||
133 | echo "GUID: " . $user->getGUID() . "\n"; |
||
134 | } |
||
135 | if ($passHash) { |
||
136 | echo "Password Hash: " . $user->{$user->passwordHashAttribute} . "\n"; |
||
137 | } |
||
138 | if ($accessToken) { |
||
139 | echo "Access Token: " . $user->getAccessToken() . "\n"; |
||
140 | } |
||
141 | if ($authKey) { |
||
142 | echo "Authentication Key: " . $user->getAuthKey() . "\n"; |
||
143 | } |
||
144 | return static::EXIT_CODE_NORMAL; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Show statistics. |
||
149 | * @param User|string|integer $user User ID. |
||
150 | * @return int |
||
151 | */ |
||
152 | public function actionStat($user = null) |
||
153 | { |
||
154 | if ($user === null) { |
||
155 | $count = User::find()->count(); |
||
156 | echo "Total number of user(s): " . $count . "\n"; |
||
157 | if ($count == 0) { |
||
158 | return static::EXIT_CODE_NORMAL; |
||
159 | } |
||
160 | $last = User::find()->orderByCreatedAt(SORT_DESC)->one(); |
||
161 | /* @var $last User */ |
||
162 | echo "Latest user (" . $last->getID() . ") registered at " . $last->getCreatedAt() . "\n"; |
||
163 | return static::EXIT_CODE_NORMAL; |
||
164 | } |
||
165 | $user = $this->getUser($user); |
||
0 ignored issues
–
show
$user is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
166 | return static::EXIT_CODE_NORMAL; |
||
167 | } |
||
168 | |||
169 | /** |
||
170 | * Assign a role to user or revoke a role. |
||
171 | * @param User|string|integer $user User ID. |
||
172 | * @param string $operation Only `assign` and `revoke` are acceptable. |
||
173 | * @param string $role Role name. |
||
174 | * @return int |
||
175 | */ |
||
176 | public function actionRole($user, $operation, $role) |
||
177 | { |
||
178 | $user = $this->getUser($user); |
||
179 | $role = Yii::$app->authManager->getRole($role); |
||
180 | if ($operation == 'assign') { |
||
181 | try { |
||
182 | $assignment = Yii::$app->authManager->assign($role, $user); |
||
183 | } catch (\yii\db\IntegrityException $ex) { |
||
184 | echo "Failed to assign `" . $role->name . "`.\n"; |
||
185 | echo "Maybe the role has been assigned.\n"; |
||
186 | return static::EXIT_CODE_ERROR; |
||
187 | } |
||
188 | if ($assignment) { |
||
189 | echo "`$role->name`" . " assigned to User (" . $user->getID() . ") successfully.\n"; |
||
190 | } else { |
||
191 | echo "Failed to assign `" . $role->name . "`.\n"; |
||
192 | } |
||
193 | return static::EXIT_CODE_NORMAL; |
||
194 | } |
||
195 | if ($operation == 'revoke') { |
||
196 | $assignment = Yii::$app->authManager->revoke($role, $user); |
||
197 | if ($assignment) { |
||
198 | echo "`$role->name`" . " revoked from User (" . $user->getID() . ").\n"; |
||
199 | } else { |
||
200 | echo "Failed to revoke `" . $role->name . "`.\n"; |
||
201 | echo "Maybe the role has not been assigned yet.\n"; |
||
202 | } |
||
203 | return static::EXIT_CODE_NORMAL; |
||
204 | } |
||
205 | echo "Unrecognized operation: $operation.\n"; |
||
206 | echo "The accepted operations are `assign` and `revoke`.\n"; |
||
207 | return static::EXIT_CODE_ERROR; |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Assign a permission to user or revoke a permission. |
||
212 | * @param User|string|integer $user User ID. |
||
213 | * @param string $operation Only `assign` and `revoke` are acceptable. |
||
214 | * @param string $permission Permission name. |
||
215 | * @return int |
||
216 | */ |
||
217 | public function actionPermission($user, $operation, $permission) |
||
218 | { |
||
219 | $user = $this->getUser($user); |
||
220 | $permission = Yii::$app->authManager->getPermission($permission); |
||
221 | if ($operation == 'assign') { |
||
222 | try { |
||
223 | $assignment = Yii::$app->authManager->assign($permission, $user); |
||
224 | } catch (\yii\db\IntegrityException $ex) { |
||
225 | echo "Failed to assign `" . $permission->name . "`.\n"; |
||
226 | echo "Maybe the permission has been assigned.\n"; |
||
227 | return static::EXIT_CODE_ERROR; |
||
228 | } |
||
229 | if ($assignment) { |
||
230 | echo "`$permission->name`" . " assigned to User (" . $user->getID() . ") successfully.\n"; |
||
231 | } else { |
||
232 | echo "Failed to assign `" . $permission->name . "`.\n"; |
||
233 | } |
||
234 | return static::EXIT_CODE_NORMAL; |
||
235 | } |
||
236 | if ($operation == 'revoke') { |
||
237 | $assignment = Yii::$app->authManager->revoke($permission, $user); |
||
238 | if ($assignment) { |
||
239 | echo "`$permission->name`" . " revoked from User (" . $user->getID() . ").\n"; |
||
240 | } else { |
||
241 | echo "Failed to revoke `" . $permission->name . "`.\n"; |
||
242 | echo "Maybe the permission has not been assigned yet.\n"; |
||
243 | } |
||
244 | return static::EXIT_CODE_NORMAL; |
||
245 | } |
||
246 | echo "Unrecognized operation: $operation.\n"; |
||
247 | echo "The accepted operations are `assign` and `revoke`.\n"; |
||
248 | return static::EXIT_CODE_ERROR; |
||
249 | } |
||
250 | |||
251 | /** |
||
252 | * Validate password. |
||
253 | * @param User|string|integer $user User ID. |
||
254 | * @param password $password Password. |
||
255 | * @return int |
||
256 | */ |
||
257 | public function actionValidatePassword($user, $password) |
||
258 | { |
||
259 | $user = $this->getUser($user); |
||
260 | $result = $user->validatePassword($password); |
||
261 | if ($result) { |
||
262 | echo "Correct.\n"; |
||
263 | } else { |
||
264 | echo "Incorrect.\n"; |
||
265 | } |
||
266 | return static::EXIT_CODE_NORMAL; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * Change password directly. |
||
271 | * @param User|string|integer $user User ID. |
||
272 | * @param string $password Password. |
||
273 | * @return int |
||
274 | */ |
||
275 | public function actionPassword($user, $password) |
||
276 | { |
||
277 | $user = $this->getUser($user); |
||
278 | $user->applyForNewPassword(); |
||
279 | $result = $user->resetPassword($password, $user->getPasswordResetToken()); |
||
280 | if ($result) { |
||
281 | echo "Password changed.\n"; |
||
282 | } else { |
||
283 | echo "Password not changed.\n"; |
||
284 | } |
||
285 | return static::EXIT_CODE_NORMAL; |
||
286 | } |
||
287 | |||
288 | /** |
||
289 | * Confirm password in history. |
||
290 | * This command will list all matching passwords in reverse order. |
||
291 | * @param User|string|integer $user User ID. |
||
292 | * @param string $password Password. |
||
293 | * @return int |
||
294 | */ |
||
295 | public function actionConfirmPasswordHistory($user, $password) |
||
296 | { |
||
297 | $user = $this->getUser($user); |
||
298 | $passwordHistory = $user->passwordHistories; |
||
299 | $passwordInHistory = 0; |
||
300 | foreach ($passwordHistory as $pass) { |
||
301 | if ($pass->validatePassword($password)) { |
||
302 | $passwordInHistory++; |
||
303 | echo "This password was created at " . $pass->getCreatedAt() . ".\n"; |
||
304 | } |
||
305 | } |
||
306 | if ($passwordInHistory) { |
||
307 | echo "$passwordInHistory matched.\n"; |
||
308 | return static::EXIT_CODE_NORMAL; |
||
309 | } |
||
310 | echo "No password matched.\n"; |
||
311 | return static::EXIT_CODE_ERROR; |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * Register users for testing. |
||
316 | * @param int $total |
||
317 | * @param string password |
||
318 | * @return int |
||
319 | * @throws Exception |
||
320 | */ |
||
321 | public function actionAddTestUsers($total = 1000, $password = '123456') |
||
322 | { |
||
323 | echo "Registration Start...\n"; |
||
324 | $userClass = $this->checkUserClass(); |
||
325 | |||
326 | $faker = Factory::create(str_replace('-', '_', Yii::$app->language)); |
||
327 | $total = (int)$total; |
||
328 | $acc = 0; |
||
329 | $time = time(); |
||
330 | $timezones = array_keys(Timezone::generateList()); |
||
331 | $genders = [Profile::GENDER_MALE, Profile::GENDER_FEMALE]; |
||
332 | for ($i = 1; $i <= $total; $i++) { |
||
333 | $user = new $userClass(['password' => $password]); |
||
334 | $user->source = 'console_test'; |
||
335 | /* @var $user User */ |
||
336 | $gender = $faker->randomElement($genders); |
||
337 | $profile = null; |
||
338 | if ($gender == Profile::GENDER_MALE) { |
||
339 | $profile = $user->createProfile([ |
||
340 | 'nickname' => $faker->titleMale, |
||
341 | 'first_name' => $faker->firstNameMale, |
||
342 | 'last_name' => $faker->lastName, |
||
343 | 'timezone' => $faker->randomElement($timezones), |
||
344 | ]); |
||
345 | } elseif ($gender == Profile::GENDER_FEMALE) { |
||
346 | $profile = $user->createProfile([ |
||
347 | 'nickname' => $faker->titleFemale, |
||
348 | 'first_name' => $faker->firstNameFemale, |
||
349 | 'last_name' => $faker->lastName, |
||
350 | 'timezone' => $faker->randomElement($timezones), |
||
351 | ]); |
||
352 | } |
||
353 | $profile->gender = $gender; |
||
354 | /* @var $profile Profile */ |
||
355 | try { |
||
356 | $result = (is_null($profile) ? $user->register() : $user->register([$profile])); |
||
357 | if ($result !== true) { |
||
358 | throw new Exception("User Not Registered."); |
||
359 | } |
||
360 | } catch (\Exception $ex) { |
||
361 | echo $ex->getMessage() . "\n"; |
||
362 | continue; |
||
363 | } |
||
364 | $acc++; |
||
365 | if ($acc % 10 == 0) { |
||
366 | $percent = (float)$i / $total * 100; |
||
367 | echo "$acc users registered($percent% finished).\n"; |
||
368 | } |
||
369 | } |
||
370 | $consumed = time() - $time; |
||
371 | echo "Totally $acc users registered.\n"; |
||
372 | echo "Registration finished($consumed seconds consumed).\n"; |
||
373 | return static::EXIT_CODE_NORMAL; |
||
374 | } |
||
375 | |||
376 | /** |
||
377 | * Deregister all users for testing. |
||
378 | * @return int |
||
379 | */ |
||
380 | public function actionRemoveAllTestUsers() |
||
381 | { |
||
382 | echo "Deregistration Start...\n"; |
||
383 | |||
384 | $userClass = $this->checkUserClass(); |
||
385 | $acc = 0; |
||
386 | $time = time(); |
||
387 | $total = (int)$userClass::find()->andWhere(['source' => 'console_test'])->count(); |
||
388 | echo "$total users maybe deregistered.\n"; |
||
389 | foreach ($userClass::find()->andWhere(['source' => 'console_test'])->each() as $user) { |
||
390 | try { |
||
391 | $user->deregister(); |
||
392 | } catch (\Exception $ex) { |
||
393 | echo $ex->getMessage() . "\n"; |
||
394 | continue; |
||
395 | } |
||
396 | $acc++; |
||
397 | if ($acc % 10 == 0) { |
||
398 | $percent = (float)$acc / $total * 100; |
||
399 | echo "$acc users deregistered($percent% finished).\n"; |
||
400 | } |
||
401 | } |
||
402 | $consumed = time() - $time; |
||
403 | echo "Totally $acc users deregistered.\n"; |
||
404 | echo "Deregistration finished($consumed seconds consumed).\n"; |
||
405 | return static::EXIT_CODE_NORMAL; |
||
406 | } |
||
407 | } |
||
408 |
If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe: