. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Cli\Commands; use Composer\Console\Input\InputOption; use Fisharebest\Webtrees\Contracts\UserInterface; use Fisharebest\Webtrees\DB; use Fisharebest\Webtrees\Services\UserService; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use function bin2hex; use function random_bytes; class UserCreate extends Command { public function __construct(private readonly UserService $user_service) { parent::__construct(); } protected function configure(): void { $this ->setName(name: 'user-create') ->setDescription(description: 'Create a new user account') ->addOption(name: 'admin', shortcut: 'a', mode: InputOption::VALUE_NONE, description: 'Make the new user an administrator') ->addOption(name: 'username', shortcut: 'u', mode: InputOption::VALUE_REQUIRED, description: 'The username of the new user') ->addOption(name: 'realname', shortcut: 'r', mode: InputOption::VALUE_REQUIRED, description: 'The real name of the new user') ->addOption(name: 'email', shortcut: 'e', mode: InputOption::VALUE_REQUIRED, description: 'The email of the new user') ->addOption(name: 'password', shortcut: 'p', mode: InputOption::VALUE_OPTIONAL, description: 'The password of the new user'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle(input: $input, output: $output); $username = $input->getOption(name: 'username'); $realname = $input->getOption(name: 'realname'); $email = $input->getOption(name: 'email'); $password = $input->getOption(name: 'password'); $admin = (bool) $input->getOption(name: 'admin'); $missing = false; if ($username === null) { $io->error(message: 'Missing required option: --username'); $missing = true; } if ($realname === null) { $io->error(message: 'Missing required option: --realname'); $missing = true; } if ($email === null) { $io->error(message: 'Missing required option: --email'); $missing = true; } if ($missing) { return Command::FAILURE; } $user = $this->user_service->findByUserName(user_name: $username); if ($user !== null) { $io->error(message: 'A user with the username "' . $username . '" already exists.'); return Command::FAILURE; } $user = $this->user_service->findByEmail(email: $email); if ($user !== null) { $io->error(message: 'A user with the email "' . $email . '" already exists'); return Command::FAILURE; } if ($password === null) { $password = bin2hex(string: random_bytes(length: 8)); $io->info(message: 'Generated password: ' . $password); } $user = $this->user_service->create(user_name: $username, real_name:$realname, email: $email, password: $password); $user->setPreference(setting_name: UserInterface::PREF_IS_ACCOUNT_APPROVED, setting_value: '1'); $user->setPreference(setting_name: UserInterface::PREF_IS_EMAIL_VERIFIED, setting_value: '1'); $io->success('User ' . $user->id() . ' created.'); if ($admin) { $user->setPreference(setting_name: UserInterface::PREF_IS_ADMINISTRATOR, setting_value: '1'); $io->success(message: 'User granted administrator role.'); } DB::exec(sql: 'COMMIT'); return Command::SUCCESS; } }