Skip to content

Commit

Permalink
Replace hardcoded forms with symfony forms
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Sep 11, 2021
1 parent ece961c commit a97cc2c
Show file tree
Hide file tree
Showing 12 changed files with 241 additions and 162 deletions.
63 changes: 45 additions & 18 deletions src/Action/LoginAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@
namespace Nucleos\UserAdminBundle\Action;

use Nucleos\UserBundle\Event\GetResponseLoginEvent;
use Nucleos\UserBundle\Form\Type\LoginFormType;
use Nucleos\UserBundle\Model\UserInterface;
use Nucleos\UserBundle\NucleosUserEvents;
use Sonata\AdminBundle\Admin\Pool;
use Sonata\AdminBundle\Templating\TemplateRegistryInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
Expand All @@ -37,7 +41,7 @@ final class LoginAction

private EventDispatcherInterface $eventDispatcher;

private UrlGeneratorInterface $urlGenerator;
private RouterInterface $router;

private AuthorizationCheckerInterface $authorizationChecker;

Expand All @@ -47,28 +51,28 @@ final class LoginAction

private TokenStorageInterface $tokenStorage;

private Session $session;

private ?CsrfTokenManagerInterface $csrfTokenManager = null;

private FormFactoryInterface $formFactory;

public function __construct(
Environment $twig,
EventDispatcherInterface $eventDispatcher,
UrlGeneratorInterface $urlGenerator,
RouterInterface $router,
AuthorizationCheckerInterface $authorizationChecker,
Pool $adminPool,
TemplateRegistryInterface $templateRegistry,
TokenStorageInterface $tokenStorage,
Session $session
FormFactoryInterface $formFactory
) {
$this->twig = $twig;
$this->eventDispatcher = $eventDispatcher;
$this->urlGenerator = $urlGenerator;
$this->router = $router;
$this->authorizationChecker = $authorizationChecker;
$this->adminPool = $adminPool;
$this->templateRegistry = $templateRegistry;
$this->tokenStorage = $tokenStorage;
$this->session = $session;
$this->formFactory = $formFactory;
}

/**
Expand All @@ -77,10 +81,12 @@ public function __construct(
*/
public function __invoke(Request $request): Response
{
$session = $request->hasSession() ? $request->getSession() : null;

if ($this->isAuthenticated()) {
$this->session->getFlashBag()->add('nucleos_user_admin_error', 'nucleos_user_admin_already_authenticated');
$this->addFlash($session, 'nucleos_user_admin_error', 'nucleos_user_admin_already_authenticated');

return new RedirectResponse($this->urlGenerator->generate('sonata_admin_dashboard'));
return new RedirectResponse($this->router->generate('sonata_admin_dashboard'));
}

$event = new GetResponseLoginEvent($request);
Expand All @@ -90,10 +96,7 @@ public function __invoke(Request $request): Response
return $event->getResponse();
}

$session = $request->hasSession() ? $request->getSession() : null;

$authErrorKey = Security::AUTHENTICATION_ERROR;
$lastUsernameKey = Security::LAST_USERNAME;
$authErrorKey = Security::AUTHENTICATION_ERROR;

// get the error if any (works with forward and redirect -- see below)
if ($request->attributes->has($authErrorKey)) {
Expand All @@ -111,21 +114,31 @@ public function __invoke(Request $request): Response

if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
$refererUri = $request->server->get('HTTP_REFERER', '');
$url = '' !== $refererUri && $refererUri !== $request->getUri() ? $refererUri : $this->urlGenerator->generate('sonata_admin_dashboard');
$url = '' !== $refererUri && $refererUri !== $request->getUri() ? $refererUri : $this->router->generate('sonata_admin_dashboard');

return new RedirectResponse($url);
}

$form = $this->formFactory
->create(LoginFormType::class, null, [
'action' => $this->router->generate('nucleos_user_admin_security_check'),
'method' => 'POST',
])
->add('save', SubmitType::class, [
'label' => 'security.login.submit',
])
;

// last username entered by the user
$lastUsername = (null === $session) ? '' : $session->get($lastUsernameKey);

return new Response($this->twig->render('@NucleosUserAdmin/Admin/Security/login.html.twig', [
'form' => $form->createView(),
'admin_pool' => $this->adminPool,
'base_template' => $this->templateRegistry->getTemplate('layout'),
'csrf_token' => $this->getCsrfToken(),
'error' => $error,
'last_username' => $lastUsername,
'reset_route' => $this->urlGenerator->generate('nucleos_user_admin_resetting_request'),
'last_username' => $this->getLastUsername($session),
'reset_route' => $this->router->generate('nucleos_user_admin_resetting_request'),
]));
}

