Test Setup Failed
Push — master ( 2d41be...47a10e )
by Luis Ramón
15:21
created

FormAuthenticator   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 14

Importance

Changes 0
Metric Value
wmc 20
lcom 2
cbo 14
dl 0
loc 145
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getCredentials() 0 16 4
A getUser() 0 8 2
C checkCredentials() 0 38 8
A onAuthenticationSuccess() 0 8 2
A onAuthenticationFailure() 0 6 1
A start() 0 5 1
A supportsRememberMe() 0 4 1
1
<?php
2
/*
3
  GESTCONV - Aplicación web para la gestión de la convivencia en 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\Usuario;
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
        $this->router = $router;
67
        $this->encoder = $encoder;
68
        $this->senecaAuthenticator = $senecaAuthenticator;
69
        $this->managerRegistry = $managerRegistry;
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function getCredentials(Request $request)
76
    {
77
        $username = $request->request->get('_username');
78
        $session = $request->getSession();
79
80
        if ($request->attributes->get('_route') !== 'usuario_comprobar' || !$request->isMethod('POST') || !$session) {
81
            return null;
82
        }
83
84
        $session->set(Security::LAST_USERNAME, $username);
85
86
        return array(
87
            'username' => $username,
88
            'password' => $request->request->get('_password'),
89
        );
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function getUser($credentials, UserProviderInterface $userProvider)
96
    {
97
        try {
98
            return $userProvider->loadUserByUsername($credentials['username']);
99
        } catch (UsernameNotFoundException $e) {
100
            throw new BadCredentialsException();
101
        }
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function checkCredentials($credentials, UserInterface $user)
108
    {
109
        if (!$user instanceof Usuario) {
110
            throw new AuthenticationServiceException();
111
        }
112
113
        $plainPassword = $credentials['password'];
114
115
        // ¿Comprobación de contraseña desde Séneca?
116
        if ($user->getEsExterno()) {
117
            $result = $this->senecaAuthenticator->checkUserCredentials($user->getUsername(), $plainPassword);
118
119
            if (true === $result) {
120
                // contraseña correcta, actualizar en local por si perdemos la conectividad
121
                if (false === $this->encoder->isPasswordValid($user, $plainPassword)) {
122
                    $user->setPassword($this->encoder->encodePassword($user, $plainPassword));
123
                    $em = $this->managerRegistry->getManagerForClass('AppBundle\Entity\Usuario');
124
                    if ($em) {
125
                        $em->flush();
126
                    }
127
                }
128
                return true;
129
            }
130
131
            if (false === $result) {
132
                return false;
133
            }
134
135
            // si no es ni "true" ni "false" es que no se ha podido contactar con Séneca, intentar en local
136
        }
137
138
        // comprobación local
139
        if (false === $this->encoder->isPasswordValid($user, $plainPassword)) {
140
            throw new BadCredentialsException();
141
        }
142
143
        return true;
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
150
    {
151
        $targetPath = $request->getSession()->get('_security.'.$providerKey.'.target_path');
152
        if (!$targetPath) {
153
            $targetPath = $this->router->generate('portada');
154
        }
155
        return new RedirectResponse($targetPath);
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
162
    {
163
        $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
164
        $url = $this->router->generate('usuario_entrar');
165
        return new RedirectResponse($url);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function start(Request $request, AuthenticationException $authException = null)
172
    {
173
        $url = $this->router->generate('usuario_entrar');
174
        return new RedirectResponse($url);
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function supportsRememberMe()
181
    {
182
        return false;
183
    }
184
}
185