mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
script to send batch password recover code
This commit is contained in:
parent
f6b6ec57bb
commit
04bdaa308a
198
Command/ChillUserSendRenewPasswordCodeCommand.php
Normal file
198
Command/ChillUserSendRenewPasswordCodeCommand.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Command;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use League\Csv\Reader;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Notification\Mailer;
|
||||
use Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper;
|
||||
use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEvent;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
|
||||
class ChillUserSendRenewPasswordCodeCommand extends ContainerAwareCommand
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
protected $em;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Mailer
|
||||
*/
|
||||
protected $mailer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var RecoverPasswordHelper
|
||||
*/
|
||||
protected $recoverPasswordHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* The current input interface
|
||||
*
|
||||
* @var InputInterface
|
||||
*/
|
||||
private $input;
|
||||
|
||||
/**
|
||||
* The current output interface
|
||||
*
|
||||
* @var OutputInterface
|
||||
*/
|
||||
private $output;
|
||||
|
||||
public function __construct(
|
||||
LoggerInterface $logger,
|
||||
EntityManagerInterface $em,
|
||||
RecoverPasswordHelper $recoverPasswordHelper,
|
||||
EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->em = $em;
|
||||
$this->recoverPasswordHelper = $recoverPasswordHelper;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName('chill:user:send-password-recover-code')
|
||||
->setDescription('Send a message with code to recover password')
|
||||
->addArgument('csvfile', InputArgument::REQUIRED, 'CSV file with the list of users')
|
||||
->addOption('template', null, InputOption::VALUE_REQUIRED, 'Template for email')
|
||||
->addOption('expiration', null, InputOption::VALUE_REQUIRED, 'Expiration of the link, as an unix timestamp')
|
||||
->addOption('subject', null, InputOption::VALUE_REQUIRED, 'Subject of the email', 'Recover your password')
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->output = $output;
|
||||
|
||||
$reader = $this->getReader();
|
||||
|
||||
foreach($reader->getRecords() as $offset => $r) {
|
||||
$user = $this->getUser($r);
|
||||
|
||||
if ($user === null) {
|
||||
$this->onUserNotFound($r, $offset);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->sendRecoverCode($user);
|
||||
}
|
||||
}
|
||||
|
||||
protected function sendRecoverCode(User $user)
|
||||
{
|
||||
if (empty($user->getEmail())) {
|
||||
$this->logger->alert("User without email", [
|
||||
'user_id' => $user->getId(),
|
||||
'username' => $user->getUsername()
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$template = $this->input->getOption('template');
|
||||
$expiration = \DateTime::createFromFormat('U',
|
||||
$this->input->getOption('expiration'));
|
||||
|
||||
$this->recoverPasswordHelper
|
||||
->sendRecoverEmail(
|
||||
$user,
|
||||
$expiration,
|
||||
$template,
|
||||
[ 'expiration' => $expiration],
|
||||
false,
|
||||
[ '_locale' => 'fr' ],
|
||||
$this->input->getOption('subject')
|
||||
);
|
||||
}
|
||||
|
||||
protected function onUserNotFound($row, $offset)
|
||||
{
|
||||
$this->logger->alert('User not found', \array_merge([
|
||||
'offset' => $offset
|
||||
], $row));
|
||||
}
|
||||
|
||||
protected function getUser($row)
|
||||
{
|
||||
/* @var $userRepository \Chill\MainBundle\Repository\UserRepository */
|
||||
$userRepository = $this->em->getRepository(User::class);
|
||||
|
||||
try {
|
||||
if (\array_key_exists('email', $row)) {
|
||||
return $userRepository->findOneByUsernameOrEmail(\trim($row['email']));
|
||||
}
|
||||
} catch (\Doctrine\ORM\NoResultException $e) {
|
||||
// continue, we will try username
|
||||
}
|
||||
|
||||
try {
|
||||
if (\array_key_exists('username', $row)) {
|
||||
return $userRepository->findOneByUsernameOrEmail(\trim($row['username']));
|
||||
}
|
||||
} catch (\Doctrine\ORM\NoResultException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Reader
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function getReader()
|
||||
{
|
||||
try {
|
||||
$reader = Reader::createFromPath($this->input->getArgument('csvfile'));
|
||||
} catch (\Exception $e) {
|
||||
$this->logger->error("The csv file could not be read", [
|
||||
'path' => $this->input->getArgument('csvfile')
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$reader->setHeaderOffset(0);
|
||||
|
||||
$headers = $reader->getHeader();
|
||||
|
||||
if (FALSE === \in_array('username', $headers)
|
||||
&& FALSE === \in_array('email', $headers)) {
|
||||
throw new \InvalidArgumentException("The csv file does not have an "
|
||||
. "username or email header");
|
||||
}
|
||||
|
||||
return $reader;
|
||||
}
|
||||
|
||||
}
|
@ -8,3 +8,8 @@ services:
|
||||
|
||||
tags:
|
||||
- { name: console.command }
|
||||
|
||||
Chill\MainBundle\Command\ChillUserSendRenewPasswordCodeCommand:
|
||||
autowire: true
|
||||
tags:
|
||||
- { name: console.command }
|
||||
|
@ -31,6 +31,7 @@ services:
|
||||
$tokenManager: '@Chill\MainBundle\Security\PasswordRecover\TokenManager'
|
||||
$urlGenerator: '@Symfony\Component\Routing\Generator\UrlGeneratorInterface'
|
||||
$mailer: '@Chill\MainBundle\Notification\Mailer'
|
||||
$routeParameters: "%chill_main.notifications%"
|
||||
|
||||
Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEventSubscriber:
|
||||
arguments:
|
||||
|
@ -33,7 +33,7 @@ Chill\MainBundle\Entity\Center:
|
||||
- NotBlank: ~
|
||||
- Length:
|
||||
max: 50
|
||||
min: 3
|
||||
min: 2
|
||||
|
||||
Chill\MainBundle\Entity\Address:
|
||||
properties:
|
||||
|
@ -47,26 +47,53 @@ class RecoverPasswordHelper
|
||||
*/
|
||||
protected $mailer;
|
||||
|
||||
protected $routeParameters;
|
||||
|
||||
const RECOVER_PASSWORD_ROUTE = 'password_recover';
|
||||
|
||||
public function __construct(
|
||||
TokenManager $tokenManager,
|
||||
UrlGeneratorInterface $urlGenerator,
|
||||
Mailer $mailer
|
||||
Mailer $mailer,
|
||||
array $routeParameters
|
||||
) {
|
||||
$this->tokenManager = $tokenManager;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->mailer = $mailer;
|
||||
$this->routeParameters = $routeParameters;
|
||||
}
|
||||
|
||||
|
||||
public function generateUrl(User $user, \DateTimeInterface $expiration, $absolute = true)
|
||||
/**
|
||||
*
|
||||
* @param User $user
|
||||
* @param \DateTimeInterface $expiration
|
||||
* @param bool $absolute
|
||||
* @param array $parameters additional parameters to url
|
||||
* @return string
|
||||
*/
|
||||
public function generateUrl(User $user, \DateTimeInterface $expiration, $absolute = true, array $parameters = [])
|
||||
{
|
||||
return $this->urlGenerator->generate(
|
||||
|
||||
$context = $this->urlGenerator->getContext();
|
||||
$previousHost = $context->getHost();
|
||||
$previousScheme = $context->getScheme();
|
||||
|
||||
$context->setHost($this->routeParameters['host']);
|
||||
$context->setScheme($this->routeParameters['scheme']);
|
||||
|
||||
$url = $this->urlGenerator->generate(
|
||||
self::RECOVER_PASSWORD_ROUTE,
|
||||
$this->tokenManager->generate($user, $expiration),
|
||||
\array_merge(
|
||||
$this->tokenManager->generate($user, $expiration),
|
||||
$parameters),
|
||||
$absolute ? UrlGeneratorInterface::ABSOLUTE_URL : UrlGeneratorInterface::ABSOLUTE_PATH
|
||||
);
|
||||
|
||||
// reset the host
|
||||
$context->setHost($previousHost);
|
||||
$context->setScheme($previousScheme);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function sendRecoverEmail(
|
||||
@ -74,21 +101,23 @@ class RecoverPasswordHelper
|
||||
\DateTimeInterface $expiration,
|
||||
$template = '@ChillMain/Password/recover_email.txt.twig',
|
||||
array $templateParameters = [],
|
||||
$force = false
|
||||
$force = false,
|
||||
array $additionalUrlParameters = [],
|
||||
$emailSubject = 'Recover your password'
|
||||
) {
|
||||
$content = $this->mailer->renderContentToUser(
|
||||
$user,
|
||||
$template,
|
||||
\array_merge([
|
||||
'user' => $user,
|
||||
'url' => $this->generateUrl($user, $expiration, true)
|
||||
'url' => $this->generateUrl($user, $expiration, true, $additionalUrlParameters)
|
||||
],
|
||||
$templateParameters
|
||||
));
|
||||
|
||||
$this->mailer->sendNotification(
|
||||
$user,
|
||||
[ 'Recover your password' ],
|
||||
[ $emailSubject ],
|
||||
[
|
||||
'text/plain' => $content,
|
||||
],
|
||||
|
Loading…
x
Reference in New Issue
Block a user