<?php
namespace App\Controller;
use App\Annotation\CmsComponent;
use App\Entity\User;
use App\Form\ProfileType;
use App\Form\UserChangePasswordType;
use App\Form\UserProfileType;
use App\Form\UserType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
public function __construct(protected EntityManagerInterface $em, protected UserPasswordHasherInterface $hasher) {}
// //////////////////////////////////
// CMS USER PAGES
// ///////////////////////////////////
#[Route(path: '/takeflight/login', name: 'control_login')]
public function login(AuthenticationUtils $authenticationUtils): \Symfony\Component\HttpFoundation\Response
{
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
if ($error) {
$this->addFlash('error', 'Invalid Username or Password');
}
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('takeflight/login-control.html.twig', [
'last_username' => $lastUsername,
]);
}
#[Route(path: '/forgot-cms-password', name: 'forgot_cms_password')]
public function forgotCMSPassword(Request $request): \Symfony\Component\HttpFoundation\Response
{
$error = null;
$data = [];
$form = $this->createFormBuilder($data)
->add('email', TextType::class, ['label' => 'Email Address', 'attr' => ['placeholder' => 'Email']])
->getForm()
;
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$user = $this->em->getRepository(User::class)->findOneByEmail($data['email']);
if ($user) {
$url_encrypt = substr(md5(random_int(0, 999).'5h0rtt3rmm3m0ry1055?'.random_int(0, 999)), 0, 20);
$user->setEmailresetkey($url_encrypt);
$this->em->persist($user);
$this->em->flush();
$message = (new \Swift_Message())
->setSubject('CMS Password reset request for '.$this->getParameter('sitename'))
->setFrom($this->getParameter('email_norely'))
->setTo($user->getEmail())
->setBody(
$this->renderView('takeflight/email-password-reset.html.twig', [
'url_encrypt' => $url_encrypt,
'user' => $user,
]),
'text/html'
)
;
$this->get('mailer')->send($message);
}
$this->addFlash('success', 'If an account is found with that email address then instructions to reset your password will be sent ');
}
return $this->render('takeflight/admin-forgot.html.twig', [
'form' => $form->createView(),
'error' => $error,
]);
}
#[Route(path: '/password-cms-reset/{url_encrypt}', name: 'password_cms_reset')]
public function passwordCMSReset(Request $request, mixed $url_encrypt)
{
$user = $this->em->getRepository(User::class)->findOneByEmailresetkey($url_encrypt);
if (!$user) {
$this->addFlash('error', 'Email reset key not valid or has expired - please try to reset your password again.');
return $this->redirectToRoute('forgot_password');
}
if ($user) {
$error = null;
$data = [];
$form = $this->createFormBuilder($data)
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => 'Repeat Password'],
])
->getForm()
;
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$password = $this->hasher->hashPassword($user, $data['plainPassword']);
$user->setEmailresetkey(null);
$user->setPassword($password);
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'Your password has been reset');
return $this->redirectToRoute('control_login');
}
return $this->render('takeflight/admin-reset.html.twig', [
'form' => $form->createView(),
'error' => $error,
'url_encrypt' => $url_encrypt,
]);
}
}
#[Route(path: '/takeflight/user/create', name: 'admin_create')]
public function adminCreate(Request $request)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $this->hasher->hashPassword($user, $user->getPlainPassword());
$user->setPassword($password);
$user->setRoles([
'ROLE_ADMIN',
]);
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'User Created Successfully');
return $this->redirectToRoute('control_dash');
}
return $this->render('takeflight/admin-create.html.twig', [
'form' => $form->createView(),
]);
}
#[Route(path: '/takeflight/user/profile', name: 'control_profile')]
public function adminProfile(Request $request)
{
// 1) build the form
$user = $this->getUser();
$form = $this->createForm(ProfileType::class, $user);
// 2) handle the submit (will only happen on POST)
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $user->resizeImage($this->get('image.handling'));
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'Profile Updated Successfully');
return $this->redirectToRoute('control_profile');
}
return $this->render('takeflight/admin-profile.html.twig', [
'form' => $form->createView(),
'user' => $user,
]);
}
#[Route(path: '/takeflight/admin_check', name: 'control_check')]
public function adminCheck() {}
// route is handled by the Security system
// //////////////////////////////////
// MEMBER PAGES
// ///////////////////////////////////
/**
* @CmsComponent("User Login", active=false, routeName="member_login")
*/
#[Route(path: '/member-login', name: 'member_login')]
public function loginMember(): \Symfony\Component\HttpFoundation\Response
{
$authenticationUtils = $this->get('security.authentication_utils');
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('@theme/members/members-login.html.twig', [
'last_username' => $lastUsername,
'error' => $error,
]);
}
#[Route(path: '/members/member_check', name: 'member_check')]
public function memberCheck() {}
// route is handled by the Security system
/**
* @CmsComponent("User Register", active=false, routeName="member_register")
*/
#[Route(path: '/member-register', name: 'member_register')]
public function userRegister(Request $request)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$password = $this->hasher->hashPassword($user, $user->getPlainPassword());
$user->setPassword($password);
$user->setRoles(['ROLE_USER']);
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'User Created Successfully');
return $this->redirect('/');
}
return $this->render('@theme/members/members-register.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @CmsComponent("Member Password Reset", active=false, routeName="member_forgot_password")
*/
#[Route(path: '/member-forgot-password', name: 'member_forgot_password')]
public function forgotPassword(Request $request): \Symfony\Component\HttpFoundation\Response
{
$error = null;
$data = [];
$form = $this->createFormBuilder($data)
->add('email', TextType::class, ['label' => 'Email Address', 'attr' => ['placeholder' => 'Email']])
->getForm()
;
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$user = $this->em->getRepository(User::class)->findOneByEmail($data['email']);
if (!$user) {
$this->addFlash('error', 'Email Address not found');
}
if ($user) {
$url_encrypt = substr(md5(random_int(0, 999).'5h0rtt3rmm3m0ry1055?'.random_int(0, 999)), 0, 20);
$user->setEmailresetkey($url_encrypt);
$this->em->persist($user);
$this->em->flush();
$resetUrl = '/member-password-reset';
$message = (new \Swift_Message())
->setSubject('Password reset request for '.$this->getParameter('sitename'))
->setFrom($this->getParameter('email_norely'))
->setTo($user->getEmail())
->setBody(
$this->renderView('@theme/emails/forgot-password.html.twig', [
'resetUrl' => $resetUrl,
'url_encrypt' => $url_encrypt,
'user' => $user,
]),
'text/html'
)
;
$this->get('mailer')->send($message);
$this->addFlash('success', 'An email has been sent with instructions to reset your password');
}
// return $this->redirect('/');
}
return $this->render('@theme/members/members-forgot.html.twig', [
'form' => $form->createView(),
'error' => $error,
]);
}
#[Route(path: '/member-password-reset/{url_encrypt}', name: 'member_password_reset')]
public function passwordReset(Request $request, mixed $url_encrypt)
{
$user = $this->em->getRepository(User::class)->findOneByEmailresetkey($url_encrypt);
if (!$user) {
$this->addFlash('error', 'Email reset key not valid or has expired - please try to reset your password again.');
return $this->redirectToRoute('forgot_password');
}
if ($user) {
$error = null;
$data = [];
$form = $this->createFormBuilder($data)
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => 'Repeat Password'],
])
->getForm()
;
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$password = $this->hasher->hashPassword($user, $data['plainPassword']);
$user->setEmailresetkey(null);
$user->setPassword($password);
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'Your password has been reset');
return $this->redirectToRoute('member_login');
}
return $this->render('@theme/members/members-reset.html.twig', [
'form' => $form->createView(),
'error' => $error,
'url_encrypt' => $url_encrypt,
]);
}
}
#[Route(path: '/member/profile', name: 'member_profile')]
public function memberProfile(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(ProfileType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'Profile Updated Successfully');
return $this->redirectToRoute('member_profile');
}
return $this->render('@theme/members/members-profile.html.twig', [
'form' => $form->createView(),
'user' => $user,
]);
}
// /////////////////////////////////////////
// SECONDARY USER (MEMBER) PAGES : Seperated from admin and member users!
// Uses a completly different firewall setup
// Only used in very few circumstances - uses a seperate user table.
// I took the liberty to setup multiple security providers just in case we
// ever needed them - i think theres only been a couple of
// instances where this feature could of been used.
// THIS IS NOT FOR CMS USERS SO DONT MIX THEM WITH ADMIN OR MEMBER USERS!
//
// This should only be used for seperate public access to a site,
// i.e comments section profiles, register-to-access content or shop customers
// USE ONLY FOR NON CMS USERS - (due to foreign key constraints)
// ////////////////////////////////////////
#[Route(path: '/user/user-check', name: 'user_login_check')]
public function loginCheck() {}
#[Route(path: '/user/profile', name: 'user_profile')]
public function userProfile(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(UserProfileType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'Profile Updated Successfully');
return $this->redirectToRoute('user_profile');
}
return $this->render('@theme/user/user-profile.html.twig', [
'form' => $form->createView(),
'user' => $user,
]);
}
#[Route(path: '/user/edit-password', name: 'user_edit_password')]
public function userEditPassword(Request $request, UserPasswordHasherInterface $hasher)
{
$user = $this->getUser();
$editForm = $this->createForm(UserChangePasswordType::class, $user);
$editForm->handleRequest($request);
if ($editForm->isSubmitted()) {
if ($editForm->isValid()) {
$data = $editForm->getData();
$password = $hasher->hashPassword($user, $data->getPlainPassword());
// @var User $user
$user->setEmailresetkey(null);
$user->setPassword($password);
$this->em->persist($user);
$this->em->flush();
$this->addFlash('success', 'Success - User Credentials updated');
return $this->redirectToRoute('user_profile');
}
$this->addFlash('error', 'Error - User not saved');
}
return $this->render('@theme/user/user-password.html.twig', [
'user' => $user,
'form' => $editForm->createView(),
]);
}
#[Route(path: '/logout', name: 'logout')]
public function logout() {}
// route is handled by the Security system
}