Move password confirmation validation to frontends

Since this is not strictly speaking a domain invariant, but rather
specific to the user interface where passwords are not displayed, and
should therefore be entered twice to prevent mistakes going unnoticed,
this stuff should be checked in the frontend, not in the install steps.

Next step: Ensure that all domain-specific validation is done in the
installer's domain layer. This will ensure these validations cannot be
forgotten, and keep the frontends DRY.
This commit is contained in:
Franz Liedke 2019-01-26 00:51:28 +01:00
parent ec88138f1d
commit cf56157ec7
6 changed files with 90 additions and 44 deletions

View File

@ -77,7 +77,6 @@ class FileDataProvider implements DataProviderInterface
return $this->adminUser + [
'username' => 'admin',
'password' => 'password',
'password_confirmation' => 'password',
'email' => 'admin@example.com',
];
}

View File

@ -120,14 +120,6 @@ class InstallCommand extends AbstractCommand
$admin = $this->dataSource->getAdminUser();
if (strlen($admin['password']) < 8) {
throw new Exception('Password must be at least 8 characters.');
}
if ($admin['password'] !== $admin['password_confirmation']) {
throw new Exception('The password did not match its confirmation.');
}
if (! filter_var($admin['email'], FILTER_VALIDATE_EMAIL)) {
throw new Exception('You must enter a valid email.');
}

View File

@ -65,12 +65,32 @@ class UserDataProvider implements DataProviderInterface
{
return [
'username' => $this->ask('Admin username:'),
'password' => $this->secret('Admin password:'),
'password_confirmation' => $this->secret('Admin password (confirmation):'),
'password' => $this->askForAdminPassword(),
'email' => $this->ask('Admin email address:'),
];
}
private function askForAdminPassword()
{
while (true) {
$password = $this->secret('Admin password:');
if (strlen($password) < 8) {
$this->validationError('Password must be at least 8 characters.');
continue;
}
$confirmation = $this->secret('Admin password (confirmation):');
if ($password !== $confirmation) {
$this->validationError('The password did not match its confirmation.');
continue;
}
return $password;
}
}
public function getSettings()
{
$title = $this->ask('Forum title:');
@ -99,6 +119,12 @@ class UserDataProvider implements DataProviderInterface
return $this->questionHelper->ask($this->input, $this->output, $question);
}
protected function validationError($message)
{
$this->output->writeln("<error>$message</error>");
$this->output->writeln('Please try again.');
}
public function isDebugMode(): bool
{
return false;

View File

@ -14,6 +14,7 @@ namespace Flarum\Install\Controller;
use Flarum\Http\SessionAuthenticator;
use Flarum\Install\Installation;
use Flarum\Install\StepFailed;
use Flarum\Install\ValidationFailed;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface;
@ -59,6 +60,7 @@ class InstallController implements RequestHandlerInterface
$baseUrl = rtrim((string) $request->getUri(), '/');
try {
$pipeline = $this->installation
->baseUrl($baseUrl)
->databaseConfig([
@ -75,8 +77,7 @@ class InstallController implements RequestHandlerInterface
])
->adminUser([
'username' => array_get($input, 'adminUsername'),
'password' => array_get($input, 'adminPassword'),
'password_confirmation' => array_get($input, 'adminPasswordConfirmation'),
'password' => $this->getConfirmedAdminPassword($input),
'email' => array_get($input, 'adminEmail'),
])
->settings([
@ -85,6 +86,9 @@ class InstallController implements RequestHandlerInterface
'welcome_title' => 'Welcome to '.array_get($input, 'forumTitle'),
])
->build();
} catch (ValidationFailed $e) {
return new Response\HtmlResponse($e->getMessage(), 500);
}
try {
$pipeline->run();
@ -97,4 +101,16 @@ class InstallController implements RequestHandlerInterface
return new Response\EmptyResponse;
}
private function getConfirmedAdminPassword(array $input)
{
$password = array_get($input, 'adminPassword');
$confirmation = array_get($input, 'adminPasswordConfirmation');
if ($password !== $confirmation) {
throw new ValidationFailed('The admin password did not match its confirmation.');
}
return $password;
}
}

View File

@ -16,7 +16,6 @@ use Flarum\Group\Group;
use Flarum\Install\Step;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Hashing\BcryptHasher;
use UnexpectedValueException;
class CreateAdminUser implements Step
{
@ -43,10 +42,6 @@ class CreateAdminUser implements Step
public function run()
{
if ($this->admin['password'] !== $this->admin['password_confirmation']) {
throw new UnexpectedValueException('The password did not match its confirmation.');
}
$uid = $this->database->table('users')->insertGetId([
'username' => $this->admin['username'],
'email' => $this->admin['email'],

View File

@ -0,0 +1,18 @@
<?php
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flarum\Install;
use Exception;
class ValidationFailed extends Exception
{
}