Commit e88229f8 authored by Cédric Girardot's avatar Cédric Girardot

Fix #5 : Modifie commande d'ajout utilisateur - possible sans intéraction

Change-Id: I51eb8af8bd1d225e4508c9aa776b6a90f2a493c9
parent 37060a56
Pipeline #10564 failed with stages
in 3 minutes and 39 seconds
......@@ -10,10 +10,13 @@ use App\Utility\Validator;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Contracts\Translation\TranslatorInterface;
use function Symfony\Component\String\u;
class AddClientCommand extends Command
{
......@@ -49,7 +52,22 @@ class AddClientCommand extends Command
protected function configure()
{
$this
->setDescription('Ajout d\'un nouvel utilisateur en base de données');
->setDescription('Ajout d\'un nouvel utilisateur en base de données')
->addOption('username', 'u', InputOption::VALUE_REQUIRED, 'Identifiant du nouvel utilisateur')
->addOption('password', 'p', InputOption::VALUE_REQUIRED, 'Mot de passe du nouvel utilisateur')
->addOption('email', 'm', InputOption::VALUE_REQUIRED, 'Email du nouvel utilisateur')
->addOption('role', 'r', InputOption::VALUE_REQUIRED, 'Role du nouvel utilisateur')
->addOption('name', 'd', InputOption::VALUE_REQUIRED, 'Nom du nouvel utilisateur')
->addOption('service', null, InputOption::VALUE_OPTIONAL, 'Service du nouvel utilisateur')
->addOption('address', null, InputOption::VALUE_OPTIONAL, 'Adresse du nouvel utilisateur')
->addOption(
'additional-address',
null,
InputOption::VALUE_OPTIONAL,
'Complément d\'adresse du nouvel utilisateur'
)
->addOption('postal-code', null, InputOption::VALUE_OPTIONAL, 'Code postal du nouvel utilisateur')
->addOption('town', null, InputOption::VALUE_OPTIONAL, 'Ville du nouvel utilisateur');
}
protected function initialize(InputInterface $input, OutputInterface $output): void
......@@ -57,121 +75,312 @@ class AddClientCommand extends Command
$this->io = new SymfonyStyle($input, $output);
}
protected function execute(
InputInterface $input,
OutputInterface $output
): int {
protected function interact(InputInterface $input, OutputInterface $output)
{
$this->io->title("Ajout d'un utilisateur");
$username = $this->io->ask(
$this->translator->trans('addUserCmd.login'),
null,
[$this->validator, 'validateUsername']
);
$username = $input->getOption('username');
$user = new User();
$user->setUsername($username);
if (null !== $username) {
$this->io->text(' > <info>'.$this->translator->trans('addUserCmd.login').'</info>: '.$username);
} else {
$username = $this->io->ask(
$this->translator->trans('addUserCmd.login'),
null,
[$this->validator, 'validateUsername']
);
$input->setOption('username', $username);
}
$email = $this->io->ask(
$this->translator->trans('addUserCmd.email'),
null,
[$this->validator, 'validateEmail']
);
$email = $input->getOption('email');
$user->setEmail($email);
if (null !== $email) {
$this->io->text(' > <info>'.$this->translator->trans('addUserCmd.email').'</info>: '.$email);
} else {
$email = $this->io->ask(
$this->translator->trans('addUserCmd.email'),
null,
[$this->validator, 'validateEmail']
);
$input->setOption('email', $email);
}
$password = $this->io->askHidden(
$this->translator->trans('addUserCmd.password'),
[$this->validator, 'validatePassword']
);
$password = $input->getOption('password');
$encodedPassword = $this->passwordEncoder->encodePassword($user, $password);
$user->setPassword($encodedPassword);
if (null !== $password) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.password').'</info>: '
.u('*')->repeat(u($password)->length())
);
} else {
$password = $this->io->askHidden(
$this->translator->trans('addUserCmd.password'),
[$this->validator, 'validatePassword']
);
$confirmPassword = $this->io->askHidden(
$this->translator->trans('addUserCmd.confirmPassword'),
function ($confirmPassword) use ($password) {
if (empty($confirmPassword)) {
throw new \RuntimeException($this->translator->trans('addUser.error.notEmpty'));
}
$confirmPassword = $this->io->askHidden(
$this->translator->trans('addUserCmd.confirmPassword'),
function ($confirmPassword) use ($password) {
if (empty($confirmPassword)) {
throw new \RuntimeException($this->translator->trans('addUser.error.notEmpty'));
}
if ($confirmPassword !== $password) {
throw new \RuntimeException(
$this->translator->trans('addUser.error.confirmPasswordNoMatch')
);
}
if ($confirmPassword !== $password) {
throw new \RuntimeException(
$this->translator->trans('addUser.error.confirmPasswordNoMatch')
);
return $confirmPassword;
}
);
return $confirmPassword;
}
);
if ($password !== $confirmPassword) {
$this->io->error($this->translator->trans('addUser.error.confirmPasswordNoMatch'));
if ($password !== $confirmPassword) {
$this->io->error($this->translator->trans('addUser.error.confirmPasswordNoMatch'));
return 3;
}
return 3;
$input->setOption('password', $password);
}
$rolesList = [
1 => $this->translator->trans('ROLE_NOTARY'),
2 => $this->translator->trans('ROLE_AGENT'),
3 => $this->translator->trans('ROLE_ADMIN'),
];
$roleValue = $this->io->choice($this->translator->trans('addUserCmd.role'), $rolesList, 3);
$roleKey = array_search($roleValue, $rolesList);
$role = UserHelper::getRoleFromInt($roleKey);
$user->setRoles([$role]);
$role = $input->getOption('role');
$name = $this->io->ask(
$this->translator->trans('addUserCmd.name'),
null,
[$this->validator, 'validateNotEmpty']
);
$user->setName($name);
if (null !== $role) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.role').'</info>: '.$role
);
} else {
$rolesList = [
1 => $this->translator->trans('ROLE_NOTARY'),
2 => $this->translator->trans('ROLE_AGENT'),
3 => $this->translator->trans('ROLE_ADMIN'),
];
$roleValue = $this->io->choice($this->translator->trans('addUserCmd.role'), $rolesList, 3);
$roleKey = array_search($roleValue, $rolesList);
$role = UserHelper::getRoleFromInt($roleKey);
if ($role === UserHelper::ROLE_AGENT) {
$service = $this->io->ask(
$this->translator->trans('addUserCmd.service'),
$input->setOption('role', $role);
}
$name = $input->getOption('name');
if (null !== $name) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.name').'</info>: '.$name
);
} else {
$name = $this->io->ask(
$this->translator->trans('addUserCmd.name'),
null,
[$this->validator, 'validateNotEmpty']
);
$user->setService($service);
$input->setOption('name', $name);
}
if ($role === UserHelper::ROLE_AGENT) {
$service = $input->getOption('service');
if (null !== $service) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.service').'</info>: '.$service
);
} else {
$service = $this->io->ask(
$this->translator->trans('addUserCmd.service'),
null,
[$this->validator, 'validateNotEmpty']
);
$input->setOption('service', $service);
}
}
if ($role === UserHelper::ROLE_NOTARY) {
$address = $this->io->ask(
$this->translator->trans('addUserCmd.address'),
null,
[$this->validator, 'validateNotEmpty']
);
$user->setAddress($address);
$address = $input->getOption('address');
$additionalAddress = $this->io->ask(
$this->translator->trans('addUserCmd.additionnalAddress'),
null,
[$this->validator, 'validateNotEmpty']
);
$user->setAdditionalAddress($additionalAddress);
if (null !== $address) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.address').'</info>: '.$address
);
} else {
$address = $this->io->ask(
$this->translator->trans('addUserCmd.address'),
null,
[$this->validator, 'validateNotEmpty']
);
$postalCode = $this->io->ask(
$this->translator->trans('addUserCmd.postalCode'),
null,
[$this->validator, 'validateNotEmpty']
);
$user->setPostalCode($postalCode);
$input->setOption('address', $address);
}
$town = $this->io->ask(
$this->translator->trans('addUserCmd.town'),
null,
[$this->validator, 'validateNotEmpty']
);
$user->setTown($town);
$additionalAddress = $input->getOption('additional-address');
if (null !== $additionalAddress) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.additionalAddress').'</info>: '.$additionalAddress
);
} else {
$additionalAddress = $this->io->ask(
$this->translator->trans('addUserCmd.additionalAddress'),
null,
[$this->validator, 'validateNotEmpty']
);
$input->setOption('additional-address', $additionalAddress);
}
$postalCode = $input->getOption('postal-code');
if (null !== $postalCode) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.postalCode').'</info>: '.$postalCode
);
} else {
$postalCode = $this->io->ask(
$this->translator->trans('addUserCmd.postalCode'),
null,
[$this->validator, 'validateNotEmpty']
);
$input->setOption('postal-code', $postalCode);
}
$town = $input->getOption('town');
if (null !== $town) {
$this->io->text(
' > <info>'.$this->translator->trans('addUserCmd.town').'</info>: '.$town
);
} else {
$town = $this->io->ask(
$this->translator->trans('addUserCmd.town'),
null,
[$this->validator, 'validateNotEmpty']
);
$input->setOption('town', $town);
}
}
}
protected function execute(
InputInterface $input,
OutputInterface $output
): int {
$stopwatch = new Stopwatch();
$stopwatch->start('add-user-command');
$username = $input->getOption('username');
$plainPassword = $input->getOption('password');
$email = $input->getOption('email');
$role = $input->getOption('role');
$name = $input->getOption('name');
$service = $input->getOption('service');
$address = $input->getOption('address');
$additionalAddress = $input->getOption('additional-address');
$postalCode = $input->getOption('postal-code');
$town = $input->getOption('town');
$this->validateUserData(
$username,
$plainPassword,
$email,
$name,
$role,
$service,
$address,
$additionalAddress,
$postalCode,
$town
);
$user = new User();
$user->setUsername($username);
$encodedPassword = $this->passwordEncoder->encodePassword($user, $plainPassword);
$user->setPassword($encodedPassword);
$user->setEmail($email);
$user->setRoles([$role]);
$user->setName($name);
$user->setService($service);
$user->setAddress($address);
$user->setAdditionalAddress($additionalAddress);
$user->setPostalCode($postalCode);
$user->setTown($town);
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->io->success($this->translator->trans('addUser.success.userCreated', [$username, $role]));
return 0;
$event = $stopwatch->stop('add-user-command');
if ($output->isVerbose()) {
$this->io->comment(
sprintf(
'New user database id: %d / Elapsed time: %.2f ms / Consumed memory: %.2f MB',
$user->getId(),
$event->getDuration(),
$event->getMemory() / (1024 ** 2)
)
);
}
return Command::SUCCESS;
}
/**
* @param string $username
* @param string $plainPassword
* @param string $email
* @param string $name
* @param string $role
* @param string $service
* @param string $address
* @param string $additionalAddress
* @param string $postalCode
* @param string $town
*/
private function validateUserData(
$username,
$plainPassword,
$email,
$name,
$role,
$service = '',
$address = '',
$additionalAddress = '',
$postalCode = '',
$town = ''
): void {
// first check if a user with the same username already exists.
$existingUser = $this->userRepository->findOneBy(['username' => $username]);
if (null !== $existingUser) {
throw new \RuntimeException(
sprintf('There is already a user registered with the "%s" username.', $username)
);
}
// validate password and email if is not this input means interactive.
$this->validator->validatePassword($plainPassword);
$this->validator->validateEmail($email);
$this->validator->validateNotEmpty($name, 'name');
if ($role === UserHelper::ROLE_AGENT) {
$this->validator->validateNotEmpty($service, 'service');
}
if ($role === UserHelper::ROLE_NOTARY) {
$this->validator->validateNotEmpty($address, 'address');
$this->validator->validateNotEmpty($additionalAddress, 'additionalAddress');
$this->validator->validateNotEmpty($postalCode, 'postalCode');
$this->validator->validateNotEmpty($town, 'town');
}
}
}
......@@ -127,7 +127,7 @@ class UserType extends AbstractType
'additionalAddress',
TextType::class,
[
'label' => 'addUser.additionnalAddress',
'label' => 'addUser.additionalAddress',
'required' => false,
]
)
......
......@@ -35,7 +35,12 @@ class Validator
public function validateUsername(?string $username): string
{
if (empty($username)) {
throw new InvalidArgumentException($this->translator->trans('addUser.error.notEmpty'));
throw new InvalidArgumentException(
$this->translator->trans(
'addUser.error.notEmpty',
['%field%' => $this->translator->trans('addUser.login')]
)
);
}
$user = $this->userRepository->findOneBy(['username' => $username]);
......@@ -59,7 +64,12 @@ class Validator
public function validateEmail(?string $email): string
{
if (empty($email)) {
throw new InvalidArgumentException($this->translator->trans('addUser.error.notEmpty'));
throw new InvalidArgumentException(
$this->translator->trans(
'addUser.error.notEmpty',
['%field%' => $this->translator->trans('addUser.email')]
)
);
}
$userEmail = $this->userRepository->findOneBy(['email' => $email]);
......@@ -83,7 +93,12 @@ class Validator
public function validatePassword(?string $plainPassword): string
{
if (empty($plainPassword)) {
throw new InvalidArgumentException($this->translator->trans('addUser.error.notEmpty'));
throw new InvalidArgumentException(
$this->translator->trans(
'addUser.error.notEmpty',
['%field%' => $this->translator->trans('addUser.password')]
)
);
}
$passwordConstraint = new PasswordRequirements(
......@@ -118,12 +133,23 @@ class Validator
*
* @param string|null $value
*
* @param string $name
*
* @return string
*/
public function validateNotEmpty(?string $value): string
public function validateNotEmpty(?string $value, $name = null): string
{
if (empty($value)) {
throw new InvalidArgumentException($this->translator->trans('addUser.error.notEmpty'));
throw new InvalidArgumentException(
$name ?
$this->translator->trans(
'addUser.error.notEmptyFieldName',
['%fieldName%' => $this->translator->trans('addUser.'.$name)]
) :
$this->translator->trans(
'addUser.error.notEmpty'
)
);
}
return $value;
......
......@@ -16,7 +16,7 @@ addUser:
roleConsole: "Rôle \n1) Étude notariale \n2) Agent du département \n3) Administrateur\n> "
service: "Service"
address: "Adresse"
additionnalAddress: "Complément d'adresse"
additionalAddress: "Complément d'adresse"
postalCode: "Code postal"
town: "Ville"
send: "Ajouter"
......@@ -25,6 +25,7 @@ addUser:
userUsernameExists: "L'utilisateur '%username%' existe déjà !"
confirmPasswordNoMatch: "Les mots de passe ne correspondent pas"
notEmpty: "Ce champ ne peut être vide"
notEmptyFieldName: "%fieldName% : Ce champ ne peut être vide"
success:
userCreated: "L'utilisateur '0' a été créé avec le(s) role(s) [1] !"
confirmEmail:
......@@ -38,7 +39,7 @@ addUserCmd:
role: "Profil"
service: "Service"
address: "Adresse"
additionnalAddress: "Complément d'adresse"
additionalAddress: "Complément d'adresse"
postalCode: "Code postal"
town: "Ville"
userEdit:
......
......@@ -2,4 +2,4 @@
./bin/test-php-docker-running
docker-compose exec php //entrypoint bin/console $@
docker-compose exec php //entrypoint bin/console "$@"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment