<?php
// src/Controller/SecurityController.php
namespace App\Controller;
use App\Entity\User;
use App\Form\LoginType;
use App\Form\Model\ChangePassword;
use App\Form\Type\ChangePasswordType;
use App\Repository\LoginAttemptRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
/**
* @see https://symfony.com/doc/current/security.html
*/
class SecurityController extends AbstractController
{
/**
* @Route("/login", name="login", methods={"GET", "POST"})
*/
public function login(AuthenticationUtils $authenticationUtils): Response
{
// Redirect if a User is already authenticated
if ($this->getUser()) {
$this->redirectToRoute('target_path');
}
// Create the form
$form = $this->createForm(LoginType::class, [
'_username' => $authenticationUtils->getLastUsername(),
], [
'method' => "POST",
'action' => $this->generateUrl('login_check'),
]);
return $this->render('security/login.html.twig', [
'form_login' => $form->createView(),
'error' => $authenticationUtils->getLastAuthenticationError()
]);
}
/**
* @Route("/login_check", name="login_check", methods={"POST"})
*/
public function check()
{
throw new \RuntimeException('You must configure the check_path to be handled by the firewall using form_login in your security firewall configuration.');
}
/**
* @Route("/logout", name="logout")
*
* @see https://symfony.com/doc/current/security.html#logging-out
*/
public function logout()
{
// controller can be blank: it will never be executed!
throw new \Exception('Don\'t forget to activate logout in security.yaml');
}
/**
* @Route("/register", name="register")
*/
public function register(Request $request)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', 'Welcome '.$user->getEmail());
// Automatic login after successful registration
return $this->get('security.authentication.guard_handler')->authenticateUserAndHandleSuccess(
$user,
$request,
$this->get('app.security.login_form_authenticator'),
'main'
);
}
return $this->render('security/register.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/change-password", name="change_password", methods={"GET","POST"})
*/
public function changePassword(Request $request)
{
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
$user = $this->getUser();
$form = $this->createForm(ChangePasswordType::class, new ChangePassword, [
'action' => $this->generateUrl($request->get('_route')),
'method' => "POST",
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$user->setPlainPassword($form->getData()->getNewPassword());
$this->getDoctrine()->getManager()->flush();
} catch (\Throwable $e) {
$this->addFlash('danger', 'Could not change your password!');
}
$this->addFlash('success', 'Your password has been changed successfully!');
return $this->redirectToRoute('logout');
}
return $this->render('security/password_change.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/.well-known/change-password", methods={"GET","POST"})
*
* @see https://web.dev/change-password-url/
* @see https://w3c.github.io/webappsec-change-password-url/
*/
public function wellKnownChangePassword(Request $request)
{
return $this->redirectToRoute('change_password');
}
/**
* @Route("/login-attempts", name="login_attempts", methods={"GET"})
*/
public function loginAttempts(LoginAttemptRepository $loginAttempts)
{
$this->denyAccessUnlessGranted('ROLE_SUPER_ADMIN');
return $this->json($loginAttempts->getRecentAttempts());
}
/**
* @Route("/maintenance", name="maintenance", methods={"GET","POST"})
*/
public function maintenance(Request $request)
{
$ipFile = $this->getParameter('kernel.project_dir').'/config/whitelist';
if ($request->get('maintenance')) {
$form = $request->get('maintenance');
if(!isset($form['activated'])){
@unlink($this->getParameter('kernel.project_dir').'/0_MAINTENANCE');
}else{
fopen($this->getParameter('kernel.project_dir').'/0_MAINTENANCE', "w");
}
$ipfile = fopen($ipFile, "w");
$ipList = array_unique(explode(PHP_EOL,$form['iplist']));
foreach($ipList as $ip){
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP)) {
fwrite($ipfile,$ip.PHP_EOL);
}
}
return $this->redirectToRoute('maintenance');
}
$maintenanceMode = ($_ENV["MAINTENANCE"] == "ENABLED") ? true : false;
$ipList = implode("\n",file($ipFile, FILE_IGNORE_NEW_LINES));
return $this->render('security/maintenance.html.twig', [
'maintenanceMode' => $maintenanceMode,
'ipList' => $ipList
]);
}
}