Commit f83c259b authored by Baudouin Feildel's avatar Baudouin Feildel
Browse files

Add command for user automation

parent 2a550223
Pipeline #990 passed with stage
in 1 minute and 44 seconds
<?php
namespace App\Command;
use App\DoctrineTypes\UserStatus;
use App\Entity\Lizmap\LizmapUser;
use App\Entity\User;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectManager;
use Error;
use RuntimeException;
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\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Security;
class AppAutomationUser extends Command
{
const STATE_PRESENT = 'present';
const STATE_ABSENT = 'absent';
const STATE_ADMIN = 'admin';
protected static $defaultName = 'app:automation:user';
/**
* @var UserPasswordEncoderInterface
*/
protected $encoder;
/**
* @var ObjectManager
*/
protected $emDdec;
/**
* @var ObjectManager
*/
protected $emLizmap;
protected $security;
public function __construct(UserPasswordEncoderInterface $encoder,
ManagerRegistry $doctrine,
Security $security)
{
parent::__construct(self::$defaultName);
$this->encoder = $encoder;
$this->emDdec = $doctrine->getManager('ddec');
$this->emLizmap = $doctrine->getManager('lizmap');
$this->security = $security;
}
protected function configure()
{
$this
->setDescription('Manage user in idempotent way.')
->addArgument('email', InputArgument::REQUIRED, 'The user email')
->addArgument('state', InputArgument::OPTIONAL, 'The user state', self::STATE_PRESENT)
->addOption('name', null, InputArgument::OPTIONAL, 'The user full name')
->addOption('password', null, InputArgument::OPTIONAL, 'The user email')
->addOption('lizmap-login', null, InputArgument::OPTIONAL, 'The linked Lizmap User');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$email = $input->getArgument('email');
$state = $input->getArgument('state');
$name = $input->hasOption('name') ? $input->getOption('name') : null;
$password = $input->hasOption('password') ? $input->getOption('password') : null;
$lizmapLogin = $input->hasOption('lizmap-login') ? $input->getOption('lizmap-login') : null;
$user = $this->findInternalUser($email);
$modified = false;
try {
switch ($state) {
case self::STATE_ABSENT:
$modified = $this->deleteUser($user);
break;
case self::STATE_ADMIN:
$modified = $this->ensureUser($user, $email, $name, $password, $lizmapLogin, UserStatus::STATUS_ADMIN);
break;
case self::STATE_PRESENT:
$modified = $this->ensureUser($user, $email, $name, $password, $lizmapLogin, UserStatus::STATUS_NORMAL);
break;
}
} catch (Error $error) {
$output->writeln("error: " . $error->getMessage());
return 1;
}
$output->writeln($modified ? "modified" : "ok");
return 0;
}
private function findInternalUser(string $email): ?User
{
/** @var User $user */
$user = $this->emDdec->getRepository(User::class)->findOneBy(['email' => $email]);
return $user;
}
private function deleteUser(?User $user): bool
{
if ($user !== null) {
$this->emDdec->remove($user);
$this->emDdec->flush();
return true;
}
return false;
}
private function ensureUser(?User $user, string $email, ?string $name, ?string $password, ?string $lizmapLogin, int $status): bool
{
if ($user !== null) {
$modified = $this->updateUser($user, $name, $password, $lizmapLogin, $status);
} else {
$this->ensureNotNull($name, "Name must be provided when creating a user");
$this->ensureNotNull($password, "Password must be provided when creating a user");
$user = $this->createUser($email, $name, $password, $lizmapLogin, $status);
$modified = $user !== null;
}
return $modified;
}
private function updateUser(User $user, ?string $name, ?string $password, ?string $lizmapLogin, int $status): bool
{
$modified = false;
if ($name !== null && $name !== $user->getName()) {
$user->setName($name);
$modified = true;
}
if ($password !== null) {
if (!$this->encoder->isPasswordValid($user, $password)) {
$encodedPassword = $this->encoder->encodePassword($user, $password);
$user->setPassword($encodedPassword);
$modified = true;
}
}
if ($lizmapLogin !== null && $user->getLizmapLogin() !== $lizmapLogin) {
$lizmapUser = $this->findLizmapUser($lizmapLogin);
if ($lizmapUser !== null) {
$user->setLizmapLogin($lizmapLogin);
$modified = true;
} else {
throw new RuntimeException("Lizmap user $lizmapLogin not found");
}
}
if ($user->getStatus() !== $status) {
$user->setStatus($status);
$modified = true;
}
if ($modified) {
$this->emDdec->persist($user);
$this->emDdec->flush();
}
return $modified;
}
private function findLizmapUser(string $login): ?LizmapUser
{
/** @var LizmapUser $user */
$user = $this->emLizmap->getRepository(LizmapUser::class)->findOneBy(['usr_login' => $login]);
return $user;
}
private function ensureNotNull($value, string $message): void
{
if ($value === null) {
throw new RuntimeException($message);
}
}
private function createUser(string $email, string $name, string $password, ?string $lizmapLogin, int $status): User
{
$user = new User();
$user->setEmail($email);
$user->setName($name);
$user->setPassword($this->encoder->encodePassword($user, $password));
$user->setStatus($status);
if ($lizmapLogin !== null) {
$lizmapUser = $this->findLizmapUser($lizmapLogin);
if ($lizmapUser !== null) {
$user->setLizmapLogin($lizmapLogin);
} else {
throw new RuntimeException("Lizmap user $lizmapLogin not found");
}
}
$this->emDdec->persist($user);
$this->emDdec->flush();
return $user;
}
}
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