add admin command

This commit is contained in:
Yisroel Baum 2026-07-02 01:21:04 +03:00
parent 4462879b7d
commit fee174ec05
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
7 changed files with 120 additions and 0 deletions

View file

@ -0,0 +1,36 @@
<?php
namespace App\Console\Commands;
use App\User\InitialAdminCredentialsProvider;
use App\User\UseCases\EnsureInitialAdmin\EnsureInitialAdmin;
use App\User\UseCases\EnsureInitialAdmin\EnsureInitialAdminRequest;
use Illuminate\Console\Command;
class EnsureInitialAdminCommand extends Command
{
protected $signature = 'rabbi-gerzi:ensure-initial-admin';
protected $description = 'Create the configured initial admin if missing';
public function __construct(
private EnsureInitialAdmin $ensureInitialAdmin,
private InitialAdminCredentialsProvider $credentialsProvider,
) {
parent::__construct();
}
public function handle(): int
{
$credentials = $this->credentialsProvider->getCredentials();
$this->ensureInitialAdmin->execute(new EnsureInitialAdminRequest(
email: $credentials->getEmail(),
password: $credentials->getPassword(),
));
$this->info('initial admin is ready');
return self::SUCCESS;
}
}

View file

@ -11,6 +11,8 @@ use App\Auth\SystemClock;
use App\Auth\TokenGenerator; use App\Auth\TokenGenerator;
use App\Shared\Files\Filesystem; use App\Shared\Files\Filesystem;
use App\Shared\Files\LaravelFilesystem; use App\Shared\Files\LaravelFilesystem;
use App\User\EnvironmentInitialAdminCredentialsProvider;
use App\User\InitialAdminCredentialsProvider;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider class AppServiceProvider extends ServiceProvider
@ -33,6 +35,10 @@ class AppServiceProvider extends ServiceProvider
Filesystem::class, Filesystem::class,
LaravelFilesystem::class, LaravelFilesystem::class,
); );
$this->app->bind(
InitialAdminCredentialsProvider::class,
EnvironmentInitialAdminCredentialsProvider::class,
);
$this->app->bind( $this->app->bind(
AuthCookieSettings::class, AuthCookieSettings::class,
function (): AuthCookieSettings { function (): AuthCookieSettings {

View file

@ -0,0 +1,31 @@
<?php
namespace App\User;
use RuntimeException;
class EnvironmentInitialAdminCredentialsProvider implements
InitialAdminCredentialsProvider
{
public function getCredentials(): InitialAdminCredentials
{
return new InitialAdminCredentials(
email: $this->requiredEnvironmentValue(
'RABBI_GERZI_INITIAL_ADMIN_EMAIL',
),
password: $this->requiredEnvironmentValue(
'RABBI_GERZI_INITIAL_ADMIN_PASSWORD',
),
);
}
private function requiredEnvironmentValue(string $key): string
{
$value = getenv($key);
if (! is_string($value) || trim($value) === '') {
throw new RuntimeException("$key is required");
}
return $value;
}
}

View file

@ -0,0 +1,22 @@
<?php
namespace App\User;
class InitialAdminCredentials
{
public function __construct(
private string $email,
private string $password,
) {
}
public function getEmail(): string
{
return $this->email;
}
public function getPassword(): string
{
return $this->password;
}
}

View file

@ -0,0 +1,8 @@
<?php
namespace App\User;
interface InitialAdminCredentialsProvider
{
public function getCredentials(): InitialAdminCredentials;
}

View file

@ -1,5 +1,6 @@
<?php <?php
use App\Console\Commands\EnsureInitialAdminCommand;
use Illuminate\Foundation\Application; use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions; use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware; use Illuminate\Foundation\Configuration\Middleware;
@ -10,6 +11,9 @@ return Application::configure(basePath: dirname(__DIR__))
commands: __DIR__ . '/../routes/console.php', commands: __DIR__ . '/../routes/console.php',
health: '/up', health: '/up',
) )
->withCommands([
EnsureInitialAdminCommand::class,
])
->withMiddleware(function (Middleware $middleware): void { ->withMiddleware(function (Middleware $middleware): void {
// //
}) })

View file

@ -7,6 +7,7 @@ use App\Shared\ValueObject\EmailAddress;
use App\User\InitialAdminCredentials; use App\User\InitialAdminCredentials;
use App\User\InitialAdminCredentialsProvider; use App\User\InitialAdminCredentialsProvider;
use App\User\UseCases\EnsureInitialAdmin\EnsureInitialAdmin; use App\User\UseCases\EnsureInitialAdmin\EnsureInitialAdmin;
use Illuminate\Container\Container;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
use Tests\Fakes\FakeHasher; use Tests\Fakes\FakeHasher;
use Tests\Fakes\FakeUserRepository; use Tests\Fakes\FakeUserRepository;
@ -25,6 +26,7 @@ class EnsureInitialAdminCommandTest extends TestCase
'secret-password', 'secret-password',
), ),
); );
$command->setLaravel($this->consoleContainer());
$commandTester = new CommandTester($command); $commandTester = new CommandTester($command);
$statusCode = $commandTester->execute([]); $statusCode = $commandTester->execute([]);
@ -67,4 +69,15 @@ class EnsureInitialAdminCommandTest extends TestCase
} }
}; };
} }
private function consoleContainer(): Container
{
return new class extends Container
{
public function runningUnitTests(): bool
{
return true;
}
};
}
} }