<?php
namespace App\Controller;
use App\EventSubscriber\WebmasterReferenceRequestSubscriber;
use App\Form\ForgotPassword;
use App\Form\Security\RegistrationForm;
use App\Form\SecurityLogin;
use App\Security\ApiUser;
use App\Security\LoginFormAuthenticator;
use App\Service\AuthenticationHelper;
use App\Service\Client\SecurityService;
use App\Service\Client\User\AccountService;
use App\Service\Client\Webmaster\WebmasterAdService;
use App\Service\ReCaptchaService;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
protected SecurityService $service;
protected AuthenticationHelper $authenticationHelper;
public function __construct(SecurityService $service, AuthenticationHelper $authHelper)
{
$this->service = $service;
$this->authenticationHelper = $authHelper;
}
/**
* @Route("/security/logout")
* @return void
*/
public function logout(): void
{
}
/**
* @Route("/login", name="login")
* @Template
*
* @param AuthenticationUtils $authenticationUtils
* @param Request $request
* @param LoginFormAuthenticator $authenticator
* @param GuardAuthenticatorHandler $guardHandler
*
* @return array|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function login(AuthenticationUtils $authenticationUtils)
{
$form = $this->createForm(SecurityLogin::class, null, [
'action' => $this->generateUrl('login'),
]);
$user = $this->getUser();
if ($user instanceof ApiUser && $user->getApiToken()) {
return $this->redirectToRoute('app_home_index');
}
return [
'error' => $authenticationUtils->getLastAuthenticationError(),
'form' => $form->createView(),
];
}
/**
* @Route("/account/registerembed", methods={"GET|POST"})
* @Template()
* @param WebmasterAdService $webmasterAdService
* @param AccountService $service
* @param Request $request
* @return array
* @throws \Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
public function registerembed(WebmasterAdService $webmasterAdService, AccountService $service, Request $request): array
{
$success = false;
$error = false;
$form = $this->createForm(RegistrationForm::class);
$form->handleRequest($request);
$session = $request->getSession();
$wmRef = $session->get(WebmasterReferenceRequestSubscriber::SESSION_KEY);
if ($request->isMethod('POST')) {
$data = $form->getData();
try {
$specs = [
'email' => $data['email'] ?? ''
];
if($session->has(WebmasterReferenceRequestSubscriber::SESSION_KEY)) {
$specs['advertised_by_webmaster'] = $wmRef['webmaster_id'] ?? 0;
$specs['advertised_by_tracking_id'] = $wmRef['tracking_id'] ?? '';
$specs['advertised_by_campaign_id'] = $wmRef['campaign_id'] ?? 0;
}
if ($service->createRegistration($specs)) {
$session->set('registrationEmail', $specs['email']);
$session->save();
$success = true;
} else {
$error = true;
$success = false;
}
} catch (\DomainException $e) {
$error = true;
$success = false;
}
}
$ad = $webmasterAdService->getPublicAdInfo($request->query->getInt('ad'));
return [
'form' => $form->createView(),
'wmRef' => $wmRef ?? ['webmaster_id' => $request->query->get('wmid')],
'error' => $error,
'success' => $success,
'ad' => $ad ?? ['theme' => 1]
];
}
/**
* @Template()
* @return array
*/
public function widget(): array
{
$form = $this->createForm(SecurityLogin::class, null, [
'action' => $this->generateUrl('login'),
'attr' => [
'class' => 'input-group'
]
]);
return [
'form' => $form->createView(),
];
}
/**
* @Route("/security/passwort-vergessen", methods={"GET", "POST"})
* @Template
* @param Request $request
* @return array
*/
public function forgotpassword(Request $request): array
{
$form = $this->createForm(ForgotPassword::class, null, [
'attr' => [
'class' => 'input-group'
]
]);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isValid()) {
if ($this->service->requestNewPassword($form->getData()['username'])) {
$this->addFlash('success', 'Wir haben Dir eine E-Mail geschickt.');
}
}
}
return [
'form' => $form->createView(),
];
}
/**
* @Route("/security/passwort-vergessen/confirm/{confirmationToken}", methods={"GET"}, requirements={"confirmationToken": "[a-f0-9]{40}"})
* @Template
* @param Request $request
* @return array
*/
public function forgotpasswordCofirm(string $confirmationToken): RedirectResponse
{
if ($this->service->confirmNewPasswordRequest($confirmationToken)) {
$this->addFlash('success', 'Du erhälst in Kürze eine weitere E-Mail mit Deinem neuen Passwort.');
} else {
$this->addFlash('error', 'Bitte versuche es erneut oder kontaktiere den Support.');
}
return $this->redirectToRoute('login');
}
/**
* @Route("/registration", methods={"GET|POST"})
* @Template()
* @return array|RedirectResponse
*/
public function registration(AccountService $service, Request $request, ReCaptchaService $recaptchaService)
{
if ($this->getUser() instanceof ApiUser) {
$this->addFlash('info', 'Bitte logge dich aus, bevor du eine Registrierung startest.');
return $this->redirect('/');
}
$form = $this->createForm(RegistrationForm::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if (!$recaptchaService->isValidSubmission($request)) {
$this->addFlash('info', 'Bitte lösen Sie das reCaptcha.');
return $this->redirectToRoute('app_security_registration');
}
$data = $form->getData();
try {
$specs = [
'email' => $data['email'],
"remote_ip" => $request->headers->get('X-Real-IP', $_SERVER["REMOTE_ADDR"]),
];
$session = $request->getSession();
if($session->has(WebmasterReferenceRequestSubscriber::SESSION_KEY)) {
$wmRef = $session->get(WebmasterReferenceRequestSubscriber::SESSION_KEY);
$specs['advertised_by_webmaster'] = $wmRef['webmaster_id'] ?? 0;
$specs['advertised_by_tracking_id'] = $wmRef['tracking_id'] ?? '';
$specs['advertised_by_campaign_id'] = $wmRef['campaign_id'] ?? 0;
}
if ($service->createRegistration($specs)) {
$session->set('registrationEmail', $specs['email']);
$session->save();
$this->addFlash('success', 'Wir haben dir eine E-Mail geschickt.');
return $this->redirectToRoute('app_security_registrationconfirm');
}
$this->addFlash('info', 'Bitte nochmal probieren oder Support kontaktieren.');
} catch (\DomainException $e) {
$this->addFlash('error', $e->getMessage());
}
return $this->redirectToRoute('app_security_registration');
}
return [
'form' => $form->createView(),
];
}
/**
* @Route("/registration/confirm/{confirmationToken}", methods={"GET"})
* @Template()
* @return array|RedirectResponse
*/
public function registrationConfirm(Request $request, string $confirmationToken = '')
{
if ($this->getUser() instanceof ApiUser) {
$this->addFlash('info', 'Bitte logge dich aus, bevor du eine Registrierung bestätigst.');
return $this->redirect('/');
}
$email = $request->getSession()->get('registrationEmail');
if (!$email) {
// restart registrationprocess
return $this->redirectToRoute('app_security_registration');
}
return [
'email' => $email,
];
}
/**
* All calls to this method should be intercepted by PinConfirmAuthenticator
*
* @Route("/registration/confirm/pin", methods={"POST"})
* @return RedirectResponse
*/
public function confirmPin(): RedirectResponse
{
if ($this->getUser() instanceof ApiUser) {
$this->addFlash('info', 'Bitte logge dich aus, bevor Du eine Registrierung bestätigst.');
}
return new RedirectResponse('/');
}
}