<?php
namespace App\Security;
use App\Entity\Periodo;
use App\Entity\Usuario;
use App\Entity\ViewProfile;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class LoginAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
private UrlGeneratorInterface $urlGenerator;
private ManagerRegistry $em;
public function __construct(UrlGeneratorInterface $urlGenerator, ManagerRegistry $managerRegistry)
{
$this->urlGenerator = $urlGenerator;
$this->em = $managerRegistry;
}
public function supports(Request $request): bool
{
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function authenticate(Request $request): Passport
{
$correo = $request->request->get('correo', '');
$request->getSession()->set(Security::LAST_USERNAME, $correo);
return new Passport(
new UserBadge($correo, function ($userIdentifier) {
$user = $this->em->getRepository(Usuario::class)->findOneBy(['correo' => $userIdentifier]);
if ($user && $user->getEstatus() == "Pendiente") {
throw new CustomUserMessageAuthenticationException('Access request pending evaluation.');
}
if ($user && $user->getEstatus() == "Rechazado") {
throw new CustomUserMessageAuthenticationException('Access request has been rejected.');
}
if ($user && $user->getEstatus() == "Suspendido") {
throw new CustomUserMessageAuthenticationException('Access credentials suspended.');
}
return $user;
}),
new PasswordCredentials($request->request->get('password', '')),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
/** @var Usuario $user */
$user = $token->getUser();
$rol = $user->getRol()->getIdRol();
$estatusActual = $user->getEstatus();
# Si el usuario tiene rol de "Aceptado" entonces se actualiza a "Activo"
if ($estatusActual == "Aceptado") {
$user->setEstatus("Activo");
$this->em->getManager()->persist($user);
$this->em->getManager()->flush();
}
# Se obtiene el periodo actual
$periodo = $this->em->getRepository(Periodo::class)->findOneBy(['actual' => 1]);
# Se obtienen los módulos y comportamientos acorde al rol del usuario
$acciones = $this->em->getRepository(ViewProfile::class)->findBy(['idRol' => $rol]);
$perfil = [];
$menu = [];
foreach ($acciones AS $accion) {
# Construcción de la variable de perfil con la información de módulos y comportamientos por rol
$perfil[$accion->getIdMod()] = [
"idMod" => $accion->getIdMod(),
"nombre" => $accion->getModulo(),
"submenu" => $accion->getSubmenu(),
"idBeh" => $accion->getIdBeh(),
"nivel" => $accion->getNivel(),
"comportamiento" => $accion->getComportamiento(),
"descripcion" => $accion->getDescripcion()
];
# Construcción del menú lateral derecho en la variable de sesión
if ($accion->getNivel() > 0) {
if (empty($accion->getSubmenu())) {
$menu[$accion->getOrden()] = [
"idMenu" => $accion->getIdMenu(),
"menu" => $accion->getModulo(),
"icono" => $accion->getIcono(),
"ruta" => $accion->getRuta(),
"submenu" => false
];
} else {
if (!array_key_exists($accion->getOrden(), $menu)) {
$menu[$accion->getOrden()] = [
"idMenu" => $accion->getIdMenu(),
"menu" => $accion->getModulo(),
"icono" => $accion->getIcono(),
"ruta" => "#"
];
}
$menu[$accion->getOrden()]["submenu"][] = [
"idMenu" => $accion->getIdSubmenu(),
"menu" => $accion->getSubmenu(),
"icono" => "fa-angle-double-up",
"ruta" => $accion->getRuta()
];
}
}
}
ksort($menu);
$request->getSession()->set('periodo', $periodo);
$request->getSession()->set('perfil', $perfil);
$request->getSession()->set('menu', $menu);
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('homepage'));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}