X-Git-Url: https://git.rapsys.eu/userbundle/blobdiff_plain/feb820aea1304e9c63ca1aeca47bcaf0aa78b195..d4954d9ad08c5f221d89397e532e23ebee6d5fe0:/Controller/UserController.php?ds=sidebyside diff --git a/Controller/UserController.php b/Controller/UserController.php index 3698493..672f933 100644 --- a/Controller/UserController.php +++ b/Controller/UserController.php @@ -12,6 +12,9 @@ namespace Rapsys\UserBundle\Controller; use Doctrine\DBAL\Exception\UniqueConstraintViolationException; + +use Rapsys\UserBundle\RapsysUserBundle; + use Symfony\Bridge\Twig\Mime\TemplatedEmail; use Symfony\Component\Form\FormError; use Symfony\Component\HttpFoundation\Request; @@ -22,8 +25,6 @@ use Symfony\Component\Mime\Address; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; -use Rapsys\UserBundle\RapsysUserBundle; - /** * {@inheritdoc} */ @@ -36,9 +37,9 @@ class UserController extends AbstractController { */ public function index(Request $request): Response { //Without admin - if (!$this->checker->isGranted($this->config['default']['admin'])) { + if (!$this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))) { //Throw 403 - throw $this->createAccessDeniedException($this->translator->trans('Unable to list users')); + throw $this->createAccessDeniedException($this->translator->trans('Unable to list users', [], $this->alias)); } //Get count @@ -47,11 +48,11 @@ class UserController extends AbstractController { //With not enough users if ($this->context['count'] - $this->page * $this->limit < 0) { //Throw 404 - throw $this->createNotFoundException($this->translator->trans('Unable to find users')); + throw $this->createNotFoundException($this->translator->trans('Unable to find users', [], $this->alias)); } - //Get users - $this->context['users'] = $this->doctrine->getRepository($this->config['class']['user'])->findAllAsArray($this->page, $this->limit); + //Get users by groups + $this->context['groups'] = $this->doctrine->getRepository($this->config['class']['user'])->findIndexByGroupId($this->page, $this->limit); //Render view return $this->render( @@ -74,7 +75,7 @@ class UserController extends AbstractController { //With invalid hash if ($hash != $this->slugger->hash($mail)) { //Throw bad request - throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash])); + throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias)); } //Get mail @@ -84,14 +85,14 @@ class UserController extends AbstractController { if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) { //Throw bad request //XXX: prevent slugger reverse engineering by not displaying decoded mail - throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail])); + throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias)); } //Without existing registrant if (!($user = $this->doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) { //Add error message mail already exists //XXX: prevent slugger reverse engineering by not displaying decoded mail - $this->addFlash('error', $this->translator->trans('Account %mail% do not exists', ['%mail%' => $smail])); + $this->addFlash('error', $this->translator->trans('The account do not exists', [], $this->alias)); //Redirect to register view return $this->redirectToRoute($this->config['route']['register']['name'], $this->config['route']['register']['context']); @@ -107,7 +108,7 @@ class UserController extends AbstractController { $this->manager->flush(); //Add error message mail already exists - $this->addFlash('notice', $this->translator->trans('Your account has been activated')); + $this->addFlash('notice', $this->translator->trans('Your account has been activated', [], $this->alias)); //Redirect to user view return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']); @@ -125,7 +126,7 @@ class UserController extends AbstractController { //With invalid hash if ($hash != $this->slugger->hash($mail)) { //Throw bad request - throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash])); + throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias)); } //Get mail @@ -135,36 +136,44 @@ class UserController extends AbstractController { if (empty($user = $this->doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) { //Throw not found //XXX: prevent slugger reverse engineering by not displaying decoded mail - throw $this->createNotFoundException($this->translator->trans('Unable to find account %mail%', ['%mail%' => $smail])); + throw $this->createNotFoundException($this->translator->trans('Unable to find account', [], $this->alias)); } //Prevent access when not admin, user is not guest and not currently logged user - if (!$this->checker->isGranted($this->config['default']['admin']) && $user != $this->security->getUser() || !$this->checker->isGranted('IS_AUTHENTICATED_FULLY')) { + if (!$this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin'])) && $user != $this->security->getUser() || !$this->checker->isGranted('IS_AUTHENTICATED_FULLY')) { //Throw access denied //XXX: prevent slugger reverse engineering by not displaying decoded mail - throw $this->createAccessDeniedException($this->translator->trans('Unable to access user: %mail%', ['%mail%' => $smail])); + throw $this->createAccessDeniedException($this->translator->trans('Unable to access user', [], $this->alias)); } //Create the EditType form and give the proper parameters - $edit = $this->createForm($this->config['edit']['view']['edit'], $user, [ + $edit = $this->factory->create($this->config['edit']['view']['edit'], $user, [ //Set action to edit route name and context 'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']), //Set civility class 'civility_class' => $this->config['class']['civility'], //Set civility default 'civility_default' => $this->doctrine->getRepository($this->config['class']['civility'])->findOneByTitle($this->config['default']['civility']), + //Disable mail + 'mail' => $this->checker->isGranted('ROLE_ADMIN'), + //Disable password + 'password' => false, //Set method - 'method' => 'POST' - ]+($this->checker->isGranted($this->config['default']['admin'])?$this->config['edit']['admin']:$this->config['edit']['field'])); + 'method' => 'POST', + //Set domain + 'translation_domain' => $this->alias + ]+($this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))?$this->config['edit']['admin']:$this->config['edit']['field'])); //With admin role - if ($this->checker->isGranted($this->config['default']['admin'])) { + if ($this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))) { //Create the EditType form and give the proper parameters - $reset = $this->createForm($this->config['edit']['view']['reset'], $user, [ + $reset = $this->factory->create($this->config['edit']['view']['reset'], $user, [ //Set action to edit route name and context 'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']), //Set method - 'method' => 'POST' + 'method' => 'POST', + //Set domain + 'translation_domain' => $this->alias ]); //With post method @@ -187,7 +196,7 @@ class UserController extends AbstractController { $this->manager->flush(); //Add notice - $this->addFlash('notice', $this->translator->trans('Account %mail% password updated', ['%mail%' => $mail = $data->getMail()])); + $this->addFlash('notice', $this->translator->trans('Account password updated', [], $this->alias)); //Redirect to cleanup the form return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail = $this->slugger->short($mail), 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']); @@ -217,21 +226,21 @@ class UserController extends AbstractController { $this->manager->flush(); //Add notice - $this->addFlash('notice', $this->translator->trans('Account %mail% updated', ['%mail%' => $mail = $data->getMail()])); + $this->addFlash('notice', $this->translator->trans('Account updated', [], $this->alias)); //Redirect to cleanup the form return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail = $this->slugger->short($mail), 'hash' => $this->slugger->hash($smail)]+$this->config['route']['edit']['context']); //Catch double slug or mail } catch (UniqueConstraintViolationException $e) { //Add error message mail already exists - $this->addFlash('error', $this->translator->trans('Account %mail% already exists', ['%mail%' => $data->getMail()])); + $this->addFlash('error', $this->translator->trans('The account already exists', [], $this->alias)); } } //Without admin role //XXX: prefer a reset on login to force user unspam action - } elseif (!$this->checker->isGranted($this->config['default']['admin'])) { + } elseif (!$this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))) { //Add notice - $this->addFlash('notice', $this->translator->trans('To change your password login with your mail and any password then follow the procedure')); + $this->addFlash('notice', $this->translator->trans('To change your password login with your mail and any password then follow the procedure', [], $this->alias)); } //Render view @@ -239,7 +248,7 @@ class UserController extends AbstractController { //Template $this->config['edit']['view']['name'], //Context - ['edit' => $edit->createView(), 'sent' => $request->query->get('sent', 0)]+$this->config['edit']['view']['context'] + ['register' => $edit->createView()]+$this->config['edit']['view']['context'] ); } @@ -254,11 +263,13 @@ class UserController extends AbstractController { */ public function login(Request $request, AuthenticationUtils $authenticationUtils, ?string $hash, ?string $mail): Response { //Create the LoginType form and give the proper parameters - $login = $this->createForm($this->config['login']['view']['form'], null, [ + $login = $this->factory->create($this->config['login']['view']['form'], null, [ //Set action to login route name and context 'action' => $this->generateUrl($this->config['route']['login']['name'], $this->config['route']['login']['context']), //Set method - 'method' => 'POST' + 'method' => 'POST', + //Set domain + 'translation_domain' => $this->alias ]); //Init context @@ -269,7 +280,7 @@ class UserController extends AbstractController { //With invalid hash if ($hash != $this->slugger->hash($mail)) { //Throw bad request - throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash])); + throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias)); } //Get mail @@ -278,7 +289,7 @@ class UserController extends AbstractController { //Without valid mail if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) { //Throw bad request - throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail])); + throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias)); } //Prefilled mail @@ -291,19 +302,21 @@ class UserController extends AbstractController { //Get the login error if there is one if ($error = $authenticationUtils->getLastAuthenticationError()) { //Get translated error - $error = $this->translator->trans($error->getMessageKey()); + $error = $this->translator->trans($error->getMessageKey(), [], $this->alias); //Add error message to mail field $login->get('mail')->addError(new FormError($error)); //Create the RecoverType form and give the proper parameters - $recover = $this->createForm($this->config['recover']['view']['form'], null, [ + $recover = $this->factory->create($this->config['recover']['view']['form'], null, [ //Set action to recover route name and context 'action' => $this->generateUrl($this->config['route']['recover']['name'], $this->config['route']['recover']['context']), //Without password 'password' => false, //Set method - 'method' => 'POST' + 'method' => 'POST', + //Set domain + 'translation_domain' => $this->alias ]); //Get recover mail entity @@ -311,13 +324,13 @@ class UserController extends AbstractController { //Set mail from login form ->setData($login->get('mail')->getData()) //Add recover error - ->addError(new FormError($this->translator->trans('Use this form to recover your account'))); + ->addError(new FormError($this->translator->trans('Use this form to recover your account', [], $this->alias))); //Add recover form to context $context['recover'] = $recover->createView(); } else { //Add notice - $this->addFlash('notice', $this->translator->trans('To change your password login with your mail and any password then follow the procedure')); + $this->addFlash('notice', $this->translator->trans('To change your password login with your mail and any password then follow the procedure', [], $this->alias)); } //Render view @@ -325,7 +338,7 @@ class UserController extends AbstractController { //Template $this->config['login']['view']['name'], //Context - ['login' => $login->createView(), 'disabled' => $request->query->get('disabled', 0), 'sent' => $request->query->get('sent', 0)]+$context+$this->config['login']['view']['context'] + ['login' => $login->createView(), 'disabled' => $request->query->get('disabled', 0)]+$context+$this->config['login']['view']['context'] ); } @@ -350,7 +363,7 @@ class UserController extends AbstractController { //With invalid hash if ($hash != $this->slugger->hash($mail.$pass)) { //Throw bad request - throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash])); + throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash], $this->alias)); } //Get mail @@ -360,21 +373,21 @@ class UserController extends AbstractController { if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) { //Throw bad request //XXX: prevent slugger reverse engineering by not displaying decoded mail - throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail])); + throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $smail], $this->alias)); } //With existing subscriber if (empty($user = $this->doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) { //Throw not found //XXX: prevent slugger reverse engineering by not displaying decoded mail - throw $this->createNotFoundException($this->translator->trans('Unable to find account %mail%', ['%mail%' => $smail])); + throw $this->createNotFoundException($this->translator->trans('Unable to find account', [], $this->alias)); } //With unmatched pass if ($pass != $this->slugger->hash($user->getPassword())) { //Throw not found //XXX: prevent use of outdated recover link - throw $this->createNotFoundException($this->translator->trans('Outdated recover link')); + throw $this->createNotFoundException($this->translator->trans('Outdated recover link', [], $this->alias)); } //Set context @@ -382,7 +395,7 @@ class UserController extends AbstractController { } //Create the LoginType form and give the proper parameters - $form = $this->createForm($this->config['recover']['view']['form'], $user, [ + $form = $this->factory->create($this->config['recover']['view']['form'], $user, [ //Set action to recover route name and context 'action' => $this->generateUrl($this->config['route']['recover']['name'], $context+$this->config['route']['recover']['context']), //With user disable mail @@ -390,7 +403,9 @@ class UserController extends AbstractController { //With user enable password 'password' => ($user !== null), //Set method - 'method' => 'POST' + 'method' => 'POST', + //Set domain + 'translation_domain' => $this->alias ]); //With post method @@ -421,7 +436,7 @@ class UserController extends AbstractController { $this->manager->flush(); //Add notice - $this->addFlash('notice', $this->translator->trans('Account password updated')); + $this->addFlash('notice', $this->translator->trans('Account password updated', [], $this->alias)); //Redirect to user login return $this->redirectToRoute($this->config['route']['login']['name'], ['mail' => $smail, 'hash' => $this->slugger->hash($smail)]+$this->config['route']['login']['context']); @@ -458,44 +473,19 @@ class UserController extends AbstractController { } } - //Iterate on keys to translate - foreach($this->config['translate'] as $translate) { - //Extract keys - $keys = explode('.', $translate); - - //Set current - $current =& $context; - - //Iterate on each subkey - do { - //Skip unset translation keys - if (!isset($current[current($keys)])) { - continue(2); - } - - //Set current to subkey - $current =& $current[current($keys)]; - } while(next($keys)); - - //Set translation - $current = $this->translator->trans($current); - - //Remove reference - unset($current); - } - //Translate subject $context['subject'] = $subject = ucfirst( $this->translator->trans( $this->config['recover']['mail']['subject'], - $this->slugger->flatten($context, null, '.', '%', '%') + $this->slugger->flatten($context, null, '.', '%', '%'), + $this->alias ) ); //Create message $message = (new TemplatedEmail()) //Set sender - ->from(new Address($this->config['contact']['address'], $this->config['contact']['name'])) + ->from(new Address($this->config['contact']['address'], $this->translator->trans($this->config['contact']['name'], [], $this->alias))) //Set recipient //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 ->to(new Address($context['recipient_mail'], $context['recipient_name'])) @@ -509,24 +499,27 @@ class UserController extends AbstractController { //Set context ->context($context); + //Add created notice + $this->addFlash('notice', $this->translator->trans('Account recovered', [], $this->alias)); + //Try sending message //XXX: mail delivery may silently fail try { //Send message $this->mailer->send($message); - //Add notice - $this->addFlash('notice', $this->translator->trans('Your recovery mail has been sent, to retrieve your account you must follow the recuperate link inside')); + //Add sent notice + $this->addFlash('notice', $this->translator->trans('Your recovery mail has been sent, to retrieve your account follow the recuperate link inside', [], $this->alias)); //Add junk warning - $this->addFlash('warning', $this->translator->trans('If you did not receive a recovery mail, check your Spam or Junk mail folders')); + $this->addFlash('warning', $this->translator->trans('If you did not receive a recovery mail, check your Spam or Junk mail folder', [], $this->alias)); - //Redirect on the same route with sent=1 to cleanup form - return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+$request->get('_route_params'), 302); + //Redirect on home route to cleanup form + return $this->redirectToRoute($this->config['route']['home']['name'], $this->config['route']['home']['context']); //Catch obvious transport exception } catch(TransportExceptionInterface $e) { //Add error message mail unreachable - $form->get('mail')->addError(new FormError($this->translator->trans('Unable to reach account'))); + $form->get('mail')->addError(new FormError($this->translator->trans('Unable to reach account', [], $this->alias))); } } } @@ -537,7 +530,7 @@ class UserController extends AbstractController { //Template $this->config['recover']['view']['name'], //Context - ['recover' => $form->createView(), 'sent' => $request->query->get('sent', 0)]+$this->config['recover']['view']['context'] + ['recover' => $form->createView()]+$this->config['recover']['view']['context'] ); } @@ -553,7 +546,7 @@ class UserController extends AbstractController { //Log new user infos $this->logger->emergency( $this->translator->trans( - 'register: mail=%mail% locale=%locale% confirm=%confirm%', + 'register: mail=%mail% locale=%locale% confirm=%confirm% ip=%ip%', [ '%mail%' => $postMail = $_POST['register']['mail'], '%locale%' => $request->getLocale(), @@ -565,8 +558,10 @@ class UserController extends AbstractController { 'hash' => $this->slugger->hash($postSmail) ]+$this->config['route']['confirm']['context'], UrlGeneratorInterface::ABSOLUTE_URL - ) - ] + ), + '%ip%' => $request->getClientIp() + ], + $this->alias ) ); } @@ -578,16 +573,20 @@ class UserController extends AbstractController { $user = $reflection->newInstance('', ''); //Create the RegisterType form and give the proper parameters - $form = $this->createForm($this->config['register']['view']['form'], $user, [ + $form = $this->factory->create($this->config['register']['view']['form'], $user, [ //Set action to register route name and context 'action' => $this->generateUrl($this->config['route']['register']['name'], $this->config['route']['register']['context']), + //Set captcha + 'captcha' => true, //Set civility class 'civility_class' => $this->config['class']['civility'], //Set civility default 'civility_default' => $this->doctrine->getRepository($this->config['class']['civility'])->findOneByTitle($this->config['default']['civility']), //Set method - 'method' => 'POST' - ]+($this->checker->isGranted($this->config['default']['admin'])?$this->config['register']['admin']:$this->config['register']['field'])); + 'method' => 'POST', + //Set domain + 'translation_domain' => $this->alias + ]+($this->checker->isGranted('ROLE_'.strtoupper($this->config['default']['admin']))?$this->config['register']['admin']:$this->config['register']['field'])); //With post method if ($request->isMethod('POST')) { @@ -616,7 +615,7 @@ class UserController extends AbstractController { } else { //Throw exception //XXX: consider missing group as fatal - throw new \Exception(sprintf('Group %s listed in %s.default.group[%d] not found by title', $groupTitle, RapsysUserBundle::getAlias(), $i)); + throw new \Exception(sprintf('Group %s listed in %s.default.group[%d] not found by title', $groupTitle, $this->alias, $i)); } } @@ -650,44 +649,19 @@ class UserController extends AbstractController { } } - //Iterate on keys to translate - foreach($this->config['translate'] as $translate) { - //Extract keys - $keys = explode('.', $translate); - - //Set current - $current =& $context; - - //Iterate on each subkey - do { - //Skip unset translation keys - if (!isset($current[current($keys)])) { - continue(2); - } - - //Set current to subkey - $current =& $current[current($keys)]; - } while(next($keys)); - - //Set translation - $current = $this->translator->trans($current); - - //Remove reference - unset($current); - } - //Translate subject $context['subject'] = $subject = ucfirst( $this->translator->trans( $this->config['register']['mail']['subject'], - $this->slugger->flatten($context, null, '.', '%', '%') + $this->slugger->flatten($context, null, '.', '%', '%'), + $this->alias ) ); //Create message $message = (new TemplatedEmail()) //Set sender - ->from(new Address($this->config['contact']['address'], $this->config['contact']['name'])) + ->from(new Address($this->config['contact']['address'], $this->translator->trans($this->config['contact']['name'], [], $this->alias))) //Set recipient //XXX: remove the debug set in vendor/symfony/mime/Address.php +46 ->to(new Address($context['recipient_mail'], $context['recipient_name'])) @@ -706,8 +680,8 @@ class UserController extends AbstractController { //Send to database $this->manager->flush(); - //Add error message mail already exists - $this->addFlash('notice', $this->translator->trans('Your account has been created')); + //Add created notice + $this->addFlash('notice', $this->translator->trans('Account created', [], $this->alias)); //Try sending message //XXX: mail delivery may silently fail @@ -715,17 +689,23 @@ class UserController extends AbstractController { //Send message $this->mailer->send($message); - //Redirect on the same route with sent=1 to cleanup form - return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+$request->get('_route_params')); + //Add verification notice + $this->addFlash('notice', $this->translator->trans('Your verification mail has been sent, to activate your account you must follow the confirmation link inside', [], $this->alias)); + + //Add junk warning + $this->addFlash('warning', $this->translator->trans('If you did not receive a verification mail, check your Spam or Junk mail folders', [], $this->alias)); + + //Redirect on home route to cleanup form + return $this->redirectToRoute($this->config['route']['home']['name'], $this->config['route']['home']['context']); //Catch obvious transport exception } catch(TransportExceptionInterface $e) { //Add error message mail unreachable - $form->get('mail')->addError(new FormError($this->translator->trans('Unable to reach account'))); + $form->get('mail')->addError(new FormError($this->translator->trans('Unable to reach account', [], $this->alias))); } //Catch double subscription } catch (UniqueConstraintViolationException $e) { //Add error message mail already exists - $this->addFlash('error', $this->translator->trans('Account already exists')); + $this->addFlash('error', $this->translator->trans('The account already exists', [], $this->alias)); } } } @@ -735,7 +715,7 @@ class UserController extends AbstractController { //Template $this->config['register']['view']['name'], //Context - ['register' => $form->createView(), 'sent' => $request->query->get('sent', 0)]+$this->config['register']['view']['context'] + ['register' => $form->createView()]+$this->config['register']['view']['context'] ); } }