From bb9cd9d61093ea0b541f354fdd03c97aab1fd954 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sat, 18 Dec 2021 16:31:48 +0000 Subject: [PATCH] Aligned password length requirements Updated all password validation to use central password defaults system while updating length requirements to now all match at 8 characters minimum. Some language text was technically correct (More than 7 characters) but this has been updated for clarity and to prompt other translations to be updated. Closes #2237 --- app/Console/Commands/CreateAdmin.php | 59 ++++++++----------- .../Controllers/Auth/RegisterController.php | 3 +- .../Controllers/Auth/UserInviteController.php | 3 +- app/Http/Controllers/UserController.php | 9 +-- app/Providers/AuthServiceProvider.php | 7 +++ resources/lang/en/auth.php | 2 +- resources/lang/en/settings.php | 2 +- 7 files changed, 44 insertions(+), 41 deletions(-) diff --git a/app/Console/Commands/CreateAdmin.php b/app/Console/Commands/CreateAdmin.php index 149444420..48da87af4 100644 --- a/app/Console/Commands/CreateAdmin.php +++ b/app/Console/Commands/CreateAdmin.php @@ -4,6 +4,9 @@ namespace BookStack\Console\Commands; use BookStack\Auth\UserRepo; use Illuminate\Console\Command; +use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\Rules\Password; +use Illuminate\Validation\Rules\Unique; use Symfony\Component\Console\Command\Command as SymfonyCommand; class CreateAdmin extends Command @@ -45,43 +48,33 @@ class CreateAdmin extends Command */ public function handle() { - $email = trim($this->option('email')); - if (empty($email)) { - $email = $this->ask('Please specify an email address for the new admin user'); - } - if (mb_strlen($email) < 5 || !filter_var($email, FILTER_VALIDATE_EMAIL)) { - $this->error('Invalid email address provided'); + $details = $this->options(); + + if (empty($details['email'])) { + $details['email'] = $this->ask('Please specify an email address for the new admin user'); + } + if (empty($details['name'])) { + $details['name'] = $this->ask('Please specify a name for the new admin user'); + } + if (empty($details['password'])) { + $details['password'] = $this->ask('Please specify a password for the new admin user (8 characters min)'); + } + + $validator = Validator::make($details, [ + 'email' => ['required', 'email', 'min:5', new Unique('users', 'email')], + 'name' => ['required', 'min:2'], + 'password' => ['required', Password::default()], + ]); + + if ($validator->fails()) { + foreach ($validator->errors()->all() as $error) { + $this->error($error); + } return SymfonyCommand::FAILURE; } - if ($this->userRepo->getByEmail($email) !== null) { - $this->error('A user with the provided email already exists!'); - - return SymfonyCommand::FAILURE; - } - - $name = trim($this->option('name')); - if (empty($name)) { - $name = $this->ask('Please specify an name for the new admin user'); - } - if (mb_strlen($name) < 2) { - $this->error('Invalid name provided'); - - return SymfonyCommand::FAILURE; - } - - $password = trim($this->option('password')); - if (empty($password)) { - $password = $this->secret('Please specify a password for the new admin user'); - } - if (mb_strlen($password) < 5) { - $this->error('Invalid password provided, Must be at least 5 characters'); - - return SymfonyCommand::FAILURE; - } - - $user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]); + $user = $this->userRepo->create($validator->validated()); $this->userRepo->attachSystemRole($user, 'admin'); $this->userRepo->downloadAndAssignUserAvatar($user); $user->email_confirmed = true; diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index d4e7fcb8e..9399e8b7f 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -13,6 +13,7 @@ use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\Rules\Password; class RegisterController extends Controller { @@ -70,7 +71,7 @@ class RegisterController extends Controller return Validator::make($data, [ 'name' => ['required', 'min:2', 'max:255'], 'email' => ['required', 'email', 'max:255', 'unique:users'], - 'password' => ['required', 'min:8'], + 'password' => ['required', Password::default()], ]); } diff --git a/app/Http/Controllers/Auth/UserInviteController.php b/app/Http/Controllers/Auth/UserInviteController.php index df8262e22..27b20f831 100644 --- a/app/Http/Controllers/Auth/UserInviteController.php +++ b/app/Http/Controllers/Auth/UserInviteController.php @@ -11,6 +11,7 @@ use Exception; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Routing\Redirector; +use Illuminate\Validation\Rules\Password; class UserInviteController extends Controller { @@ -55,7 +56,7 @@ class UserInviteController extends Controller public function setPassword(Request $request, string $token) { $this->validate($request, [ - 'password' => ['required', 'min:8'], + 'password' => ['required', Password::default()], ]); try { diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 414bfefeb..a78f921f2 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -13,6 +13,7 @@ use BookStack\Uploads\ImageRepo; use Exception; use Illuminate\Http\Request; use Illuminate\Support\Str; +use Illuminate\Validation\Rules\Password; use Illuminate\Validation\ValidationException; class UserController extends Controller @@ -82,7 +83,7 @@ class UserController extends Controller $sendInvite = ($request->get('send_invite', 'false') === 'true'); if ($authMethod === 'standard' && !$sendInvite) { - $validationRules['password'] = ['required', 'min:6']; + $validationRules['password'] = ['required', Password::default()]; $validationRules['password-confirm'] = ['required', 'same:password']; } elseif ($authMethod === 'ldap' || $authMethod === 'saml2' || $authMethod === 'openid') { $validationRules['external_auth_id'] = ['required']; @@ -155,11 +156,11 @@ class UserController extends Controller $this->checkPermissionOrCurrentUser('users-manage', $id); $this->validate($request, [ - 'name' => 'min:2', + 'name' => ['min:2'], 'email' => ['min:2', 'email', 'unique:users,email,' . $id], - 'password' => ['min:6', 'required_with:password_confirm'], + 'password' => ['required_with:password_confirm', Password::default()], 'password-confirm' => ['same:password', 'required_with:password'], - 'setting' => 'array', + 'setting' => ['array'], 'profile_image' => array_merge(['nullable'], $this->getImageValidationRules()), ]); diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 4a626e4fa..b301604a5 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -11,6 +11,7 @@ use BookStack\Auth\Access\LoginService; use BookStack\Auth\Access\RegistrationService; use Illuminate\Support\Facades\Auth; use Illuminate\Support\ServiceProvider; +use Illuminate\Validation\Rules\Password; class AuthServiceProvider extends ServiceProvider { @@ -21,6 +22,12 @@ class AuthServiceProvider extends ServiceProvider */ public function boot() { + // Password Configuration + Password::defaults(function () { + return Password::min(8); + }); + + // Custom guards Auth::extend('api-token', function ($app, $name, array $config) { return new ApiTokenGuard($app['request'], $app->make(LoginService::class)); }); diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php index 107585bf0..ad0d516bb 100644 --- a/resources/lang/en/auth.php +++ b/resources/lang/en/auth.php @@ -21,7 +21,7 @@ return [ 'email' => 'Email', 'password' => 'Password', 'password_confirm' => 'Confirm Password', - 'password_hint' => 'Must be over 7 characters', + 'password_hint' => 'Must be at least 8 characters', 'forgot_password' => 'Forgot Password?', 'remember_me' => 'Remember Me', 'ldap_email_hint' => 'Please enter an email to use for this account.', diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index 1cca516c8..08d4e7294 100755 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -174,7 +174,7 @@ return [ 'users_role' => 'User Roles', 'users_role_desc' => 'Select which roles this user will be assigned to. If a user is assigned to multiple roles the permissions from those roles will stack and they will receive all abilities of the assigned roles.', 'users_password' => 'User Password', - 'users_password_desc' => 'Set a password used to log-in to the application. This must be at least 6 characters long.', + 'users_password_desc' => 'Set a password used to log-in to the application. This must be at least 8 characters long.', 'users_send_invite_text' => 'You can choose to send this user an invitation email which allows them to set their own password otherwise you can set their password yourself.', 'users_send_invite_option' => 'Send user invite email', 'users_external_auth_id' => 'External Authentication ID',