Skip to content

Commit 86a9c9c

Browse files
committed
Fixed the ordering argument for the UserPasswordEncoderCommand by using options
1 parent d10cdd6 commit 86a9c9c

File tree

2 files changed

+64
-27
lines changed

2 files changed

+64
-27
lines changed

src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
namespace Symfony\Bundle\SecurityBundle\Command;
1313

1414
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
15+
use Symfony\Component\Console\Helper\Table;
1516
use Symfony\Component\Console\Input\InputArgument;
1617
use Symfony\Component\Console\Input\InputInterface;
18+
use Symfony\Component\Console\Input\InputOption;
1719
use Symfony\Component\Console\Output\OutputInterface;
1820
use Symfony\Component\Console\Question\Question;
19-
use Symfony\Component\Console\Helper\Table;
2021

2122
/**
2223
* Encode a user's password.
@@ -32,10 +33,10 @@ protected function configure()
3233
{
3334
$this
3435
->setName('security:encode-password')
35-
->setDescription('Encode a password.')
36+
->setDescription('Encodes a password.')
3637
->addArgument('password', InputArgument::OPTIONAL, 'Enter a password')
37-
->addArgument('user-class', InputArgument::OPTIONAL, 'Enter the user class configured to find the encoder you need.')
38-
->addArgument('salt', InputArgument::OPTIONAL, 'Enter the salt you want to use to encode your password.')
38+
->addOption('user-class', null, InputOption::VALUE_REQUIRED, 'Enter the user class configured to find the encoder you need.')
39+
->addOption('salt', null, InputOption::VALUE_REQUIRED, 'Enter the salt you want to use to encode your password.')
3940
->setHelp(<<<EOF
4041
4142
The <info>%command.name%</info> command allows to encode a password using encoders
@@ -59,8 +60,10 @@ protected function configure()
5960
The command allows you to provide your own <comment>salt</comment>. If you don't provide any,
6061
the command will take care about that for you.
6162
62-
You can also use the non interactive way by typing the following command:
63-
<info>php %command.full_name% [password] [user-class] [salt]</info>
63+
You can also use the non interactive way:
64+
- the very simple way is to simply type: <info>php %command.full_name% [password] -n</info>. The salt will be generated
65+
for you, and the configuration of the <comment>Symfony\Component\Security\Core\User\User</comment> class will be taken to grab the right encoder.
66+
- You can also provide the salt and the user class by typing: <info>php %command.full_name% [password] --salt=[salt] --user-class=[namespace-class]</info>
6467
6568
EOF
6669
)
@@ -75,8 +78,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
7578
$this->writeIntroduction($output);
7679

7780
$password = $input->getArgument('password');
78-
$salt = $input->getArgument('salt');
79-
$userClass = $input->getArgument('user-class');
81+
$salt = $input->getOption('salt');
82+
$userClass = $input->getOption('user-class');
8083

8184
$helper = $this->getHelper('question');
8285

@@ -86,15 +89,24 @@ protected function execute(InputInterface $input, OutputInterface $output)
8689
}
8790

8891
if (!$salt) {
89-
$saltQuestion = $this->createSaltQuestion($input, $output);
90-
$salt = $helper->ask($input, $output, $saltQuestion);
92+
if ($input->isInteractive()) {
93+
$saltQuestion = $this->createSaltQuestion($input, $output);
94+
$salt = $helper->ask($input, $output, $saltQuestion);
95+
} else {
96+
$salt = $this->generateSalt($output);
97+
}
9198
}
9299

93100
$output->writeln("\n <comment>Encoders are configured by user type in the security.yml file.</comment>");
94101

95-
if (!$userClass) {
96-
$userClassQuestion = $this->createUserClassQuestion($input, $output);
97-
$userClass = $helper->ask($input, $output, $userClassQuestion);
102+
if (!$userClass && $input->isInteractive()) {
103+
104+
if ($input->isInteractive()) {
105+
$userClassQuestion = $this->createUserClassQuestion($input, $output);
106+
$userClass = $helper->ask($input, $output, $userClassQuestion);
107+
} else {
108+
$userClass = 'Symfony\Component\Security\Core\User\User';
109+
}
98110
}
99111

100112
$encoder = $this->getContainer()->get('security.encoder_factory')->getEncoder($userClass);
@@ -148,15 +160,13 @@ private function createPasswordQuestion(InputInterface $input, OutputInterface $
148160
*/
149161
private function createSaltQuestion(InputInterface $input, OutputInterface $output)
150162
{
163+
$output->writeln('<comment>Caution: It is strongly recommended that you do not generate your own salt for this function. It will create a secure salt automatically for you if you do not specify one.</comment>');
151164
$saltQuestion = new Question("\n > (Optional) <question>Provide a salt (press <enter> to generate one):</question> ");
152165

153-
$container = $this->getContainer();
154-
$saltQuestion->setValidator(function ($value) use ($output, $container) {
166+
$that = $this;
167+
$saltQuestion->setValidator(function ($value) use ($output, $that) {
155168
if ('' === trim($value)) {
156-
$value = hash('sha512', $container->get('security.secure_random')->nextBytes(30));
157-
158-
$output->writeln("\n<comment>The salt has been generated: </comment>".$value);
159-
$output->writeln(sprintf("<comment>Make sure that your salt storage field fits this salt length: %s chars.</comment>\n", strlen($value)));
169+
$value = $that->generateSalt($output);
160170
}
161171

162172
return $value;
@@ -222,4 +232,17 @@ private function writeResult(OutputInterface $output)
222232
'',
223233
));
224234
}
235+
236+
/*
237+
* @internal
238+
*/
239+
public function generateSalt(OutputInterface $output)
240+
{
241+
$value = base64_encode($this->getContainer()->get('security.secure_random')->nextBytes(16));
242+
243+
$output->writeln("\n<comment>The salt has been generated: </comment>".$value);
244+
$output->writeln(sprintf("<comment>Make sure that your salt storage field fits this salt length: %s chars.</comment>\n", strlen($value)));
245+
246+
return $value;
247+
}
225248
}

src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public function testEncodePasswordPasswordPlainText()
2929
$this->passwordEncoderCommandTester->execute(array(
3030
'command' => 'security:encode-password',
3131
'password' => 'password',
32-
'user-class' => 'Symfony\Component\Security\Core\User\User',
33-
'salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
32+
'--user-class' => 'Symfony\Component\Security\Core\User\User',
33+
'--salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
3434
));
3535
$expected = file_get_contents(__DIR__.'/app/PasswordEncode/plaintext.txt');
3636

@@ -42,8 +42,8 @@ public function testEncodePasswordBcrypt()
4242
$this->passwordEncoderCommandTester->execute(array(
4343
'command' => 'security:encode-password',
4444
'password' => 'password',
45-
'user-class' => 'Custom\Class\Bcrypt\User',
46-
'salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
45+
'--user-class' => 'Custom\Class\Bcrypt\User',
46+
'--salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
4747
));
4848
$expected = file_get_contents(__DIR__.'/app/PasswordEncode/bcrypt.txt');
4949

@@ -55,8 +55,8 @@ public function testEncodePasswordPbkdf2()
5555
$this->passwordEncoderCommandTester->execute(array(
5656
'command' => 'security:encode-password',
5757
'password' => 'password',
58-
'user-class' => 'Custom\Class\Pbkdf2\User',
59-
'salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
58+
'--user-class' => 'Custom\Class\Pbkdf2\User',
59+
'--salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
6060
));
6161

6262
$expected = file_get_contents(__DIR__.'/app/PasswordEncode/pbkdf2.txt');
@@ -71,11 +71,25 @@ public function testEncodePasswordNoConfigForGivenUserClass()
7171
$this->passwordEncoderCommandTester->execute(array(
7272
'command' => 'security:encode-password',
7373
'password' => 'password',
74-
'user-class' => 'Wrong/User/Class',
75-
'salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
74+
'--user-class' => 'Wrong/User/Class',
75+
'--salt' => 'AZERTYUIOPOfghjklytrertyuiolnbcxdfghjkytrfghjk',
7676
));
7777
}
7878

79+
public function testEncodePasswordWithNoSaltNoInteraction()
80+
{
81+
$this->passwordEncoderCommandTester->execute(
82+
array(
83+
'command' => 'security:encode-password',
84+
'password' => 'password',
85+
'--user-class' => 'Symfony\Component\Security\Core\User\User',
86+
),
87+
array('interactive' => false)
88+
);
89+
90+
$this->assertRegExp('/Password encoding succeeded/', $this->passwordEncoderCommandTester->getDisplay());
91+
}
92+
7993
protected function setUp()
8094
{
8195
$kernel = $this->createKernel(array('test_case' => 'PasswordEncode'));

0 commit comments

Comments
 (0)