FormAuthenticator::checkCredentials()   C
last analyzed

Complexity

Conditions 8
Paths 9

Size

Total Lines 38
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 38
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 18
nc 9
nop 2
1
<?php
2
/*
3
  ÁTICA - Aplicación web para la gestión documental de centros educativos
4
5
  Copyright (C) 2015-2017: Luis Ramón López López
6
7
  This program is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU Affero General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
11
12
  This program is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
  GNU Affero General Public License for more details.
16
17
  You should have received a copy of the GNU Affero General Public License
18
  along with this program.  If not, see [http://www.gnu.org/licenses/].
19
*/
20
21
namespace AppBundle\Security;
22
23
use AppBundle\Entity\User;
24
use AppBundle\Service\SenecaAuthenticatorService;
25
use Doctrine\Common\Persistence\ManagerRegistry;
26
use Symfony\Component\HttpFoundation\RedirectResponse;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\Routing\RouterInterface;
29
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
30
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
31
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
32
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
33
use Symfony\Component\Security\Core\Security;
34
use Symfony\Component\Security\Core\User\UserInterface;
35
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
36
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
37
use Symfony\Component\Security\Core\Exception\AuthenticationException;
38
use Symfony\Component\Security\Core\User\UserProviderInterface;
39
40
class FormAuthenticator extends AbstractGuardAuthenticator
41
{
42
    /**
43
     * @var UserPasswordEncoderInterface
44
     */
45
    private $encoder;
46
47
    /**
48
     * @var RouterInterface
49
     */
50
    private $router;
51
52
    /**
53
     * @var SenecaAuthenticatorService
54
     */
55
    private $senecaAuthenticator;
56
57
    /**
58
     * @var ManagerRegistry
59
     */
60
    private $managerRegistry;
61
62
    /**
63
     * Constructor
64
     */
65
    public function __construct(RouterInterface $router, UserPasswordEncoderInterface $encoder, SenecaAuthenticatorService $senecaAuthenticator, ManagerRegistry $managerRegistry)
66
    {
67
        $this->router = $router;
68
        $this->encoder = $encoder;
69
        $this->senecaAuthenticator = $senecaAuthenticator;
70
        $this->managerRegistry = $managerRegistry;
71
    }
72
73
    public function supports(Request $request)
74
    {
75
        $session = $request->getSession();
76
77
        if ($request->attributes->get('_route') !== 'login_check' || !$request->isMethod('POST') || !$session) {
78
            return false;
79
        }
80
81
        return true;
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87
    public function getCredentials(Request $request)
88
    {
89
        $username = $request->request->get('_username');
90
        $session = $request->getSession();
91
92
        $session->set(Security::LAST_USERNAME, $username);
93
94
        return array(
95
            'username' => $username,
96
            'password' => $request->request->get('_password'),
97
        );
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function getUser($credentials, UserProviderInterface $userProvider)
104
    {
105
        try {
106
            return $userProvider->loadUserByUsername($credentials['username']);
107
        } catch (UsernameNotFoundException $e) {
108
            throw new BadCredentialsException();
109
        }
110
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115
    public function checkCredentials($credentials, UserInterface $user)
116
    {
117
        if (!$user instanceof User) {
118
            throw new AuthenticationServiceException();
119
        }
120
121
        $plainPassword = $credentials['password'];
122
123
        // ¿Comprobación de contraseña desde Séneca?
124
        if ($user->getExternalCheck()) {
125
            $result = $this->senecaAuthenticator->checkUserCredentials($user->getLoginUsername(), $plainPassword);
126
127
            if (true === $result) {
128
                // contraseña correcta, actualizar en local por si perdemos la conectividad
129
                if (false === $this->encoder->isPasswordValid($user, $plainPassword)) {
130
                    $user->setPassword($this->encoder->encodePassword($user, $plainPassword));
131
                    $em = $this->managerRegistry->getManagerForClass(User::class);
132
                    if ($em) {
133
                        $em->flush();
134
                    }
135
                }
136
                return true;
137
            }
138
139
            if (false === $result) {
140
                return false;
141
            }
142
143
            // si no es ni "true" ni "false" es que no se ha podido contactar con Séneca, intentar en local
144
        }
145
146
        // comprobación local
147
        if (false === $this->encoder->isPasswordValid($user, $plainPassword)) {
148
            throw new BadCredentialsException();
149
        }
150
151
        return true;
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
158
    {
159
        $targetPath = $request->getSession()->get('_security.'.$providerKey.'.target_path');
160
        if (!$targetPath) {
161
            $targetPath = $this->router->generate('frontpage');
162
        }
163
        return new RedirectResponse($targetPath);
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
170
    {
171
        $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
172
        $url = $this->router->generate('login');
173
        return new RedirectResponse($url);
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179
    public function start(Request $request, AuthenticationException $authException = null)
180
    {
181
        $url = $this->router->generate('login');
182
        return new RedirectResponse($url);
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188
    public function supportsRememberMe()
189
    {
190
        return false;
191
    }
192
}
193