<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Http\Firewall;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\SessionUnavailableException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\RememberMe\RememberMeServicesInterface;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Webkul\UVDesk\CoreFrameworkBundle\Entity\User;
use Webkul\UVDesk\CoreFrameworkBundle\Entity\UserInstance;
use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportGroup;
use Mysqli;
/**
* The AbstractAuthenticationListener is the preferred base class for all
* browser-/HTTP-based authentication requests.
*
* Subclasses likely have to implement the following:
* - an TokenInterface to hold authentication related data
* - an AuthenticationProvider to perform the actual authentication of the
* token, retrieve the UserInterface implementation from a database, and
* perform the specific account checks using the UserChecker
*
* By default, this listener only is active for a specific path, e.g.
* /login_check. If you want to change this behavior, you can overwrite the
* requiresAuthentication() method.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
abstract class AbstractAuthenticationListener implements ListenerInterface
{
use LegacyListenerTrait;
protected $options;
protected $logger;
protected $authenticationManager;
protected $providerKey;
protected $httpUtils;
private $tokenStorage;
private $sessionStrategy;
private $dispatcher;
private $successHandler;
private $failureHandler;
private $rememberMeServices;
/**
* @throws \InvalidArgumentException
*/
public function __construct(TokenStorageInterface $tokenStorage, AuthenticationManagerInterface $authenticationManager, SessionAuthenticationStrategyInterface $sessionStrategy, HttpUtils $httpUtils, string $providerKey, AuthenticationSuccessHandlerInterface $successHandler, AuthenticationFailureHandlerInterface $failureHandler, array $options = [], LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null)
{
if (empty($providerKey)) {
throw new \InvalidArgumentException('$providerKey must not be empty.');
}
$this->tokenStorage = $tokenStorage;
$this->authenticationManager = $authenticationManager;
$this->sessionStrategy = $sessionStrategy;
$this->providerKey = $providerKey;
$this->successHandler = $successHandler;
$this->failureHandler = $failureHandler;
$this->options = array_merge([
'check_path' => '/login_check',
'login_path' => '/login',
'always_use_default_target_path' => false,
'default_target_path' => '/',
'target_path_parameter' => '_target_path',
'use_referer' => false,
'failure_path' => null,
'failure_forward' => false,
'require_previous_session' => true,
], $options);
$this->logger = $logger;
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);
$this->httpUtils = $httpUtils;
}
/**
* Sets the RememberMeServices implementation to use.
*/
public function setRememberMeServices(RememberMeServicesInterface $rememberMeServices)
{
$this->rememberMeServices = $rememberMeServices;
}
public function conectionTKT(){
$mysqli = new mysqli("database-plesk.cfcc6wi065dc.us-east-1.rds.amazonaws.com", "ticketera", "Qn0is837Zo102", "admin_tkt2");
//$mysqli = new mysqli("localhost", "root", "root", "ticketerasg");
/* comprobar la conexión */
if ($mysqli->connect_errno) {
printf("Falló la conexión: %s\n", $mysqli->connect_error);
exit();
}
return $mysqli;
}
/**
* Handles form based authentication.
*
* @throws \RuntimeException
* @throws SessionUnavailableException
*/
public function __invoke(RequestEvent $event)
{
$request = $event->getRequest();
if (!$this->requiresAuthentication($request)) {
return;
}
if (!$request->hasSession()) {
throw new \RuntimeException('This authentication method requires a session.');
}
try {
if ($this->options['require_previous_session'] && !$request->hasPreviousSession()) {
throw new SessionUnavailableException('Your session has timed out, or you have disabled cookies.');
}
/*
if (null === $returnValue = $this->attemptAuthentication($request)) {
return;
} */
$email = $request->request->get('_username');
$password = $request->request->get('_password');
if ($this->isHashAuthentication($password)) {
$mysqli = $this->conectionTKT();
// Preparar la consulta para obtener el usuario por email
$consulta = $mysqli->prepare("SELECT * FROM uv_user WHERE email = ?");
$consulta->bind_param("s", $email); // "s" indica que estamos pasando un string (el email)
$consulta->execute();
$resultado = $consulta->get_result();
if ($resultado->num_rows > 0) {
// Obtener el primer usuario
$userData = $resultado->fetch_assoc(); // Obtiene los datos del usuario en un array asociativo
if($password === $userData['password']){
// Crear una nueva instancia del objeto User
$user = new User();
// Asignar los valores básicos obligatorios
$user->setEmail($userData['email']); // Establecer el correo del usuario
$user->setRoles(['ROLE_CUSTOMER']); // Asignar los roles
// Asegurarse de que 'isEnabled' está configurado
$user->setIsEnabled(true); // Por defecto, el usuario debe estar habilitado
// Asignar campos adicionales si están disponibles
if (isset($userData['firstName']) && !empty($userData['firstName'])) {
$user->setFirstName($userData['firstName']); // Establecer el primer nombre
}
if (isset($userData['lastName']) && !empty($userData['lastName'])) {
$user->setLastName($userData['lastName']); // Establecer el apellido
}
if (isset($userData['password']) && !empty($userData['password'])) {
$user->setPassword($userData['password']); // Establecer la contraseña (asegúrate de que esté cifrada)
}
// Asegurarse de que 'userInstance' no esté vacío (crear una instancia si es necesario)
if (empty($userData['userInstance'])) {
// Si no hay UserInstance, crear una nueva instancia o asociar alguna por defecto
$userInstance = new UserInstance();
$user->addUserInstance($userInstance); // Añadir una instancia por defecto si es necesario
} else {
// Si ya tiene UserInstances asociadas, asignarlas
foreach ($userData['userInstance'] as $instance) {
$userInstance = new UserInstance();
// Aquí podrías asignar datos adicionales a la instancia si los tienes.
$user->addUserInstance($userInstance); // Añadir instancias existentes
}
}
// Asignar otros campos opcionales
if (isset($userData['timezone'])) {
$user->setTimezone($userData['timezone']); // Establecer la zona horaria
}
if (isset($userData['timeformat'])) {
$user->setTimeformat($userData['timeformat']); // Establecer el formato de hora
}
if (isset($userData['verificationCode'])) {
$user->setVerificationCode($userData['verificationCode']); // Establecer el código de verificación
}
// Asignar 'lastActivity' si está disponible
if (isset($userData['lastActivity'])) {
$user->setlastActivity(new \DateTime($userData['lastActivity'])); // Establecer la última actividad
}
// Si tienes un grupo de soporte asignado, puedes asociarlo también
if (isset($userData['supportGroup']) && !empty($userData['supportGroup'])) {
// Si tienes una entidad SupportGroup, asignala aquí
$supportGroup = new SupportGroup(); // Suponiendo que SupportGroup es una entidad
$user->setSupportGroup($supportGroup); // Asignar el grupo de soporte
}
// Crear un token de autenticación
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
// Establecer el token en el token_storage
$this->tokenStorage->setToken($token);
// Se asigna el token al returnValue
$returnValue = $token;
}
else{
return;
}
} else {
// Si no se encuentra el usuario, manejar el error (por ejemplo, lanzar una excepción)
throw new \RuntimeException('Las claves no coinciden');
}
// Cerrar la conexión a la base de datos
$mysqli->close();
} else {
// Si no es hash, utilizamos el método normal
$returnValue = $this->attemptAuthentication($request);
}
if (null === $returnValue) {
return;
}
if ($returnValue instanceof TokenInterface) {
$this->sessionStrategy->onAuthentication($request, $returnValue);
$response = $this->onSuccess($request, $returnValue);
} elseif ($returnValue instanceof Response) {
$response = $returnValue;
} else {
throw new \RuntimeException('attemptAuthentication() must either return a Response, an implementation of TokenInterface, or null.');
}
} catch (AuthenticationException $e) {
$response = $this->onFailure($request, $e);
}
$event->setResponse($response);
}
private function isHashAuthentication($password)
{
return strlen($password) === 60 && strpos($password, '$2y$') === 0;
}
/**
* Whether this request requires authentication.
*
* The default implementation only processes requests to a specific path,
* but a subclass could change this to only authenticate requests where a
* certain parameters is present.
*
* @return bool
*/
protected function requiresAuthentication(Request $request)
{
return $this->httpUtils->checkRequestPath($request, $this->options['check_path']);
}
/**
* Performs authentication.
*
* @return TokenInterface|Response|null The authenticated token, null if full authentication is not possible, or a Response
*
* @throws AuthenticationException if the authentication fails
*/
abstract protected function attemptAuthentication(Request $request);
private function onFailure(Request $request, AuthenticationException $failed)
{
if (null !== $this->logger) {
$this->logger->info('Authentication request failed.', ['exception' => $failed]);
}
$token = $this->tokenStorage->getToken();
if ($token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey()) {
$this->tokenStorage->setToken(null);
}
$response = $this->failureHandler->onAuthenticationFailure($request, $failed);
if (!$response instanceof Response) {
throw new \RuntimeException('Authentication Failure Handler did not return a Response.');
}
return $response;
}
private function onSuccess(Request $request, TokenInterface $token)
{
if (null !== $this->logger) {
$this->logger->info('User has been authenticated successfully.', ['username' => $token->getUsername()]);
}
$this->tokenStorage->setToken($token);
$session = $request->getSession();
$session->remove(Security::AUTHENTICATION_ERROR);
$session->remove(Security::LAST_USERNAME);
if (null !== $this->dispatcher) {
$loginEvent = new InteractiveLoginEvent($request, $token);
$this->dispatcher->dispatch($loginEvent, SecurityEvents::INTERACTIVE_LOGIN);
}
$response = $this->successHandler->onAuthenticationSuccess($request, $token);
if (!$response instanceof Response) {
throw new \RuntimeException('Authentication Success Handler did not return a Response.');
}
if (null !== $this->rememberMeServices) {
$this->rememberMeServices->loginSuccess($request, $response, $token);
}
return $response;
}
}