Extract AdminUser class that enforces invariants

This commit is contained in:
Franz Liedke 2019-01-26 01:13:38 +01:00
parent cf56157ec7
commit 1e056b2c50
8 changed files with 104 additions and 45 deletions

View File

@ -0,0 +1,58 @@
<?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 Carbon\Carbon;
use Illuminate\Hashing\BcryptHasher;
class AdminUser
{
private $username;
private $password;
private $email;
public function __construct($username, $password, $email)
{
$this->username = $username;
$this->password = $password;
$this->email = $email;
$this->validate();
}
public function getUsername()
{
return $this->username;
}
public function getAttributes(): array
{
return [
'username' => $this->username,
'email' => $this->email,
'password' => (new BcryptHasher)->make($this->password),
'joined_at' => Carbon::now(),
'is_email_confirmed' => 1,
];
}
private function validate()
{
if (! filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
throw new ValidationFailed('You must enter a valid email.');
}
if (! $this->username || preg_match('/[^a-z0-9_-]/i', $this->username)) {
throw new ValidationFailed('Username can only contain letters, numbers, underscores, and dashes.');
}
}
}

View File

@ -11,13 +11,15 @@
namespace Flarum\Install\Console;
use Flarum\Install\AdminUser;
interface DataProviderInterface
{
public function getDatabaseConfiguration();
public function getBaseUrl();
public function getAdminUser();
public function getAdminUser(): AdminUser;
public function getSettings();

View File

@ -12,6 +12,7 @@
namespace Flarum\Install\Console;
use Exception;
use Flarum\Install\AdminUser;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Yaml\Yaml;
@ -72,13 +73,13 @@ class FileDataProvider implements DataProviderInterface
return $this->baseUrl ?? 'http://flarum.local';
}
public function getAdminUser()
public function getAdminUser(): AdminUser
{
return $this->adminUser + [
'username' => 'admin',
'password' => 'password',
'email' => 'admin@example.com',
];
return new AdminUser(
$this->adminUser['username'] ?? 'admin',
$this->adminUser['password'] ?? 'password',
$this->adminUser['email'] ?? 'admin@example.com'
);
}
public function getSettings()

View File

@ -118,24 +118,13 @@ class InstallCommand extends AbstractCommand
$validation->getMessageBag()->toArray())));
}
$admin = $this->dataSource->getAdminUser();
if (! filter_var($admin['email'], FILTER_VALIDATE_EMAIL)) {
throw new Exception('You must enter a valid email.');
}
if (! $admin['username'] || preg_match('/[^a-z0-9_-]/i',
$admin['username'])) {
throw new Exception('Username can only contain letters, numbers, underscores, and dashes.');
}
$this->runPipeline(
$this->installation
->configPath($this->input->getOption('config'))
->debugMode($this->dataSource->isDebugMode())
->baseUrl($this->dataSource->getBaseUrl())
->databaseConfig($dbConfig)
->adminUser($admin)
->adminUser($this->dataSource->getAdminUser())
->settings($this->dataSource->getSettings())
->build()
);

View File

@ -11,6 +11,7 @@
namespace Flarum\Install\Console;
use Flarum\Install\AdminUser;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@ -61,13 +62,13 @@ class UserDataProvider implements DataProviderInterface
return $this->baseUrl = rtrim($this->ask('Base URL:'), '/');
}
public function getAdminUser()
public function getAdminUser(): AdminUser
{
return [
'username' => $this->ask('Admin username:'),
'password' => $this->askForAdminPassword(),
'email' => $this->ask('Admin email address:'),
];
return new AdminUser(
$this->ask('Admin username:'),
$this->askForAdminPassword(),
$this->ask('Admin email address:')
);
}
private function askForAdminPassword()

View File

@ -12,6 +12,7 @@
namespace Flarum\Install\Controller;
use Flarum\Http\SessionAuthenticator;
use Flarum\Install\AdminUser;
use Flarum\Install\Installation;
use Flarum\Install\StepFailed;
use Flarum\Install\ValidationFailed;
@ -75,11 +76,7 @@ class InstallController implements RequestHandlerInterface
'prefix' => array_get($input, 'tablePrefix'),
'strict' => false,
])
->adminUser([
'username' => array_get($input, 'adminUsername'),
'password' => $this->getConfirmedAdminPassword($input),
'email' => array_get($input, 'adminEmail'),
])
->adminUser($this->makeAdminUser($input))
->settings([
'forum_title' => array_get($input, 'forumTitle'),
'mail_from' => 'noreply@'.preg_replace('/^www\./i', '', parse_url($baseUrl, PHP_URL_HOST)),
@ -102,7 +99,21 @@ class InstallController implements RequestHandlerInterface
return new Response\EmptyResponse;
}
private function getConfirmedAdminPassword(array $input)
/**
* @param array $input
* @return AdminUser
* @throws ValidationFailed
*/
private function makeAdminUser(array $input): AdminUser
{
return new AdminUser(
array_get($input, 'adminUsername'),
$this->getConfirmedAdminPassword($input),
array_get($input, 'adminEmail')
);
}
private function getConfirmedAdminPassword(array $input): string
{
$password = array_get($input, 'adminPassword');
$confirmation = array_get($input, 'adminPasswordConfirmation');

View File

@ -22,7 +22,9 @@ class Installation
private $dbConfig = [];
private $baseUrl;
private $customSettings = [];
private $adminUser = [];
/** @var AdminUser */
private $adminUser;
// A few instance variables to persist objects between steps.
// Could also be local variables in build(), but this way
@ -73,7 +75,7 @@ class Installation
return $this;
}
public function adminUser($admin)
public function adminUser(AdminUser $admin)
{
$this->adminUser = $admin;

View File

@ -11,11 +11,10 @@
namespace Flarum\Install\Steps;
use Carbon\Carbon;
use Flarum\Group\Group;
use Flarum\Install\AdminUser;
use Flarum\Install\Step;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Hashing\BcryptHasher;
class CreateAdminUser implements Step
{
@ -25,11 +24,11 @@ class CreateAdminUser implements Step
private $database;
/**
* @var array
* @var AdminUser
*/
private $admin;
public function __construct(ConnectionInterface $database, array $admin)
public function __construct(ConnectionInterface $database, AdminUser $admin)
{
$this->database = $database;
$this->admin = $admin;
@ -37,18 +36,14 @@ class CreateAdminUser implements Step
public function getMessage()
{
return 'Creating admin user '.$this->admin['username'];
return 'Creating admin user '.$this->admin->getUsername();
}
public function run()
{
$uid = $this->database->table('users')->insertGetId([
'username' => $this->admin['username'],
'email' => $this->admin['email'],
'password' => (new BcryptHasher)->make($this->admin['password']),
'joined_at' => Carbon::now(),
'is_email_confirmed' => 1,
]);
$uid = $this->database->table('users')->insertGetId(
$this->admin->getAttributes()
);
$this->database->table('group_user')->insert([
'user_id' => $uid,