src/Controller/SecurityController.php line 82

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\App\UserPasswordChange;
  4. use App\Entity\App\Users;
  5. use App\Repository\Tools\AppSettingsRepository;
  6. use App\Repository\UsersRepository;
  7. use App\Services\LogService;
  8. use App\Services\MailerService;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  11. use Symfony\Component\HttpFoundation\Response;
  12. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  13. use Symfony\Component\Routing\Annotation\Route;
  14. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  15. use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
  16. use Symfony\Component\Security\Csrf\CsrfToken;
  17. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  18. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Contracts\Translation\TranslatorInterface;
  21. class SecurityController extends AbstractController
  22. {
  23.     private $_AppSettings;
  24.     private $entityManager;
  25.     private $mailerService;
  26.     private $csrfTokenManager;
  27.     private $translator;
  28.     public function __construct(
  29.         AppSettingsRepository     $apRepository,
  30.         UsersRepository           $userRepository,
  31.         UrlGeneratorInterface     $urlGenerator,
  32.         EntityManagerInterface    $entityManager,
  33.         MailerService             $mailerService,
  34.         CsrfTokenManagerInterface $csrfTokenManager,
  35.         TranslatorInterface       $translator,
  36.         LogService $logService
  37.     ){
  38.         $this->entityManager $entityManager;
  39.         $this->mailerService $mailerService;
  40.         $this->csrfTokenManager $csrfTokenManager;
  41.         $this->translator $translator;
  42.         $this->userRepository $userRepository;
  43.         $this->urlGenerator $urlGenerator;
  44.         $this->_getAppSettings($apRepository);
  45.         $this->logService $logService;
  46.     }
  47.     public function generateRandomString($length 10) {
  48.         return substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'ceil($length/strlen($x)) )),1,$length);
  49.     }
  50.     public function _getAppSettings($apRepository){
  51.         $this->_AppSettings $apRepository->getAppSettings();
  52.     }
  53.     #[Route('/login'name'app_login')]
  54.     public function login(AuthenticationUtils $authenticationUtils): Response
  55.     {
  56.         $error $authenticationUtils->getLastAuthenticationError();
  57.         if ($error) {
  58.             $translatedError $this->translator->trans($error->getMessageKey(), $error->getMessageData(), 'security');
  59.             $this->addFlash('error'$translatedError);
  60.         }
  61.         $lastUsername $authenticationUtils->getLastUsername();
  62.         return $this->render('security/login.html.twig', ['app_settings' => $this->_AppSettings,'last_username' => $lastUsername'error' => $error]);
  63.     }
  64.     #[Route('/wyloguj'name'app_logout')]
  65.     public function logout(): void
  66.     {
  67.         throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
  68.     }
  69.     #[Route('/resetowanie-hasla/zgloszenie'name'app-reset-password-request'methods: ["GET""POST"])]
  70.     public function appResetPasswordRequest(Request $request): Response
  71.     {
  72.         if ($request->isMethod('POST')) {
  73.             $csrfToken $request->request->get('_csrf_token');
  74.             if (!$this->csrfTokenManager->isTokenValid(new CsrfToken('reset_request'$csrfToken))) {
  75.                 throw new InvalidCsrfTokenException();
  76.             }
  77.             $username = (string)$request->request->get('ress_username');
  78.             $email = (string)$request->request->get('ress_email');
  79.             if (empty($username) || empty($email)) {
  80.                 $this->addFlash('error''Login i adres e-mail są wymagane.');
  81.                 return $this->redirectToRoute('app-reset-password-request');
  82.             }
  83.             if (!filter_var($emailFILTER_VALIDATE_EMAIL)) {
  84.                 $this->addFlash('error''Podano niepoprawny adres e-mail.');
  85.                 return $this->redirectToRoute('app-reset-password-request');
  86.             }
  87.             $user $this->userRepository->findOneBy([
  88.                 'username' => $username,
  89.                 'email' => $email
  90.             ]);
  91.             if (!$user) {
  92.                 $this->addFlash('success''Jeśli dane zostały wprowadzone poprawnie, otrzymasz wiadomość e-mail z instrukcjami dotyczącymi resetowania hasła.');
  93.                 return $this->redirectToRoute('app-reset-password-request');
  94.             }
  95.             if (!$user->isUserStatus()) {
  96.                 $this->addFlash('success''Jeśli dane zostały wprowadzone poprawnie, otrzymasz wiadomość e-mail z instrukcjami dotyczącymi resetowania hasła.');
  97.                 return $this->redirectToRoute('app-reset-password-request');
  98.             }
  99.             if ($user->getEmail() == null) {
  100.                 $this->addFlash('success''Jeśli dane zostały wprowadzone poprawnie, otrzymasz wiadomość e-mail z instrukcjami dotyczącymi resetowania hasła.');
  101.                 return $this->redirectToRoute('app-reset-password-request');
  102.             }
  103.             $data = [
  104.                 'user_change_password_code' => $user->getId() . uniqid(). $this->generateRandomString(130)
  105.             ];
  106.             try {
  107.                 $this->entityManager->beginTransaction();
  108.                 $this->userRepository->disableOldChangePassword($user->getId());
  109.                 $newReset = new UserPasswordChange();
  110.                 $newReset->setCreatedAt(new \DateTime());
  111.                 $newReset->setUserId($user->getId());
  112.                 $newReset->setUserPasswordChangeStatus(true);
  113.                 $newReset->setUserPasswordChangeCode($data['user_change_password_code']);
  114.                 $this->entityManager->persist($newReset);
  115.                 $this->entityManager->flush();
  116.                 $_queue $this->mailerService->createQueue(
  117.                     10,
  118.                     $user->getEmail(),
  119.                     [
  120.                         'user_login' => $user->getUserlogin(),
  121.                         'user_change_password_url' =>
  122.                             $this->urlGenerator->generate(
  123.                                 'app-reset-password',
  124.                                 ['token' => $data['user_change_password_code']],
  125.                                 UrlGeneratorInterface::ABSOLUTE_URL
  126.                             )
  127.                     ],
  128.                     0,
  129.                     null,
  130.                     $request->getClientIp()
  131.                 );
  132.                 $log $this->logService->createLog(
  133.                     48,
  134.                     [
  135.                         'userId' => $user->getId(),
  136.                         'tokenId' => $newReset->getUserPasswordChangeId()
  137.                     ],
  138.                     null,
  139.                     $request->getClientIp()
  140.                 );
  141.                 $this->entityManager->commit();
  142.                 $this->addFlash('success''Jeśli dane zostały wprowadzone poprawnie, otrzymasz wiadomość e-mail z instrukcjami dotyczącymi resetowania hasła.');
  143.             } catch (\Exception $e) {
  144.                 $this->entityManager->rollback();
  145.                 $this->addFlash('error''Wystąpił błąd podczas przetwarzania żądania. Prosimy spróbować ponownie.');
  146. //                $this->addFlash('error', $e->getMessage());
  147.             }
  148.             return $this->redirectToRoute('app-reset-password-request');
  149.         }
  150.         return $this->render('security/reset_password_registation.html.twig', ['app_settings' => $this->_AppSettings]);
  151.     }
  152.     #[Route('/resetowanie-hasla/zmiana/{token}'name'app-reset-password'methods: ["GET""POST"])]
  153.     public function appResetPassword(Request $requeststring $tokenUserPasswordHasherInterface  $passwordEncoder): Response
  154.     {
  155.         if ($request->isMethod('POST')) {
  156.             $csrfToken $request->request->get('_csrf_token');
  157.             if (!$this->csrfTokenManager->isTokenValid(new CsrfToken('reset_password'$csrfToken))) {
  158.                 throw new InvalidCsrfTokenException();
  159.             }
  160.             $userLogin = (string)$request->request->get('ress_username');
  161.             $password1 = (string)$request->request->get('reset_password1');
  162.             $password2 = (string)$request->request->get('reset_password2');
  163.             if (empty($password1) || empty($password2) || empty($userLogin)) {
  164.                 $this->addFlash('error''Wprowadzone dane są niekompletne.');
  165.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  166.             }
  167.             if ($password1 !== $password2) {
  168.                 $this->addFlash('error''Wprowadzone hasła różnią się.');
  169.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  170.             }
  171.             if (strlen($password1) < 10) {
  172.                 $this->addFlash('error''Hasło musi zawierać przynajmniej 10 znaków.');
  173.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  174.             }
  175.             if (!preg_match('/[0-9]/'$password1)) {
  176.                 $this->addFlash('error''Hasło musi zawierać cyfrę.');
  177.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  178.             }
  179.             if (!preg_match('/[@$%&!#*()_+-]/'$password1)) {
  180.                 $this->addFlash('error''Hasło musi zawierać znaki specjalne.');
  181.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  182.             }
  183.             if (!preg_match('/[a-z]/'$password1)) {
  184.                 $this->addFlash('error''Hasło musi zawierać co najmniej jedną małą literę!');
  185.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  186.             }
  187.             if (!preg_match('/[A-Z]/'$password1)) {
  188.                 $this->addFlash('error''Hasło musi zawierać co najmniej jedną wielką literę!');
  189.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  190.             }
  191.             $resetRequest $this->entityManager->getRepository(UserPasswordChange::class)
  192.                 ->findOneBy(['userPasswordChangeCode' => $token'userPasswordChangeStatus' => true]);
  193.             if (!$resetRequest) {
  194.                 $this->addFlash('error''Błędny login lub kod resetowania hasła wygasł. Sprawdź dane i spróbuj ponownie.');
  195.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  196.             }
  197.             $expiryTime = (clone $resetRequest->getCreatedAt())->modify('+6 hours');
  198.             if (new \DateTime() > $expiryTime) {
  199. //                $this->addFlash('error', 'Błędny lub wykorzystany klucz zmiany hasła.');
  200.                 $this->addFlash('error''Błędny login lub kod resetowania hasła wygasł. Sprawdź dane i spróbuj ponownie.');
  201.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  202.             }
  203.             $user $this->entityManager->getRepository(Users::class)
  204.                 ->find($resetRequest->getUserId());
  205.             if (!$user) {
  206.                 //            $this->addFlash('error', 'Nie znaleziono użytkownika.');
  207.                 $this->addFlash('error''Błędny login lub kod resetowania hasła wygasł. Sprawdź dane i spróbuj ponownie.');
  208.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  209.             }
  210.             if($user->getUserIdentifier() != $userLogin){
  211.                 $this->addFlash('error''Błędny login lub kod resetowania hasła wygasł. Sprawdź dane i spróbuj ponownie.');
  212.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  213.             }
  214.             if (!$user->isUserStatus()) {
  215.                 //            $this->addFlash('error', 'Twoje konto jest zablokowane. Skontaktuj się z administratorem.');
  216.                 $this->addFlash('error''Błędny login lub kod resetowania hasła wygasł. Sprawdź dane i spróbuj ponownie.');
  217.                 return $this->redirectToRoute('app-reset-password', ['token' => $token]);
  218.             }
  219.             $hashedPassword $passwordEncoder->hashPassword($user$password1);
  220.             $user->setPassword($hashedPassword);
  221.             $user->setPasswordChangedAt(new \DateTime());
  222.             $user->setTryLogin(0);
  223.             $user->setUserStatus(true);
  224.             $user->setUpdatedAt(new \DateTime());
  225.             $resetRequest->setUserPasswordChangeStatus(false);
  226.             $resetRequest->setUserPasswordChangeDateUsed(new \DateTime());
  227.             $this->entityManager->flush();
  228.             $log $this->logService->createLog(
  229.                 47,
  230.                 [
  231.                     'userId' => $user->getId(),
  232.                     'tokenId' => $resetRequest->getUserPasswordChangeId(),
  233.                 ],
  234.                 null,
  235.                 $request->getClientIp()
  236.             );
  237.             $this->addFlash('success''Hasło zostało pomyślnie zresetowane.');
  238.             return $this->redirectToRoute('app_login');
  239.         }
  240.         return $this->render('security/reset_password.html.twig', ['app_settings' => $this->_AppSettings]);
  241.     }
  242. }