Expand All @@ -134,6 +147,11 @@ public function setCsrfTokenManager(CsrfTokenManagerInterface $csrfTokenManager)
$this->csrfTokenManager = $csrfTokenManager;
}

private function getLastUsername(?SessionInterface $session): ?string
{
return (null === $session) ? '' : $session->get(Security::LAST_USERNAME);
}

private function isAuthenticated(): bool
{
$token = $this->tokenStorage->getToken();
Expand All @@ -151,4 +169,13 @@ private function getCsrfToken(): ?string
{
return null !== $this->csrfTokenManager ? $this->csrfTokenManager->getToken('authenticate')->getValue() : null;
}

private function addFlash(?SessionInterface $session, string $type, string $message): void
{
if (!$session instanceof Session) {
return;
}

$session->getFlashBag()->add($type, $message);
}
}
37 changes: 22 additions & 15 deletions src/Action/RequestAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,55 +13,62 @@

namespace Nucleos\UserAdminBundle\Action;

use Nucleos\UserBundle\Form\Type\RequestPasswordFormType;
use Sonata\AdminBundle\Admin\Pool;
use Sonata\AdminBundle\Templating\TemplateRegistryInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Twig\Environment;

final class RequestAction
{
private Environment $twig;

private UrlGeneratorInterface $urlGenerator;
private RouterInterface $router;

private AuthorizationCheckerInterface $authorizationChecker;

private Pool $adminPool;

private TemplateRegistryInterface $templateRegistry;

private FormFactoryInterface $formFactory;

public function __construct(
Environment $twig,
UrlGeneratorInterface $urlGenerator,
RouterInterface $router,
AuthorizationCheckerInterface $authorizationChecker,
Pool $adminPool,
TemplateRegistryInterface $templateRegistry
TemplateRegistryInterface $templateRegistry,
FormFactoryInterface $formFactory
) {
$this->twig = $twig;
$this->urlGenerator = $urlGenerator;
$this->router = $router;
$this->authorizationChecker = $authorizationChecker;
$this->adminPool = $adminPool;
$this->templateRegistry = $templateRegistry;
$this->formFactory = $formFactory;
}

public function __invoke(Request $request): Response
{
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
return new RedirectResponse($this->urlGenerator->generate('sonata_admin_dashboard'));
return new RedirectResponse($this->router->generate('sonata_admin_dashboard'));
}

return new Response(
$this->twig->render(
'@NucleosUserAdmin/Admin/Security/Resetting/request.html.twig',
[
'base_template' => $this->templateRegistry->getTemplate('layout'),
'admin_pool' => $this->adminPool,
]
)
);
$form = $this->formFactory->create(RequestPasswordFormType::class, null, [
'action' => $this->router->generate('nucleos_user_admin_resetting_send_email'),
'method' => 'POST',
]);

return new Response($this->twig->render('@NucleosUserAdmin/Admin/Security/Resetting/request.html.twig', [
'form' => $form->createView(),
'base_template' => $this->templateRegistry->getTemplate('layout'),
'admin_pool' => $this->adminPool,
]));
}
}
34 changes: 16 additions & 18 deletions src/Action/ResetAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccountStatusException;
use Symfony\Contracts\Translation\TranslatorInterface;
Expand All @@ -41,7 +41,7 @@ final class ResetAction

private Environment $twig;

private UrlGeneratorInterface $urlGenerator;
private RouterInterface $router;

private AuthorizationCheckerInterface $authorizationChecker;

