AdminAuthenticator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 1
nc 1
nop 4
1
<?php
2
3
namespace App\Security;
4
5
use App\Repository\UserRepositoryInterface;
6
use Symfony\Component\HttpFoundation\RedirectResponse;
7
use Symfony\Component\HttpFoundation\Request;
8
use Symfony\Component\HttpFoundation\Response;
9
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
10
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
11
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
12
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
13
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
14
use Symfony\Component\Security\Core\Security;
15
use Symfony\Component\Security\Core\User\UserInterface;
16
use Symfony\Component\Security\Core\User\UserProviderInterface;
17
use Symfony\Component\Security\Csrf\CsrfToken;
18
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
19
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
20
use Symfony\Component\Security\Http\Util\TargetPathTrait;
21
22
class AdminAuthenticator extends AbstractFormLoginAuthenticator
23
{
24
    use TargetPathTrait;
25
26
    private $userRepository;
27
    private $urlGenerator;
28
    private $csrfTokenManager;
29
    private $passwordEncoder;
30
31
    public function __construct(UserRepositoryInterface $userRepository, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
32
    {
33
        $this->userRepository = $userRepository;
34
        $this->urlGenerator = $urlGenerator;
35
        $this->csrfTokenManager = $csrfTokenManager;
36
        $this->passwordEncoder = $passwordEncoder;
37
    }
38
39
    public function supports(Request $request): bool
40
    {
41
        return 'sonata_admin_dashboard' === $request->attributes->get('_route')
42
            && $request->isMethod('POST');
43
    }
44
45
    public function getCredentials(Request $request): array
46
    {
47
        $credentials = [
48
            'email' => $request->request->get('email'),
49
            'password' => $request->request->get('password'),
50
            'csrf_token' => $request->request->get('_csrf_token'),
51
        ];
52
53
        if (null !== ($session = $request->getSession())) {
54
            $session->set(
55
                Security::LAST_USERNAME,
56
                $credentials['email']
57
            );
58
        }
59
60
        return $credentials;
61
    }
62
63
    public function getUser($credentials, UserProviderInterface $userProvider): UserInterface
64
    {
65
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
66
        if (!$this->csrfTokenManager->isTokenValid($token)) {
67
            throw new InvalidCsrfTokenException('Invalid CSRF token.');
68
        }
69
70
        $user = $this->userRepository->getOneByEmail($credentials['email']);
71
        if (!$user) {
72
            // fail authentication with a custom error
73
            throw new CustomUserMessageAuthenticationException('Email could not be found.');
74
        }
75
76
        return $user;
77
    }
78
79
    public function checkCredentials($credentials, UserInterface $user): bool
80
    {
81
        return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
82
    }
83
84
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey): Response
85
    {
86
        $session = $request->getSession();
87
        if (null !== $session && $targetPath = $this->getTargetPath($session, $providerKey)) {
88
            return new RedirectResponse($targetPath);
89
        }
90
91
        return new RedirectResponse($this->urlGenerator->generate('sonata_admin_dashboard'));
92
    }
93
94
    protected function getLoginUrl(): string
95
    {
96
        return $this->urlGenerator->generate('admin_login');
97
    }
98
}
99