Completed
Pull Request — master (#5)
by Nicolas
08:10
created

AbstractSecurityController   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 11
dl 0
loc 213
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A loginAction() 0 12 1
B forgotPasswordAction() 0 37 4
C resetPasswordAction() 0 58 11
A profileAction() 0 23 3
A getAuthenticationUtils() 0 4 1
A translate() 0 4 1
A getTokenManager() 0 4 1
A getMessenger() 0 4 1
A updateUser() 0 13 2
1
<?php
2
3
namespace Smart\AuthenticationBundle\Controller;
4
5
use Smart\AuthenticationBundle\Security\Form\Type\ResetPasswordType;
6
use Smart\AuthenticationBundle\Security\Form\Type\UserProfileType;
7
use Smart\AuthenticationBundle\Form\Type\Security\ForgotPasswordType;
8
use Smart\AuthenticationBundle\Security\Token;
9
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\Security\Core\User\UserInterface;
13
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
14
use Yokai\MessengerBundle\Sender\SenderInterface;
15
use Yokai\SecurityTokenBundle\Exception\TokenNotFoundException;
16
use Yokai\SecurityTokenBundle\Exception\TokenConsumedException;
17
use Yokai\SecurityTokenBundle\Exception\TokenExpiredException;
18
use Yokai\SecurityTokenBundle\Manager\TokenManagerInterface;
19
20
/**
21
 * @author Nicolas Bastien <[email protected]>
22
 */
23
class AbstractSecurityController extends Controller
24
{
25
    /**
26
     * Define application context, override this in your controller
27
     * @var string
28
     */
29
    protected $context;
30
        
31
    /**
32
     * @return Response
33
     */
34
    public function loginAction()
35
    {
36
        $helper = $this->getAuthenticationUtils();
37
38
        return $this->render($this->context . '/security/login.html.twig', [
39
            'last_username' => $helper->getLastUsername(),
40
            'error'         => $helper->getLastAuthenticationError(),
41
            'layout_template' => $this->context . '/empty_layout.html.twig',
42
            'security_login_check_url' => $this->generateUrl($this->context . '_security_login_check'),
43
            'security_forgot_password_url' => $this->generateUrl($this->context . '_security_forgot_password'),
44
        ]);
45
    }
46
47
    /**
48
     * @param Request $request
49
     *
50
     * @return Response
51
     */
52
    public function forgotPasswordAction(Request $request)
53
    {
54
        $form =  $this->createForm(ForgotPasswordType::class);
55
        $form->handleRequest($request);
56
57
        if (!$form->isSubmitted() || !$form->isValid()) {
58
            return $this->render(
59
                $this->context . '/security/forgot_password.html.twig',
60
                [
61
                    'form' => $form->createView(),
62
                    'security_login_form_url' => $this->generateUrl($this->context . '_security_login_form'),
63
                    'security_forgot_password_url' => $this->generateUrl($this->context . '_security_forgot_password'),
64
                ]
65
            );
66
        }
67
68
        $user = $this->get($this->context . '_user_provider')->loadUserByUsername($form->get('email')->getData());
69
70
        $this->addFlash('success', 'flash.forgot_password.success');
71
72
        if ($user) {
73
            $token = $this->getTokenManager()->create(Token::RESET_PASSWORD, $user);
74
75
            $this->getMessenger()->send(
76
                'security.forgot_password',
77
                $user,
78
                [
79
                    '{context}' => $this->context,
80
                    'token' => $token->getValue(),
81
                    'domain' => $this->container->getParameter('domain'),
82
                    'security_reset_password_route' => $this->context . '_security_reset_password'
83
                ]
84
            );
85
        }
86
87
        return $this->redirectToRoute($this->context . '_security_login_form');
88
    }
89
90
    /**
91
     * @param Request $request
92
     *
93
     * @return Response
94
     */
95
    public function resetPasswordAction(Request $request)
96
    {
97
        if ($this->getUser()) {
98
            return $this->redirectToRoute($this->context . '_dashboard');
99
        }
100
101
        if (!$request->query->has('token')) {
102
            $this->addFlash('error', 'flash.security.invalid_token');
103
104
            return $this->redirectToRoute($this->context . '_security_login_form');
105
        }
106
107
        try {
108
            $token = $this->getTokenManager()->get(Token::RESET_PASSWORD, $request->query->get('token'));
109
        } catch (TokenNotFoundException $e) {
110
            $this->addFlash('error', 'flash.security.token_not_found');
111
            return $this->redirectToRoute($this->context . '_security_login_form');
112
        } catch (TokenExpiredException $e) {
113
            $this->addFlash('error', 'flash.security.token_expired');
114
            return $this->redirectToRoute($this->context . '_security_login_form');
115
        } catch (TokenConsumedException $e) {
116
            $this->addFlash('error', 'flash.security.token_used');
117
            return $this->redirectToRoute($this->context . '_security_login_form');
118
        }
119
120
        if (!$token) {
121
            return $this->redirectToRoute($this->context . '_security_login_form');
122
        }
123
124
        /** @var UserInterface $user */
125
        $user = $this->getTokenManager()->getUser($token);
126
127
        $form =  $this->createForm(ResetPasswordType::class, $user);
128
        $form->handleRequest($request);
129
130
        if (!$form->isSubmitted() || !$form->isValid()) {
131
            return $this->render(
132
                $this->context . '/security/reset_password.html.twig',
133
                [
134
                    'token' => $token->getValue(),
135
                    'form' => $form->createView(),
136
                    'security_reset_password_route' => $this->context . '_security_reset_password'
137
                ]
138
            );
139
        }
140
141
        try {
142
            if (null !== $user->getPlainPassword()) {
0 ignored issues
show
Bug introduced by
The method getPlainPassword() does not seem to exist on object<Symfony\Component...ore\User\UserInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
143
                $this->updateUser($user);
144
                $this->getTokenManager()->consume($token);
145
            }
146
            $this->addFlash('success', 'flash.reset_password.success');
147
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class Smart\AuthenticationBundle\Controller\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
148
            $this->addFlash('error', 'flash.reset_password.error');
149
        }
150
151
        return $this->redirectToRoute($this->context . '_security_login_form');
152
    }
153
154
    /**
155
     * @param Request $request
156
     *
157
     * @return Response
158
     */
159
    public function profileAction(Request $request)
160
    {
161
        $user = $this->getUser();
162
163
        $form = $this->createForm(UserProfileType::class, $user, []);
164
165
        $form->handleRequest($request);
166
167
        if (!$form->isSubmitted() || !$form->isValid()) {
168
            return $this->render($this->context . '/security/profile.html.twig', [
169
                'base_template' => $this->get('sonata.admin.pool')->getTemplate('layout'),
170
                'admin_pool'    => $this->get('sonata.admin.pool'),
171
                'form'          => $form->createView(),
172
                'security_profile_url' => $this->generateUrl('admin_security_profile'),
173
            ]);
174
        }
175
176
        $this->updateUser($user);
0 ignored issues
show
Documentation introduced by
$user is of type null|object, but the function expects a object<Symfony\Component...ore\User\UserInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
177
178
        $this->addFlash('success', $this->translate('profile_edit.processed', [], 'security'));
179
180
        return $this->redirectToRoute('sonata_admin_dashboard');
181
    }
182
183
    /**
184
     * @return AuthenticationUtils
185
     */
186
    private function getAuthenticationUtils()
187
    {
188
        return $this->get('security.authentication_utils');
189
    }
190
191
    /**
192
     * @param string      $id         The message id (may also be an object that can be cast to string)
193
     * @param array       $parameters An array of parameters for the message
194
     * @param string|null $domain     The domain for the message or null to use the default
195
     *
196
     * @return string
197
     */
198
    protected function translate($id, array $parameters = array(), $domain = null)
199
    {
200
        return $this->get('translator')->trans($id, $parameters, $domain);
201
    }
202
203
    /**
204
     * @return TokenManagerInterface
205
     */
206
    private function getTokenManager()
207
    {
208
        return $this->get('yokai_security_token.token_manager');
209
    }
210
211
    /**
212
     * @return SenderInterface
213
     */
214
    protected function getMessenger()
215
    {
216
        return $this->get('yokai_messenger.sender');
217
    }
218
219
    /**
220
     * @param UserInterface $user
221
     */
222
    protected function updateUser(UserInterface $user)
223
    {
224
        if (null !== $user->getPlainPassword()) {
0 ignored issues
show
Bug introduced by
The method getPlainPassword() does not seem to exist on object<Symfony\Component...ore\User\UserInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
225
            $encoder = $this->get('security.password_encoder');
226
            $user->setPassword(
0 ignored issues
show
Bug introduced by
The method setPassword() does not seem to exist on object<Symfony\Component...ore\User\UserInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
227
                $encoder->encodePassword($user, $user->getPlainPassword())
0 ignored issues
show
Bug introduced by
The method getPlainPassword() does not seem to exist on object<Symfony\Component...ore\User\UserInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
228
            );
229
        }
230
231
        $manager = $this->getDoctrine()->getManager();
232
        $manager->persist($user);
233
        $manager->flush();
234
    }
235
}
236