Expand All @@ -68,7 +68,7 @@ final class ResetAction
*/
public function __construct(
Environment $twig,
UrlGeneratorInterface $urlGenerator,
RouterInterface $router,
AuthorizationCheckerInterface $authorizationChecker,
Pool $adminPool,
TemplateRegistryInterface $templateRegistry,
Expand All @@ -81,7 +81,7 @@ public function __construct(
string $firewallName
) {
$this->twig = $twig;
$this->urlGenerator = $urlGenerator;
$this->router = $router;
$this->authorizationChecker = $authorizationChecker;
$this->adminPool = $adminPool;
$this->templateRegistry = $templateRegistry;
Expand All @@ -101,7 +101,7 @@ public function __construct(
public function __invoke(Request $request, string $token): Response
{
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
return new RedirectResponse($this->urlGenerator->generate('sonata_admin_dashboard'));
return new RedirectResponse($this->router->generate('sonata_admin_dashboard'));
}

$user = $this->userManager->findUserByConfirmationToken($token);
Expand All @@ -113,10 +113,13 @@ public function __invoke(Request $request, string $token): Response
}

if (!$user->isPasswordRequestNonExpired($this->resetTtl)) {
return new RedirectResponse($this->urlGenerator->generate('nucleos_user_admin_resetting_request'));
return new RedirectResponse($this->router->generate('nucleos_user_admin_resetting_request'));
}

$form = $this->formFactory->create(ResettingFormType::class, new Resetting($user), [
'action' => $this->router->generate('nucleos_user_admin_security_check', [
'token' => $token,
]),
'validation_groups' => ['ResetPassword', 'Default'],
]);

Expand All @@ -128,24 +131,19 @@ public function __invoke(Request $request, string $token): Response
$this->translator->trans('resetting.flash.success', [], 'NucleosUserBundle')
);

$response = new RedirectResponse($this->urlGenerator->generate('sonata_admin_dashboard'));
$response = new RedirectResponse($this->router->generate('sonata_admin_dashboard'));

$this->resetUser($user, $response);

return $response;
}

return new Response(
$this->twig->render(
'@NucleosUserAdmin/Admin/Security/Resetting/reset.html.twig',
[
'token' => $token,
'form' => $form->createView(),
'base_template' => $this->templateRegistry->getTemplate('layout'),
'admin_pool' => $this->adminPool,
]
)
);
return new Response($this->twig->render('@NucleosUserAdmin/Admin/Security/Resetting/reset.html.twig', [
'token' => $token,
'form' => $form->createView(),
'base_template' => $this->templateRegistry->getTemplate('layout'),
'admin_pool' => $this->adminPool,
]));
}

public function setLogger(LoggerInterface $logger): void
Expand Down
3 changes: 2 additions & 1 deletion src/Resources/config/action.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
ref('security.authorization_checker'),
ref('sonata.admin.pool'),
ref('sonata.admin.global_template_registry'),
ref('form.factory'),
])

->set(SendEmailAction::class)
Expand Down Expand Up @@ -82,7 +83,7 @@
ref('sonata.admin.pool'),
ref('sonata.admin.global_template_registry'),
ref('security.token_storage'),
ref('session'),
ref('form.factory'),
])
->call('setCsrfTokenManager', [
ref('security.csrf.token_manager')->ignoreOnInvalid(),
Expand Down
24 changes: 10 additions & 14 deletions src/Resources/views/Admin/Security/Resetting/request.html.twig
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
{% extends '@NucleosUserAdmin/Admin/Security/layout.html.twig' %}

{% form_theme form 'bootstrap_3_layout.html.twig' %}

{% block login_box_content %}
<p class="login-box-msg">
{{ 'resetting.request.submit'|trans({}, 'NucleosUserBundle') }}
</p>

<form action="{{ path('nucleos_user_admin_resetting_send_email') }}" method="post" role="form">
<div class="form-group has-feedback">
<input type="text" class="form-control" id="username" name="username" required="required"
placeholder="{{ 'resetting.request.username'|trans({}, 'NucleosUserBundle')|replace({':': ''}) }}"/>
<span class="glyphicon glyphicon-user form-control-feedback"></span>
</div>
{{ form_start(form) }}

{% set actions %}{{ form_widget(form.save, { attr: { class: 'btn btn-primary btn-block' } }) }}{% endset %}

{{ form_widget(form) }}

{{ actions }}

<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-primary btn-block btn-flat">
{{ 'resetting.request.submit'|trans({}, 'NucleosUserBundle') }}
</button>
</div>
</div>
</form>
{{ form_end(form) }}
{% endblock %}
10 changes: 8 additions & 2 deletions src/Resources/views/Admin/Security/Resetting/reset.html.twig
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
{% extends '@NucleosUserAdmin/Admin/Security/layout.html.twig' %}

{% form_theme form 'bootstrap_3_layout.html.twig' %}

{% block login_box_content %}
<p class="login-box-msg">
{{ 'resetting.reset.submit'|trans({}, 'NucleosUserBundle') }}
</p>

{{ form_start(form, { 'action': path('nucleos_user_admin_resetting_reset', {'token': token}) }) }}
{{ form_start(form) }}

{% set actions %}{{ form_widget(form.save, { attr: { class: 'btn btn-primary btn-block' } }) }}{% endset %}

{{ form_widget(form) }}

{{ actions }}

{{ form_end(form) }}
{% endblock sonata_wrapper %}
{% endblock login_box_content %}
Loading

0 comments on commit a97cc2c

Please sign in to comment.