diff --git a/src/Controller/ResetPasswordController.php b/src/Controller/ResetPasswordController.php new file mode 100644 index 0000000..d5b6430 --- /dev/null +++ b/src/Controller/ResetPasswordController.php @@ -0,0 +1,184 @@ +resetPasswordHelper = $resetPasswordHelper; + $this->entityManager = $entityManager; + } + + /** + * Display & process form to request a password reset. + * + * @Route("", name="app_forgot_password_request") + */ + public function request(Request $request, MailerInterface $mailer, TranslatorInterface $translator): Response + { + $form = $this->createForm(ResetPasswordRequestFormType::class); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + return $this->processSendingPasswordResetEmail( + $form->get('email')->getData(), + $mailer, + $translator + ); + } + + return $this->render('reset_password/request.html.twig', [ + 'requestForm' => $form->createView(), + ]); + } + + /** + * Confirmation page after a user has requested a password reset. + * + * @Route("/check-email", name="app_check_email") + */ + public function checkEmail(): Response + { + // Generate a fake token if the user does not exist or someone hit this page directly. + // This prevents exposing whether or not a user was found with the given email address or not + if (null === ($resetToken = $this->getTokenObjectFromSession())) { + $resetToken = $this->resetPasswordHelper->generateFakeResetToken(); + } + + return $this->render('reset_password/check_email.html.twig', [ + 'resetToken' => $resetToken, + ]); + } + + /** + * Validates and process the reset URL that the user clicked in their email. + * + * @Route("/reset/{token}", name="app_reset_password") + */ + public function reset(Request $request, UserPasswordHasherInterface $userPasswordHasher, TranslatorInterface $translator, string $token = null): Response + { + if ($token) { + // We store the token in session and remove it from the URL, to avoid the URL being + // loaded in a browser and potentially leaking the token to 3rd party JavaScript. + $this->storeTokenInSession($token); + + return $this->redirectToRoute('app_reset_password'); + } + + $token = $this->getTokenFromSession(); + if (null === $token) { + throw $this->createNotFoundException('No reset password token found in the URL or in the session.'); + } + + try { + $user = $this->resetPasswordHelper->validateTokenAndFetchUser($token); + } catch (ResetPasswordExceptionInterface $e) { + $this->addFlash('reset_password_error', sprintf( + '%s - %s', + $translator->trans(ResetPasswordExceptionInterface::MESSAGE_PROBLEM_VALIDATE, [], 'ResetPasswordBundle'), + $translator->trans($e->getReason(), [], 'ResetPasswordBundle') + )); + + return $this->redirectToRoute('app_forgot_password_request'); + } + + // The token is valid; allow the user to change their password. + $form = $this->createForm(ChangePasswordFormType::class); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + // A password reset token should be used only once, remove it. + $this->resetPasswordHelper->removeResetRequest($token); + + // Encode(hash) the plain password, and set it. + $encodedPassword = $userPasswordHasher->hashPassword( + $user, + $form->get('plainPassword')->getData() + ); + + $user->setPassword($encodedPassword); + $this->entityManager->flush(); + + // The session is cleaned up after the password has been changed. + $this->cleanSessionAfterReset(); + + return $this->redirectToRoute('app_home'); + } + + return $this->render('reset_password/reset.html.twig', [ + 'resetForm' => $form->createView(), + ]); + } + + private function processSendingPasswordResetEmail(string $emailFormData, MailerInterface $mailer, TranslatorInterface $translator): RedirectResponse + { + $user = $this->entityManager->getRepository(User::class)->findOneBy([ + 'email' => $emailFormData, + ]); + + // Do not reveal whether a user account was found or not. + if (!$user) { + return $this->redirectToRoute('app_check_email'); + } + + try { + $resetToken = $this->resetPasswordHelper->generateResetToken($user); + } catch (ResetPasswordExceptionInterface $e) { + // If you want to tell the user why a reset email was not sent, uncomment + // the lines below and change the redirect to 'app_forgot_password_request'. + // Caution: This may reveal if a user is registered or not. + // + // $this->addFlash('reset_password_error', sprintf( + // '%s - %s', + // $translator->trans(ResetPasswordExceptionInterface::MESSAGE_PROBLEM_HANDLE, [], 'ResetPasswordBundle'), + // $translator->trans($e->getReason(), [], 'ResetPasswordBundle') + // )); + + return $this->redirectToRoute('app_check_email'); + } + + $email = (new TemplatedEmail()) + ->from(new Address('mailer@sfycas.local', '"Sfycas mail bot"')) + ->to($user->getEmail()) + ->subject('Your password reset request') + ->htmlTemplate('reset_password/email.html.twig') + ->context([ + 'resetToken' => $resetToken, + ]) + ; + + $mailer->send($email); + + // Store the token object in session for retrieval in check-email route. + $this->setTokenObjectInSession($resetToken); + + return $this->redirectToRoute('app_check_email'); + } +} diff --git a/src/Controller/SfyCASLoginController.php b/src/Controller/SfyCASLoginController.php index 6f6e93d..d48b660 100755 --- a/src/Controller/SfyCASLoginController.php +++ b/src/Controller/SfyCASLoginController.php @@ -11,6 +11,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\HttpFoundation\Cookie; +use Symfony\Component\Routing\Generator\UrlGenerator; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Psr\Log\LoggerInterface; @@ -54,10 +55,14 @@ class SfyCASLoginController extends AbstractController $casSession=$_casSession[0]; $logger->info('SFYCAS Session : ' . $casSession->getTicket()); } else { + $logger->info('SFYCAS Session : create new cas session'); $casSession=new SfyCASSession(); } + $chemin=$request->getBasePath(); + + //$logger->info('SFYCAS login base url : ' . $request); $service=$request->query->get('service'); $user=$this->getUser(); //echo $user->getUsername(); @@ -71,9 +76,35 @@ class SfyCASLoginController extends AbstractController $entityManager->flush(); //$response = new RedirectResponse($service. '?ticket=ST-ABFDABFE'); - $response = new RedirectResponse($service. '&ticket=ST-' . $ticket); + + $attributes = parse_url($service); + $params = $attributes['query']; + if(isset($attributes['query'])) { + $responseUrl = $service. '&ticket=ST-'.$ticket; + } else { + $responseUrl = $service. '?ticket=ST-'.$ticket; + } + + + //$response = new RedirectResponse($service. '?ticket=ST-' . $ticket); + $response = new RedirectResponse($responseUrl); + /*$response->headers->set('Set-Cookie', + Cookie::create( + 'sfy_cas_session', + $casSession->getTicket(), + time() + 60 * 60 * 24 * 30, + '/', + null, + false, + true, + false, + Cookie::SAMESITE_LAX + ) + ); + */ + $response->headers->setCookie(Cookie::create('CASTGC', 'ST-' . $ticket)); - $logger->info('SFYCAS login user : ' . $user . ' service : ' . $service); + $logger->info('SFYCAS login user : ' . $user . 'ticket ' . $ticket . ' service : ' . $service); return $response; //return $this->redirect($service. '?ticket=ST-ABFDABFE'); diff --git a/src/Controller/SfyCASServiceValidator.php b/src/Controller/SfyCASServiceValidator.php index 93cd708..9cd1446 100755 --- a/src/Controller/SfyCASServiceValidator.php +++ b/src/Controller/SfyCASServiceValidator.php @@ -19,18 +19,61 @@ class SfyCASServiceValidator extends AbstractController { public function validate(Request $request, LoggerInterface $logger): Response { $logger->warning('SFYCAS validate ' . $request->query->get('ticket')); - $ticket=$request->query->get('ticket'); + $ticket = $request->query->get('ticket'); + $logger->info('SFYCAS validate : looking session for ticket ' . $ticket); $casSession = $this->getDoctrine()->getRepository(SfyCASSession::class) ->findOneBy(['ticket' => $ticket]); - $logger->info('SFYCAS validate found session ' . $casSession->getLogin()); - return $this->render('sfy_cas_login/cas_validate.html.twig', [ - 'controller_name' => 'SfyCASServiceValidator', - 'login' => $casSession->getLogin(), - 'ticket' => $casSession->getTicket(), - ]); + if ($casSession) { + $logger->info('SFYCAS validate found session ' . $casSession->getLogin() . ' ticket ' . $casSession->getTicket()); + + return $this->render('sfy_cas_login/cas_validate.html.twig', [ + 'controller_name' => 'SfyCASServiceValidator', + 'login' => $casSession->getLogin(), + 'ticket' => $casSession->getTicket(), + ]); + } else { + $logger->info('SFYCAS no session found for ticket ' . $ticket); + return $this->render('sfy_cas_validate/error.html.twig', [ + 'controller_name' => 'SfyCASServiceValidator', + 'message' => 'ticket not found', + ]); + } } + + /** + * @Route("/cas/p3/serviceValidate", defaults={"_format"="xml"}, name="app_cas_p3_validate") + */ + public function p3Validate(Request $request, LoggerInterface $logger): Response + { + $logger->warning('SFYCAS p3 validate '. $request->query->get('ticket')); + $response = $this->forward('App\Controller\SfyCASServiceValidator::validate', ['request' => $request]); + return $response; + + $ticket = $request->query->get('ticket'); + + $logger->info('SFYCAS validate : looking session for ticket ' . $ticket); + $casSession = $this->getDoctrine()->getRepository(SfyCASSession::class) + ->findOneBy(['ticket' => $ticket]); + + + if ($casSession) { + $logger->info('SFYCAS v3 validate found session ' . $casSession->getLogin() . ' ticket ' . $casSession->getTicket()); + + return $this->render('sfy_cas_login/cas_validate.html.twig', [ + 'controller_name' => 'SfyCASServiceValidator', + 'login' => $casSession->getLogin(), + 'ticket' => $casSession->getTicket(), + ]); + } else { + $logger->info('SFYCAS no session found for ticket ' . $ticket); + return $this->render('sfy_cas_validate/error.html.twig', [ + 'controller_name' => 'SfyCASServiceValidator', + 'message' => 'ticket not found', + ]); + } + } } diff --git a/templates/sfy_cas_validate/error.html.twig b/templates/sfy_cas_validate/error.html.twig new file mode 100644 index 0000000..c242e47 --- /dev/null +++ b/templates/sfy_cas_validate/error.html.twig @@ -0,0 +1,5 @@ + + + {{ message}} + + \ No newline at end of file diff --git a/templates/sfy_cas_validate/sucess.html.twig b/templates/sfy_cas_validate/sucess.html.twig new file mode 100644 index 0000000..ca61f3c --- /dev/null +++ b/templates/sfy_cas_validate/sucess.html.twig @@ -0,0 +1,5 @@ + + + {{ login }} + + \ No newline at end of file