feat(install): init database and create superadmin using CLI

closes #380
This commit is contained in:
Yassine Doghri 2023-11-16 11:01:41 +00:00
parent 97d793f55e
commit 02d4ba69ac
3 changed files with 195 additions and 0 deletions

View File

@ -123,6 +123,23 @@ based on the `.env.example` file.
:::
### Using CLI
1. Create a `.env` file in the package root based on the `.env.example` file.
2. Initialize the database using:
```sh
php spark install:init-database
```
3. Create the superadmin user using:
```sh
php spark install:create-superadmin
```
4. Head on to your admin gateway to start podcasting!
### Email/SMTP setup
Email configuration is required for some features to work properly (eg.

View File

@ -0,0 +1,139 @@
<?php
declare(strict_types=1);
namespace Modules\Install\Commands;
use CodeIgniter\Shield\Commands\BaseCommand;
use CodeIgniter\Shield\Commands\Exceptions\BadInputException;
use CodeIgniter\Shield\Commands\Exceptions\CancelException;
use CodeIgniter\Shield\Entities\User;
use CodeIgniter\Shield\Validation\ValidationRules;
class CreateSuperadmin extends BaseCommand
{
/**
* @var string
*/
protected $group = 'Install';
/**
* @var string
*/
protected $name = 'install:create-superadmin';
/**
* @var string
*/
protected $description = 'Creates the instance superadmin.';
/**
* Validation rules for user fields
*
* @var array<string, array<string, array{rules: string[]}>>
*/
private array $validationRules = [];
public function run(array $params): void
{
// first, check that super admin does not exist
$userModel = model('UserModel');
$isSuperAdminCreated = $userModel->where('is_owner', true)
->countAllResults();
if ($isSuperAdminCreated > 0) {
$this->write('Super admin was already created!', 'red');
exit(EXIT_ERROR);
}
$this->setValidationRules();
$username = $params['n'] ?? null;
$email = $params['e'] ?? null;
$data = [
'is_owner' => true,
];
if ($username === null) {
$username = $this->prompt('Username', null, $this->validationRules['username']['rules']);
}
$data['username'] = $username;
if ($email === null) {
$email = $this->prompt('Email', null, $this->validationRules['email']['rules']);
}
$data['email'] = $email;
$password = $this->prompt('Password', null, $this->validationRules['password']['rules']);
$passwordConfirm = $this->prompt(
'Password confirmation',
null,
$this->validationRules['password']['rules']
);
if ($password !== $passwordConfirm) {
throw new BadInputException("The passwords don't match");
}
$data['password'] = $password;
// Run validation if the user has passed username and/or email via command line
$validation = service('validation');
$validation->setRules($this->validationRules);
if (! $validation->run($data)) {
foreach ($validation->getErrors() as $message) {
$this->write($message, 'red');
}
throw new CancelException('Super admin creation aborted');
}
$userModel = model('UserModel');
$user = new User($data);
$userModel->save($user);
$this->write('Super admin "' . $username . '" created', 'green');
}
private function setValidationRules(): void
{
$validationRules = new ValidationRules();
$rules = $validationRules->getRegistrationRules();
// Remove `strong_password` because it only supports use cases
// to check the user's own password.
$passwordRules = $rules['password']['rules'];
if (is_string($passwordRules)) {
$passwordRules = explode('|', $passwordRules);
}
if (($key = array_search('strong_password[]', $passwordRules, true)) !== false) {
unset($passwordRules[$key]);
}
if (($key = array_search('strong_password', $passwordRules, true)) !== false) {
unset($passwordRules[$key]);
}
/** @var Auth $config */
$config = config('Auth');
// Add `min_length`
$passwordRules[] = 'min_length[' . $config->minimumPasswordLength . ']';
$rules['password']['rules'] = $passwordRules;
$this->validationRules = [
'username' => $rules['username'],
'email' => $rules['email'],
'password' => $rules['password'],
];
}
}

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Modules\Install\Commands;
use CodeIgniter\CLI\BaseCommand;
use Config\Database;
use Config\Services;
class InitDatabase extends BaseCommand
{
/**
* @var string
*/
protected $group = 'Install';
/**
* @var string
*/
protected $name = 'install:init-database';
/**
* @var string
*/
protected $description = 'Runs all database migrations for Castopod.';
public function run(array $params): void
{
// Run all migrations
$migrate = Services::migrations();
$migrate->setNamespace(null)
->latest();
// Seed database
$seeder = Database::seeder();
$seeder->call('AppSeeder');
}
}