<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace OceanExpertBundle\Controller;
use DateTime;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\Form\Factory\FormFactory;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Util\TokenGenerator;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Controller managing the resetting of the password
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
class ResettingController extends AbstractController
{
private TokenGenerator $fosTokenGenerator;
private MailerInterface $fosMailer;
private UserManagerInterface $fosUserManager;
private FormFactory $fosResettingFormFactory;
public function __construct(
TokenGenerator $fosTokenGenerator,
MailerInterface $fosMailer,
UserManagerInterface $fosUserManager,
FormFactory $fosResettingFormFactory
) {
$this->fosTokenGenerator = $fosTokenGenerator;
$this->fosMailer = $fosMailer;
$this->fosUserManager = $fosUserManager;
$this->fosResettingFormFactory = $fosResettingFormFactory;
}
/**
* Request reset user password: show form
*/
public function requestAction(): Response
{
return $this->render('Resetting/request.html.twig');
}
/**
* Request reset user password: submit form and send email
*/
public function sendEmailAction(Request $request): Response
{
$username = $request->request->get('username');
/** @var $user UserInterface */
$user = $this->fosUserManager->findUserByUsernameOrEmail($username);
if (null === $user) {
return $this->render(
'Resetting/request.html.twig',
array(
'invalid_username' => $username
)
);
}
if ($user->isPasswordRequestNonExpired($this->container->getParameter('fos_user.resetting.token_ttl'))) {
return $this->render(
'Default/error.html.twig',
array(
'message' => 'The password for this user has already been requested within the last 30 minutes.'
)
);
}
if (null === $user->getConfirmationToken()) {
/**
* @var $tokenGenerator TokenGeneratorInterface
*/
// $tokenGenerator = $this->get('fos_user.util.token_generator');
$tokenGenerator = $this->fosTokenGenerator;
$user->setConfirmationToken($tokenGenerator->generateToken());
}
// $this->get('fos_user.mailer')->sendResettingEmailMessage($user);
$this->fosMailer->sendResettingEmailMessage($user);
$user->setPasswordRequestedAt(new DateTime());
// $this->get('fos_user.user_manager')->updateUser($user);
$this->fosUserManager->updateUser($user);
return new RedirectResponse($this->generateUrl('fos_user_resetting_check_email',
array('email' => $this->getObfuscatedEmail($user))
));
}
/**
* Get the truncated email displayed when requesting the resetting.
*
* The default implementation only keeps the part following @ in the address.
*
* @param UserInterface $user
*
* @return string
*/
protected function getObfuscatedEmail(UserInterface $user)
{
$email = $user->getEmail();
if (false !== $pos = strpos($email, '@')) {
$email = '...' . substr($email, $pos);
}
return $email;
}
/**
* Tell the user to check his email provider
*/
public function checkEmailAction(Request $request): Response
{
$email = $request->query->get('email');
if (empty($email)) {
// the user does not come from the sendEmail action
return new RedirectResponse($this->generateUrl('fos_user_resetting_request'));
}
return $this->render('Resetting/checkEmail.html.twig', array(
'email' => $email,
));
}
/**
* Reset user password
*/
public function resetAction(Request $request, $token): Response
{
/**
* @var $dispatcher EventDispatcherInterface
*/
$dispatcher = $this->get('event_dispatcher');
$user = $this->fosUserManager->findUserByConfirmationToken($token);
if (null === $user) {
return $this->render(
'Default/error.html.twig',
array(
'message' => 'Invalid token or the token already has been used to reset the password.
Please try resetting password again.'
)
);
}
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->fosResettingFormFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted()
&& $form->isValid()
) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_SUCCESS, $event);
$this->fosUserManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl(
'view_profile',
array(
'user' => $user->getId()
)
);
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(
FOSUserEvents::RESETTING_RESET_COMPLETED, new
FilterUserResponseEvent(
$user,
$request,
$response
)
);
return $response;
}
return $this->render(
'Resetting/reset.html.twig',
array(
'token' => $token,
'form' => $form->createView(),
'firstlogin'=> $request->query->get('firstlogin')
)
);
}
/**
* reset the username of an expert
*
* @param Request $request
*
* @return Response string
*/
public function changeUsernameAction(Request $request): Response
{
$security_context = $this->get('security.token_storage');
$username = $request->request->get('username');
$loggedUser = $security_context->getToken()->getUsername();
$message = '';
if ($this->get('security.authorization_checker')->isGranted('ROLE_GLOBAL_EDITOR')
|| $username == $loggedUser
) {
$em = $this->getDoctrine()->getManager();
$newusername = $request->request->get('newusername');
$user = $this->fosUserManager->findUserByUsername($username);
$existing = $this->fosUserManager->findUserByUsername($newusername);
if ($existing) {
$message = "A user with username '$newusername' already exists.$existing";
} elseif ($user) {
$changeUser = $em->getRepository('OceanExpertBundle:FosUser')->findOneById($user->getId());
if ($changeUser) {
$changeUser->setUsername($newusername);
$changeUser->setUsernameCanonical($newusername);
$em->persist($changeUser);
$em->flush();
$message = 'success';
}
} else {
$message = 'Username does not exists.';
}
} else {
$message = 'Invalid credentials';
}
return new Response($message);
}
/**
* reset the email address of an expert
*
* @param Request $request
*
* @return JsonResponse
*/
public function changeEmailAction(Request $request): Response
{
$security_context = $this->get('security.token_storage');
$loggedUser = $security_context->getToken()->getUser();
if (!is_object($loggedUser)
|| !($loggedUserEmail = $loggedUser->getEmail())) {
$message = array(
'status' => 0,
'message' => "Are you logged in as valid user?"
);
return new JsonResponse($message);
}
$currentEmail = trim($request->request->get('currentEmail'));
$newEmail = trim($request->request->get('newEmail'));
//$currentEmail = 'w.appeltans@unesco.org';
//$newEmail = 'a.lambert@unesco.org';
//dump($currentEmail);
//dump($newEmail);
//die();
if (is_null($currentEmail)
|| is_null($newEmail)
|| $currentEmail === ''
|| $newEmail === ''
) {
$message = array(
'status' => 0,
'message' => "We need both a current and a new email address."
);
return new JsonResponse($message);
}
//get the user for whom we want to change the address
//this is not always the logged in user!!!
$em = $this->getDoctrine()->getManager();
$user = $this->fosUserManager->findUserByUsernameOrEmail($currentEmail);
//check if current email is valid
if (!filter_var($currentEmail, FILTER_VALIDATE_EMAIL)) {
$message = array(
'status' => 0,
'message' => "Email ($currentEmail) is not a valid email address."
);
return new JsonResponse($message);
} else {
//sanitize current email
$currentEmail = filter_var($currentEmail, FILTER_SANITIZE_EMAIL);
}
//check if new email is valid
if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) {
$message = array(
'status' => 0,
'message' => "Email ($newEmail) is not a valid email address."
);
return new JsonResponse($message);
} else {
//sanitize new email
$newEmail = filter_var($newEmail, FILTER_SANITIZE_EMAIL);
}
//check if email already exists
//this is also done in RegistrationController.php:checkEmailAvailableAction
$existingUsername = $this->fosUserManager->findUserByUsername($newEmail);
$existingEmail = $this->fosUserManager->findUserByEmail($newEmail);
if ($existingEmail) {
$message = array(
'status' => 0,
'message' => 'A user (' . $existingEmail->getId() . ') with email (' . $newEmail . ') already exists.'
);
return new JsonResponse($message);
} elseif ($existingUsername) {
$message = array(
'status' => 0,
'message' => 'A user (' . $existingUsername->getId() . ') with username (' . $newEmail . ') already exists.'
);
return new JsonResponse($message);
}
if ($this->get('security.authorization_checker')->isGranted('ROLE_GLOBAL_EDITOR') ){
$changeUser = $em->getRepository('OceanExpertBundle:FosUser')->findOneById($user->getId());
//we already checked the validity of the new email
$changeUser->setEmail($newEmail);
$changeUser->setEmailCanonical($newEmail);
$em->persist($changeUser);
$em->flush();
$indiv = $em->getRepository('OceanExpertBundle:Indiv')->findOneByIdInd($user->getId());
if ($indiv) {
//we already checked the validity of the new email
$indiv->setEmail1($newEmail);
$em->persist($indiv);
$em->flush();
}
$message = array(
'status' => 1,
'message' => "Email changed successfully."
);
} elseif ($currentEmail == $loggedUserEmail) {
$confirmCode = $request->request->get('confirmCode');
$emailToken = sha1($confirmCode . '' . $newEmail);
$findCode = $em->getRepository('OceanExpertBundle:ConfirmationTokens')->findOneByConfirmationToken($emailToken);
if (count($findCode) > 0) {
$changeUser = $em->getRepository('OceanExpertBundle:FosUser')->findOneById($user->getId());
if ($changeUser) {
$changeUser->setEmail($newEmail);
$changeUser->setEmailCanonical($newEmail);
$em->persist($changeUser);
$em->flush();
$indiv = $em->getRepository('OceanExpertBundle:Indiv')->findOneByIdInd($user->getId());
if ($indiv) {
//we already checked the validity of the new email
$indiv->setEmail1($newEmail);
$em->persist($indiv);
$em->flush();
}
$message = array(
'status' => 1,
'message' => "Email changed successfully."
);
}
$em->remove($findCode);
$em->flush();
} else {
$message = array(
'status' => 0,
'message' => "Invalid token provided."
);
}
} else {
$message = array(
'status' => 0,
'message' => "Invalid credentials."
);
}
return new JsonResponse($message);
}
}