Skip to content

Commit

Permalink
allow security:form-login non interractive
Browse files Browse the repository at this point in the history
  • Loading branch information
eltharin committed Sep 17, 2024
1 parent fb404cc commit 3890465
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/Maker/Common/CanGenerateTestsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public function interactSetGenerateTests(InputInterface $input, ConsoleStyle $io

if (!$this->generateTests) {
$this->generateTests = $io->confirm('Do you want to generate PHPUnit tests? [Experimental]', false);
$input->setOption('with-tests', $this->generateTests);
}
}

Expand Down
62 changes: 41 additions & 21 deletions src/Maker/Security/MakeFormLogin.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
Expand All @@ -57,11 +59,10 @@ final class MakeFormLogin extends AbstractMaker

private const SECURITY_CONFIG_PATH = 'config/packages/security.yaml';
private YamlSourceManipulator $ysm;
private string $controllerName;
private string $firewallToUpdate;
private string $userClass;
private string $userNameField;
private bool $willLogout;
private ?array $securityData = null;

Check failure on line 65 in src/Maker/Security/MakeFormLogin.php

View workflow job for this annotation

GitHub Actions / PHPStan

Property Symfony\Bundle\MakerBundle\Maker\Security\MakeFormLogin::$securityData type has no value type specified in iterable type array.

public function __construct(
private FileManager $fileManager,
Expand All @@ -77,9 +78,12 @@ public static function getCommandName(): string

public function configureCommand(Command $command, InputConfiguration $inputConfig): void
{
$command->setHelp(file_get_contents(\dirname(__DIR__, 2).'/Resources/help/security/MakeFormLogin.txt'));
$command->addArgument('controllerName', InputArgument::OPTIONAL, 'The class name of the Controller (e.g. <fg=yellow>SecurityController</>)')
->addOption('will-logout', null, InputOption::VALUE_NONE, 'Will generate a \'/logout\' URL? ')
->setHelp(file_get_contents(\dirname(__DIR__, 2).'/Resources/help/security/MakeFormLogin.txt'));

$this->configureCommandWithTestsOption($command);
$inputConfig->setArgumentAsNonInteractive('controllerName');
}

public static function getCommandDescription(): string
Expand Down Expand Up @@ -111,38 +115,44 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
throw new RuntimeCommandException(\sprintf('The file "%s" does not exist. PHP & XML configuration formats are currently not supported.', self::SECURITY_CONFIG_PATH));
}

$this->ysm = new YamlSourceManipulator($this->fileManager->getFileContents(self::SECURITY_CONFIG_PATH));
$securityData = $this->ysm->getData();
$securityData = $this->getSecurityData();

if (!isset($securityData['security']['providers']) || !$securityData['security']['providers']) {
throw new RuntimeCommandException('To generate a form login authentication, you must configure at least one entry under "providers" in "security.yaml".');
}

$this->controllerName = $io->ask(
'Choose a name for the controller class (e.g. <fg=yellow>SecurityController</>)',
'SecurityController',
Validator::validateClassName(...)
);
if (null === $input->getArgument('controllerName')) {
$input->setArgument(
'controllerName', $input->getArgument('controllerName') ?? $io->ask(

Check failure on line 126 in src/Maker/Security/MakeFormLogin.php

View workflow job for this annotation

GitHub Actions / PHPStan

Expression on left side of ?? is always null.
'Choose a name for the controller class (e.g. <fg=yellow>SecurityController</>)',
'SecurityController',
Validator::validateClassName(...)
));
}

$securityHelper = new InteractiveSecurityHelper();
$this->firewallToUpdate = $securityHelper->guessFirewallName($io, $securityData);
$this->userClass = $securityHelper->guessUserClass($io, $securityData['security']['providers']);
$this->userNameField = $securityHelper->guessUserNameField($io, $this->userClass, $securityData['security']['providers']);
$this->willLogout = $io->confirm('Do you want to generate a \'/logout\' URL?');
if (false === $input->getOption('will-logout')) {
$input->setOption('will-logout',$io->confirm('Do you want to generate a \'/logout\' URL?'));
}

$this->interactSetGenerateTests($input, $io);
}

public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void
{
$securityData = $this->getSecurityData();
$securityHelper = new InteractiveSecurityHelper();
$this->firewallToUpdate = $securityHelper->guessFirewallName($io, $securityData);
$this->userClass = $securityHelper->guessUserClass($io, $securityData['security']['providers']);
$this->userNameField = $securityHelper->guessUserNameField($io, $this->userClass, $securityData['security']['providers']);

$useStatements = new UseStatementGenerator([
AbstractController::class,
Response::class,
Route::class,
AuthenticationUtils::class,
]);

$controllerNameDetails = $generator->createClassNameDetails($this->controllerName, 'Controller\\', 'Controller');
$controllerNameDetails = $generator->createClassNameDetails($input->getArgument('controllerName'), 'Controller\\', 'Controller');
$templatePath = strtolower($controllerNameDetails->getRelativeNameWithoutSuffix());

$controllerPath = $generator->generateController(
Expand All @@ -155,7 +165,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
]
);

if ($this->willLogout) {
if ($input->getOption('will-logout')) {
$manipulator = new ClassSourceManipulator($generator->getFileContentsForPendingOperation($controllerPath));

$this->securityControllerBuilder->addLogoutMethod($manipulator);
Expand All @@ -167,26 +177,26 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
\sprintf('%s/login.html.twig', $templatePath),
'security/formLogin/login_form.tpl.php',
[
'logout_setup' => $this->willLogout,
'logout_setup' => $input->getOption('will-logout'),
'username_label' => Str::asHumanWords($this->userNameField),
'username_is_email' => false !== stripos($this->userNameField, 'email'),
]
);

$securityData = $this->securityConfigUpdater->updateForFormLogin($this->ysm->getContents(), $this->firewallToUpdate, 'app_login', 'app_login');

if ($this->willLogout) {
if ($input->getOption('will-logout')) {
$securityData = $this->securityConfigUpdater->updateForLogout($securityData, $this->firewallToUpdate);
}

if ($this->shouldGenerateTests()) {
if ($input->getOption('with-tests')) {
$userClassNameDetails = $generator->createClassNameDetails(
'\\'.$this->userClass,
'Entity\\'
);

$testClassDetails = $generator->createClassNameDetails(
'LoginControllerTest',
$controllerNameDetails->getShortName() . 'Test',
'Test\\',
);

Expand Down Expand Up @@ -223,4 +233,14 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
\sprintf('Next: Review and adapt the login template: <info>%s/login.html.twig</info> to suit your needs.', $templatePath),
]);
}

private function getSecurityData(): array

Check failure on line 237 in src/Maker/Security/MakeFormLogin.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Symfony\Bundle\MakerBundle\Maker\Security\MakeFormLogin::getSecurityData() return type has no value type specified in iterable type array.
{
if (null === $this->securityData)
{
$this->ysm = new YamlSourceManipulator($this->fileManager->getFileContents(self::SECURITY_CONFIG_PATH));
$this->securityData = $this->ysm->getData();
}
return $this->securityData;
}
}

0 comments on commit 3890465

Please sign in to comment.