Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace hardcoded forms with symfony forms #382

Merged
merged 1 commit into from
Sep 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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