Skip to content

Commit 9ae1651

Browse files
authored
Merge pull request #1078 from kenjis/fix-command-user-create-validation
fix: Can't create new users via CLI if username is disabled
2 parents 62df7fd + 3aa3b19 commit 9ae1651

File tree

2 files changed

+92
-63
lines changed

2 files changed

+92
-63
lines changed

phpstan-baseline.php

Lines changed: 75 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
'path' => __DIR__ . '/src/Authentication/Actions/Email2FA.php',
99
];
1010
$ignoreErrors[] = [
11-
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
11+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
1212
'count' => 2,
1313
'path' => __DIR__ . '/src/Authentication/Actions/Email2FA.php',
1414
];
1515
$ignoreErrors[] = [
16-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
16+
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
1717
'count' => 2,
1818
'path' => __DIR__ . '/src/Authentication/Actions/Email2FA.php',
1919
];
@@ -33,6 +33,16 @@
3333
'count' => 1,
3434
'path' => __DIR__ . '/src/Authentication/Authentication.php',
3535
];
36+
$ignoreErrors[] = [
37+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#',
38+
'count' => 1,
39+
'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php',
40+
];
41+
$ignoreErrors[] = [
42+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
43+
'count' => 1,
44+
'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php',
45+
];
3646
$ignoreErrors[] = [
3747
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
3848
'count' => 4,
@@ -46,70 +56,70 @@
4656
$ignoreErrors[] = [
4757
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#',
4858
'count' => 1,
49-
'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php',
59+
'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php',
5060
];
5161
$ignoreErrors[] = [
5262
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
5363
'count' => 1,
54-
'path' => __DIR__ . '/src/Authentication/Authenticators/AccessTokens.php',
64+
'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php',
5565
];
5666
$ignoreErrors[] = [
57-
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#',
67+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#',
5868
'count' => 1,
5969
'path' => __DIR__ . '/src/Authentication/Authenticators/JWT.php',
6070
];
6171
$ignoreErrors[] = [
62-
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#',
72+
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#',
6373
'count' => 1,
6474
'path' => __DIR__ . '/src/Authentication/Authenticators/JWT.php',
6575
];
6676
$ignoreErrors[] = [
67-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#',
77+
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{token\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\JWT\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#',
6878
'count' => 1,
6979
'path' => __DIR__ . '/src/Authentication/Authenticators/JWT.php',
7080
];
7181
$ignoreErrors[] = [
72-
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
73-
'count' => 3,
82+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#',
83+
'count' => 1,
7484
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
7585
];
7686
$ignoreErrors[] = [
77-
'message' => '#^Only booleans are allowed in an elseif condition, string\\|null given\\.$#',
87+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\RememberModel\\:\\:class is discouraged\\.$#',
7888
'count' => 1,
7989
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
8090
];
8191
$ignoreErrors[] = [
82-
'message' => '#^Only booleans are allowed in an if condition, CodeIgniter\\\\Shield\\\\Entities\\\\UserIdentity\\|null given\\.$#',
92+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
8393
'count' => 1,
8494
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
8595
];
8696
$ignoreErrors[] = [
87-
'message' => '#^Only booleans are allowed in an if condition, int\\|string\\|null given\\.$#',
97+
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
8898
'count' => 3,
8999
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
90100
];
91101
$ignoreErrors[] = [
92-
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#',
102+
'message' => '#^Only booleans are allowed in an elseif condition, string\\|null given\\.$#',
93103
'count' => 1,
94104
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
95105
];
96106
$ignoreErrors[] = [
97-
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#',
107+
'message' => '#^Only booleans are allowed in an if condition, CodeIgniter\\\\Shield\\\\Entities\\\\UserIdentity\\|null given\\.$#',
98108
'count' => 1,
99109
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
100110
];
101111
$ignoreErrors[] = [
102-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#',
103-
'count' => 1,
112+
'message' => '#^Only booleans are allowed in an if condition, int\\|string\\|null given\\.$#',
113+
'count' => 3,
104114
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
105115
];
106116
$ignoreErrors[] = [
107-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\RememberModel\\:\\:class is discouraged\\.$#',
117+
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:attempt\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:attempt\\(\\)$#',
108118
'count' => 1,
109119
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
110120
];
111121
$ignoreErrors[] = [
112-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
122+
'message' => '#^Parameter \\#1 \\$credentials \\(array\\{email\\?\\: string, username\\?\\: string, password\\?\\: string\\}\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\Authenticators\\\\Session\\:\\:check\\(\\) should be contravariant with parameter \\$credentials \\(array\\) of method CodeIgniter\\\\Shield\\\\Authentication\\\\AuthenticatorInterface\\:\\:check\\(\\)$#',
113123
'count' => 1,
114124
'path' => __DIR__ . '/src/Authentication/Authenticators/Session.php',
115125
];
@@ -158,6 +168,11 @@
158168
'count' => 1,
159169
'path' => __DIR__ . '/src/Collectors/Auth.php',
160170
];
171+
$ignoreErrors[] = [
172+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:class is discouraged\\.$#',
173+
'count' => 9,
174+
'path' => __DIR__ . '/src/Commands/User.php',
175+
];
161176
$ignoreErrors[] = [
162177
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
163178
'count' => 1,
@@ -175,13 +190,13 @@
175190
'path' => __DIR__ . '/src/Controllers/MagicLinkController.php',
176191
];
177192
$ignoreErrors[] = [
178-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
179-
'count' => 2,
193+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#',
194+
'count' => 1,
180195
'path' => __DIR__ . '/src/Controllers/MagicLinkController.php',
181196
];
182197
$ignoreErrors[] = [
183-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#',
184-
'count' => 1,
198+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
199+
'count' => 2,
185200
'path' => __DIR__ . '/src/Controllers/MagicLinkController.php',
186201
];
187202
$ignoreErrors[] = [
@@ -240,13 +255,18 @@
240255
'path' => __DIR__ . '/src/Entities/Group.php',
241256
];
242257
$ignoreErrors[] = [
243-
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
244-
'count' => 8,
258+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\GroupModel\\:\\:class is discouraged\\.$#',
259+
'count' => 2,
245260
'path' => __DIR__ . '/src/Entities/User.php',
246261
];
247262
$ignoreErrors[] = [
248-
'message' => '#^Only booleans are allowed in a ternary operator condition, int\\<0, max\\> given\\.$#',
249-
'count' => 1,
263+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#',
264+
'count' => 2,
265+
'path' => __DIR__ . '/src/Entities/User.php',
266+
];
267+
$ignoreErrors[] = [
268+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\PermissionModel\\:\\:class is discouraged\\.$#',
269+
'count' => 2,
250270
'path' => __DIR__ . '/src/Entities/User.php',
251271
];
252272
$ignoreErrors[] = [
@@ -255,14 +275,14 @@
255275
'path' => __DIR__ . '/src/Entities/User.php',
256276
];
257277
$ignoreErrors[] = [
258-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:class is discouraged\\.$#',
259-
'count' => 2,
278+
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
279+
'count' => 8,
260280
'path' => __DIR__ . '/src/Entities/User.php',
261281
];
262282
$ignoreErrors[] = [
263-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:class is discouraged\\.$#',
264-
'count' => 9,
265-
'path' => __DIR__ . '/src/Commands/User.php',
283+
'message' => '#^Only booleans are allowed in a ternary operator condition, int\\<0, max\\> given\\.$#',
284+
'count' => 1,
285+
'path' => __DIR__ . '/src/Entities/User.php',
266286
];
267287
$ignoreErrors[] = [
268288
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
@@ -289,6 +309,11 @@
289309
'count' => 2,
290310
'path' => __DIR__ . '/src/Filters/TokenAuth.php',
291311
];
312+
$ignoreErrors[] = [
313+
'message' => '#^Property CodeIgniter\\\\Shield\\\\Models\\\\LoginModel\\:\\:\\$validationRules \\(list\\<string\\>\\|string\\) does not accept default value of type array\\{ip_address\\: \'required\', id_type\\: \'required\', identifier\\: \'permit_empty\\|string\', user_agent\\: \'permit_empty\\|string\', user_id\\: \'permit_empty\', date\\: \'required\'\\}\\.$#',
314+
'count' => 1,
315+
'path' => __DIR__ . '/src/Models/LoginModel.php',
316+
];
292317
$ignoreErrors[] = [
293318
'message' => '#^Call to deprecated function random_string\\(\\)\\:
294319
The type \'basic\', \'md5\', and \'sha1\' are deprecated\\. They are not cryptographically secure\\.$#',
@@ -301,19 +326,34 @@
301326
'count' => 1,
302327
'path' => __DIR__ . '/src/Models/UserIdentityModel.php',
303328
];
329+
$ignoreErrors[] = [
330+
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
331+
'count' => 1,
332+
'path' => __DIR__ . '/src/Models/UserModel.php',
333+
];
304334
$ignoreErrors[] = [
305335
'message' => '#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#',
306336
'count' => 2,
307337
'path' => __DIR__ . '/src/Models/UserModel.php',
308338
];
309339
$ignoreErrors[] = [
310-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
340+
'message' => '#^Parameter \\#1 \\$row \\(array\\|CodeIgniter\\\\Shield\\\\Entities\\\\User\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:insert\\(\\) should be contravariant with parameter \\$row \\(array\\<int\\|string, float\\|int\\|object\\|string\\|null\\>\\|object\\|null\\) of method CodeIgniter\\\\Model\\:\\:insert\\(\\)$#',
311341
'count' => 1,
312342
'path' => __DIR__ . '/src/Models/UserModel.php',
313343
];
314344
$ignoreErrors[] = [
315-
'message' => '#^Return type \\(int|string|true\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:insert\\(\\) should be covariant with return type \\(\\(\\$returnID is true \\? int|string|false \\: bool\\) of method CodeIgniter\\\\Model\\:\\:insert\\(\\)\\$#',
316-
'count' => 4,
345+
'message' => '#^Parameter \\#1 \\$row \\(array\\|CodeIgniter\\\\Shield\\\\Entities\\\\User\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:save\\(\\) should be contravariant with parameter \\$row \\(array\\<int\\|string, float\\|int\\|object\\|string\\|null\\>\\|object\\) of method CodeIgniter\\\\BaseModel\\:\\:save\\(\\)$#',
346+
'count' => 1,
347+
'path' => __DIR__ . '/src/Models/UserModel.php',
348+
];
349+
$ignoreErrors[] = [
350+
'message' => '#^Parameter \\#2 \\$row \\(array\\|CodeIgniter\\\\Shield\\\\Entities\\\\User\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:update\\(\\) should be contravariant with parameter \\$row \\(array\\<int\\|string, float\\|int\\|object\\|string\\|null\\>\\|object\\|null\\) of method CodeIgniter\\\\Model\\:\\:update\\(\\)$#',
351+
'count' => 1,
352+
'path' => __DIR__ . '/src/Models/UserModel.php',
353+
];
354+
$ignoreErrors[] = [
355+
'message' => '#^Return type \\(int\\|string\\|true\\) of method CodeIgniter\\\\Shield\\\\Models\\\\UserModel\\:\\:insert\\(\\) should be covariant with return type \\(\\(\\$returnID is true \\? int\\|string\\|false \\: bool\\)\\) of method CodeIgniter\\\\Model\\:\\:insert\\(\\)$#',
356+
'count' => 1,
317357
'path' => __DIR__ . '/src/Models/UserModel.php',
318358
];
319359
$ignoreErrors[] = [
@@ -366,24 +406,5 @@
366406
'count' => 1,
367407
'path' => __DIR__ . '/tests/Unit/UserTest.php',
368408
];
369-
$ignoreErrors[] = [
370-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\TokenLoginModel\\:\\:class is discouraged\\.$#',
371-
'count' => 1,
372-
'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php',
373-
];
374-
$ignoreErrors[] = [
375-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\UserIdentityModel\\:\\:class is discouraged\\.$#',
376-
'count' => 1,
377-
'path' => __DIR__ . '/src/Authentication/Authenticators/HmacSha256.php',
378-
];
379-
$ignoreErrors[] = [
380-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\GroupModel\\:\\:class is discouraged\\.$#',
381-
'count' => 2,
382-
'path' => __DIR__ . '/src/Authorization/Traits/Authorizable.php',
383-
];
384-
$ignoreErrors[] = [
385-
'message' => '#^Call to function model with CodeIgniter\\\\Shield\\\\Models\\\\PermissionModel\\:\\:class is discouraged\\.$#',
386-
'count' => 2,
387-
'path' => __DIR__ . '/src/Authorization/Traits/Authorizable.php',
388-
];
409+
389410
return ['parameters' => ['ignoreErrors' => $ignoreErrors]];

src/Commands/User.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ private function setValidationRules(): void
220220

221221
$rules = $validationRules->getRegistrationRules();
222222

223-
// Remove `strong_password` because it only supports use cases
223+
// Remove `strong_password` rule because it only supports use cases
224224
// to check the user's own password.
225225
$passwordRules = $rules['password']['rules'];
226226
if (is_string($passwordRules)) {
@@ -241,11 +241,10 @@ private function setValidationRules(): void
241241

242242
$rules['password']['rules'] = $passwordRules;
243243

244-
$this->validationRules = [
245-
'username' => $rules['username'],
246-
'email' => $rules['email'],
247-
'password' => $rules['password'],
248-
];
244+
// Remove `password_confirm` field.
245+
unset($rules['password_confirm']);
246+
247+
$this->validationRules = $rules;
249248
}
250249

251250
/**
@@ -258,10 +257,14 @@ private function create(?string $username = null, ?string $email = null): void
258257
{
259258
$data = [];
260259

261-
if ($username === null) {
260+
// If you don't use `username`, remove the validation rules for it.
261+
if ($username === null && isset($this->validationRules['username'])) {
262262
$username = $this->prompt('Username', null, $this->validationRules['username']['rules']);
263263
}
264264
$data['username'] = $username;
265+
if ($username === null) {
266+
unset($data['username']);
267+
}
265268

266269
if ($email === null) {
267270
$email = $this->prompt('Email', null, $this->validationRules['email']['rules']);
@@ -299,9 +302,14 @@ private function create(?string $username = null, ?string $email = null): void
299302
$userModel = model(UserModel::class);
300303

301304
$user = new UserEntity($data);
302-
$userModel->save($user);
303305

304-
$this->write('User "' . $username . '" created', 'green');
306+
if ($username === null) {
307+
$userModel->allowEmptyInserts()->save($user);
308+
$this->write('New User created', 'green');
309+
} else {
310+
$userModel->save($user);
311+
$this->write('User "' . $username . '" created', 'green');
312+
}
305313
}
306314

307315
/**

0 commit comments

Comments
 (0)