<?php
namespace App\Controller;
use App\Entity\Painel\LogSenha;
use App\Entity\Painel\Usuario;
use App\Helper\StringHelper;
use App\Repository\Painel\LogSenhaRepository;
use App\Repository\Painel\UsuarioRepository;
use App\Service\Email;
use App\Service\S3Service;
use App\Service\QrCodeService;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
class UsuarioController extends AbstractController
{
private $usuario;
private $encoder;
private $mailer;
private $perfil;
private $em;
private $logSenha;
private $s3;
public function __construct(
UsuarioRepository $usuarioRepository,
UserPasswordEncoderInterface $encoder,
EntityManagerInterface $em,
LogSenhaRepository $logSenhaRepository,
S3Service $s3Service,
QrCodeService $qrCodeService
) {
$this->usuario = $usuarioRepository;
$this->logSenha = $logSenhaRepository;
$this->encoder = $encoder;
$this->em = $em;
$this->s3 = $s3Service;
$this->qrCodeService = $qrCodeService;
}
/**
* @Route("/user/recuperar-senha", name="usuario_recuperar_senha")
*/
public function recuperarSenha(Request $request, Email $email)
{
$dados = $request->request->all();
$usuario = $this->usuario->findOneBy(['email' => $dados['email']]);
if (empty($usuario)) {
$request->getSession()->getFlashBag()->add('success', 'Caso o usuário exista, um e-mail de recuperação de senha foi enviado.');
} else {
$senhaNova = StringHelper::geraSenha(7);
$data_atual = new \DateTime();
$params = [
'name' => $usuario->getNome(),
'subject' => "Recuperar Senha 2IM Analytics - {$data_atual->format('d/m/Y H:i:s')}",
'nome' => $usuario->getNome(),
'login' => $usuario->getLogin(),
'to' => $usuario->getEmail(),
'id' => $usuario->getId_usuario(),
'template' => 'email/recuperar-senha.html.twig',
'novaSenha' => $senhaNova,
];
$testeEnvio = $email->enviar($params);
if ( $testeEnvio['status'] > 0 ) {
$usuario->setForce_update(true);
$usuario->setSenha($this->encoder->encodePassword($usuario, $senhaNova));
$this->em->flush();
$request->getSession()->getFlashBag()->add('success', 'Email de recuperação de senha enviado!');
} else {
$request->getSession()->getFlashBag()->add('error', 'Erro ao enviar email para recuperação de senha!');
}
}
return $this->redirectToRoute('app_login');
}
/**
* @Route("/user/recuperar-qrcode/{loginUser}", name="usuario_recuperar_qrcode")
*/
public function recuperarQrCode($loginUser, Email $email, Request $request)
{
$usuario = $this->usuario->findOneBy(['login' => $loginUser]);
if (empty($usuario)) {
$request->getSession()->getFlashBag()->add('erro', 'Erro ao enviar email para recuperação de senha!');
} else {
$qrCode = $this->qrCodeService->generateQrCode($usuario);
$params = [
'name' => $usuario->getNome(),
'subject' => 'Recuperar QrCode 2IM Analytics',
'nome' => $usuario->getNome(),
'login' => $usuario->getLogin(),
'to' => $usuario->getEmail(),
'id' => $usuario->getId_usuario(),
'qrCode' => $qrCode,
'template' => 'email/recuperar-qrcode.html.twig',
];
$testeEnvio = $email->enviar($params);
if ($testeEnvio['status'] > 0) {
$request->getSession()->getFlashBag()->add('sucess', 'Email de recuperação de QrCode enviado!');
} else {
$request->getSession()->getFlashBag()->add('erro', 'Erro ao enviar email para recuperação de QrCode!');
}
}
return $this->redirectToRoute('app_login');
}
/**
* @Route("/user/redefinir-senha", name="usuario_redefinir_senha")
*/
public function redefinirSenha(Request $request, UserInterface $usuario = null, Email $email)
{
if (!$usuario) {
$this->addFlash('error', 'Erro em parametros do usuario');
return $this->redirectToRoute('app_login');
}
$this->em->beginTransaction();
try {
if ($request->isMethod('POST')) {
$dados = $request->request->all();
if (!$this->validPassword($dados['senha'], $dados['repete_senha'], $usuario)) {
return $this->redirectToRoute('usuario_redefinir_senha');
}
// Enviar e-mail informando a redefinição de senha.
$data_atual = new DateTime('America/Sao_Paulo');
/*$enviado = $email->redefinirSenha(
$usuario->getEmail(),
$usuario->getNome(),
$request->getClientIp(),
$data_atual->format('d/m/Y H:i:s'),
$this->generateUrl('app_login', [], UrlGeneratorInterface::ABSOLUTE_URL)
);/** */
//if ( $enviado ) {
$senha = $this->encoder->encodePassword($usuario, $dados['senha']);
$usuario->setSenha($senha);
$usuario->setSenha_update($data_atual->format('d/m/Y H:i:s'));
$usuario->setForce_update(false);
$logSenha = new LogSenha();
$logSenha->setUsuario($usuario)
->setSenha($senha)
;
$this->em->persist($logSenha);
$this->em->flush();
$this->em->commit();
// $this->addFlash('sucess', 'Email de redefinição de senha enviado!');
//} else {
$this->addFlash('error', 'Erro ao enviar email para redefinição de senha!');
//}
$this->addFlash('sucess', 'Sua senha foi atualizada!');
return $this->redirectToRoute('app_logout');
}
} catch (\Throwable $e) {
$this->em->rollBack();
if (12 === $e->getCode()) {
$this->addFlash('error', $e->getMessage());
return $this->redirectToRoute('usuario_redefinir_senha');
}
throw $e;
}
return $this->render(
'usuario-update-senha.twig',
[
'page' => 'page-visoes',
]
);
}
/**
* @Route("/user/meus-dados", name="usuario_meus_dados")
*/
public function meusDadosAction(Request $request, UserInterface $usuarioLogged)
{
try {
$dados = $request->request->all();
if ($request->isMethod('POST')) {
$this->em->beginTransaction();
$arquivo = $request->files->get('foto');
if ($arquivo) {
$file = new File($arquivo);
// Upload data.
$filePath = "foto_{$usuarioLogged->getId_usuario()}.{$arquivo->guessClientExtension()}";
$object = [
'Bucket' => $_ENV['AWS_S3_BUCKET'],
'Key' => "painel/usuarios/foto/{$filePath}",
'SourceFile' => $file,
'ACL' => 'public-read',
'ContentType' => $arquivo->getMimeType(),
'Tagging' => "usuari_{$usuarioLogged->getId_usuario()}",
];
$resposta = $this->s3->upload($object);
if (true == $resposta['status']) {
$usuarioLogged->setFoto($filePath);
$this->addFlash('sucess', $resposta['message']);
} else {
$this->addFlash('error', $resposta['message']);
}
// seta a imagem do usario
$foto = $this->s3->download($_ENV['AWS_S3_BUCKET'], "painel/usuarios/foto/{$filePath}");
if ($foto) {
$request->getSession()->set('foto', $foto['@metadata']['effectiveUri']);
}
}
$usuarioLogged->setEmail($dados['email'])
->setLogin($dados['login'])
->setNome($dados['nome'])
;
if (isset($dados['senha'])) {
$this->validPassword($dados['senha'], $dados['repete_senha'], $usuarioLogged);
$usuarioLogged->setSenha($this->encoder->encodePassword($usuarioLogged, $dados['senha']));
}
$this->em->flush();
$this->em->commit();
$this->addFlash('sucess', 'Dados editados.');
}
} catch (\Throwable $e) {
dd($e);
$code = (0 == $e->getCode()) ? 500 : $e->getCode();
$mensagens = 500 == $code ? ['Ocorreu um erro, estamos resolvendo!'] : explode(',', $e->getMessage());
foreach ($mensagens as $mensagem) {
$this->addFlash('error', $mensagem);
}
$this->em->rollback();
}
return $this->render(
'usuario-meus-dados.html.twig',
[
'page' => 'page-green',
'usuario' => $usuarioLogged,
]
);
}
/**
* @Route("/user/foto", name="foto")
*/
public function foto(Request $request, UserInterface $usuario = null)
{
return $this->render('usuario-foto.html.twig');
}
private function validPassword($senha, $repeteSenha = false, $usuario): bool
{
// testa se senhas são iguais
if ($repeteSenha) {
if ($senha != $repeteSenha) {
$this->addFlash('error', 'Senhas devem ser iguais!');
return false;
}
}
// testa caracteres da senha
if (strlen($senha) < 8 || !preg_match('/ *[0-9].*[A-Z].*[@$!%*#?&.,=+-\/(\/):;\/^\/~\/|"]| *[0-9].*[@$!%*#?&.,=+-\/(\/):;\/^\/~\/|"].*[A-Z]| *[A-Z].*[0-9].*[@$!%*#?&.,=+-\/(\/):;\/^\/~\/|"]| *[A-Z].*[@$!%*#?&.,=+-\/(\/):;\/^\/~\/|"].*[0-9]| *[@$!%*#?&.,=+-\/(\/):;\/^\/~\/|"].*[A-Z].*[0-9]| *[@$!%*#?&.,=+-\/(\/):;\/^\/~\/|"].*[0-9].*[A-Z]/', $senha)) {
$this->addFlash('error', 'Os campos senha deve ter no mínimo 8 caracters com LETRAS(pelo menos uma maiúscula) e NÚMEROS e CARACTERES ESPECIAIS!');
return false;
}
// testa se senha contem algum dado cadastrado
// $nomeDividido = explode(' ', $usuario->getNome());
// $nomeInteiro = preg_match('/'.strtolower(str_replace(' ', '', $usuario->getNome())).'/', strtolower($senha));
// foreach ($nomeDividido as $parteNome) {
// $testeNome = preg_match('/'.strtolower($parteNome).'/', strtolower($senha));
// if ($testeNome) {
// break;
// }
// }
// $login = $usuario->getLogin();
// $loginTeste = preg_match('/'.$login.'/', $senha);
// if ($nomeInteiro || $loginTeste || $testeNome) {
// $this->addFlash('error', 'Senha não pode conter nenhum de seus dados pessoais!');
// return false;
// }
// testa senhas sequenciais
$letras = '/abcdefghijklmnopqrstuvxzwy/';
$letrasInvertido = '/ywzxvutsrqponmlkjihgfedcba/';
$numeros = '/0123456789/';
$numerosInvertido = '/9876543210/';
$seqLetrasInvertido = false;
$seqNumerosInvertido = false;
$seqLetras = false;
$seqNumeros = false;
$countSenha = strlen($senha);
for ($i = 0; $i < $countSenha; ++$i) {
if ($i + 2 < $countSenha) {
$teste = $senha[$i].$senha[$i + 1].$senha[$i + 2];
$seqLetras = strstr($letras, strtolower($teste));
$seqLetrasInvertido = strstr($letrasInvertido, strtolower($teste));
$seqNumeros = strstr($numeros, $teste);
$seqNumerosInvertido = strstr($numerosInvertido, $teste);
if ($seqLetras || $seqNumeros || $seqLetrasInvertido || $seqNumerosInvertido) {
$this->addFlash('error', 'Senha não pode conter sequencia de letras ou numeros!');
return false;
}
}
}
// verifica se senha ja foi usada
$logSenhas = $this->logSenha->findBy(['usuario' => $usuario]);
$verificaSenha = false;
foreach ($logSenhas as $logSenha) {
$user = new Usuario();
$user->setSenha($logSenha->getSenha());
$verificaSenha = $this->encoder->isPasswordValid($user, $senha);
if ($verificaSenha) {
$user = '';
break;
}
}
if ($verificaSenha) {
$this->addFlash('error', 'Esta senha já foi utilizada anteriormente. Por favor, escolha uma senha nova.');
return false;
}
return true;
}
}