Completed
Push — master ( 8b8003...277c4a )
by
unknown
10s
created

AbstractSecurityController::updateUser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 2
nop 1
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\SmartUserInterface;
9
use Smart\AuthenticationBundle\Security\Token;
10
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
11
use Symfony\Component\HttpFoundation\Request;
12
use Symfony\Component\HttpFoundation\Response;
13
use Symfony\Component\Security\Core\User\UserInterface;
14
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
15
use Yokai\MessengerBundle\Sender\SenderInterface;
16
use Yokai\SecurityTokenBundle\Exception\TokenNotFoundException;
17
use Yokai\SecurityTokenBundle\Exception\TokenConsumedException;
18
use Yokai\SecurityTokenBundle\Exception\TokenExpiredException;
19
use Yokai\SecurityTokenBundle\Manager\TokenManagerInterface;
20
21
/**
22
 * @author Nicolas Bastien <[email protected]>
23
 */
24
class AbstractSecurityController extends Controller
25
{
26
    /**
27
     * Define application context, override this in your controller
28
     * @var string
29
     */
30
    protected $context;
31
        
32
    /**
33
     * @return Response
34
     */
35
    public function loginAction()
36
    {
37
        $helper = $this->getAuthenticationUtils();
38
39
        return $this->render($this->context . '/security/login.html.twig', [
40
            'last_username' => $helper->getLastUsername(),
41
            'error'         => $helper->getLastAuthenticationError(),
42
            'layout_template' => $this->context . '/empty_layout.html.twig',
43
            'security_login_check_url' => $this->generateUrl($this->context . '_security_login_check'),
44
            'security_forgot_password_url' => $this->generateUrl($this->context . '_security_forgot_password'),
45
        ]);
46
    }
47
48
    /**
49
     * @param Request $request
50
     *
51
     * @return Response
52
     */
53
    public function forgotPasswordAction(Request $request)
54
    {
55
        $form =  $this->createForm(ForgotPasswordType::class);
56
        $form->handleRequest($request);
57
58
        if (!$form->isSubmitted() || !$form->isValid()) {
59
            return $this->render(
60
                $this->context . '/security/forgot_password.html.twig',
61
                [
62
                    'form' => $form->createView(),
63
                    'security_login_form_url' => $this->generateUrl($this->context . '_security_login_form'),
64
                    'security_forgot_password_url' => $this->generateUrl($this->context . '_security_forgot_password'),
65
                ]
66
            );
67
        }
68
69
        $user = $this->get($this->context . '_user_provider')->loadUserByUsername($form->get('email')->getData());
70
71
        $this->addFlash('success', 'flash.forgot_password.success');
72
73
        if ($user) {
74
            $token = $this->getTokenManager()->create(Token::RESET_PASSWORD, $user);
75
76
            $this->getMessenger()->send(
77
                'security.forgot_password',
78
                $user,
79
                [
80
                    '{context}' => $this->context,
81
                    'token' => $token->getValue(),
82
                    'domain' => $this->container->getParameter('domain'),
83
                    'security_reset_password_route' => $this->context . '_security_reset_password'
84
                ]
85
            );
86
        }
87
88
        return $this->redirectToRoute($this->context . '_security_login_form');
89
    }
90
91
    /**
92
     * @param Request $request
93
     *
94
     * @return Response
95
     */
96
    public function resetPasswordAction(Request $request)
97
    {
98
        if ($this->getUser()) {
99
            return $this->redirectToRoute($this->context . '_dashboard');
100
        }
101
102
        if (!$request->query->has('token')) {
103
            $this->addFlash('error', 'flash.security.invalid_token');
104
105
            return $this->redirectToRoute($this->context . '_security_login_form');
106
        }
107
108
        try {
109
            $token = $this->getTokenManager()->get(Token::RESET_PASSWORD, $request->query->get('token'));
110
        } catch (TokenNotFoundException $e) {
111
            $this->addFlash('error', 'flash.security.token_not_found');
112
            return $this->redirectToRoute($this->context . '_security_login_form');
113
        } catch (TokenExpiredException $e) {
114
            $this->addFlash('error', 'flash.security.token_expired');
115
            return $this->redirectToRoute($this->context . '_security_login_form');
116
        } catch (TokenConsumedException $e) {
117
            $this->addFlash('error', 'flash.security.token_used');
118
            return $this->redirectToRoute($this->context . '_security_login_form');
119
        }
120
121
        /** @var SmartUserInterface $user */
122
        $user = $this->getTokenManager()->getUser($token);
123
124
        $form =  $this->createForm(ResetPasswordType::class, $user);
125
        $form->handleRequest($request);
126
127
        if (!$form->isSubmitted() || !$form->isValid()) {
128
            return $this->render(
129
                $this->context . '/security/reset_password.html.twig',
130
                [
131
                    'token' => $token->getValue(),
132
                    'form' => $form->createView(),
133
                    'security_reset_password_route' => $this->context . '_security_reset_password'
134
                ]
135
            );
136
        }
137
138
        try {
139
            if (null !== $user->getPlainPassword()) {
140
                $this->updateUser($user);
141
                $this->getTokenManager()->consume($token);
142
            }
143
            $this->addFlash('success', 'flash.reset_password.success');
144
        } catch (\Exception $e) {
145
            $this->addFlash('error', 'flash.reset_password.error');
146
        }
147
148
        return $this->redirectToRoute($this->context . '_security_login_form');
149
    }
150
151
    /**
152
     * @param Request $request
153
     *
154
     * @return Response
155
     */
156
    public function profileAction(Request $request)
157
    {
158
        /** @var SmartUserInterface $user */
159
        $user = $this->getUser();
160
161
        $form = $this->createForm(UserProfileType::class, $user, []);
162
163
        $form->handleRequest($request);
164
165
        if (!$form->isSubmitted() || !$form->isValid()) {
166
            return $this->render($this->context . '/security/profile.html.twig', [
167
                'base_template' => $this->get('sonata.admin.pool')->getTemplate('layout'),
168
                'admin_pool'    => $this->get('sonata.admin.pool'),
169
                'form'          => $form->createView(),
170
                'security_profile_url' => $this->generateUrl('admin_security_profile'),
171
            ]);
172
        }
173
174
        $this->updateUser($user);
175
176
        $this->addFlash('success', $this->translate('profile_edit.processed', [], 'security'));
177
178
        return $this->redirectToRoute('sonata_admin_dashboard');
179
    }
180
181
    /**
182
     * @return AuthenticationUtils
183
     */
184
    private function getAuthenticationUtils()
185
    {
186
        return $this->get('security.authentication_utils');
187
    }
188
189
    /**
190
     * @param string      $id         The message id (may also be an object that can be cast to string)
191
     * @param array       $parameters An array of parameters for the message
192
     * @param string|null $domain     The domain for the message or null to use the default
193
     *
194
     * @return string
195
     */
196
    protected function translate($id, array $parameters = array(), $domain = null)
197
    {
198
        return $this->get('translator')->trans($id, $parameters, $domain);
199
    }
200
201
    /**
202
     * @return TokenManagerInterface
203
     */
204
    private function getTokenManager()
205
    {
206
        return $this->get('yokai_security_token.token_manager');
207
    }
208
209
    /**
210
     * @return SenderInterface
211
     */
212
    protected function getMessenger()
213
    {
214
        return $this->get('yokai_messenger.sender');
215
    }
216
217
    /**
218
     * @param SmartUserInterface $user
219
     */
220
    protected function updateUser(SmartUserInterface $user)
221
    {
222
        if (null !== $user->getPlainPassword()) {
223
            $encoder = $this->get('security.password_encoder');
224
            $user->setPassword(
225
                $encoder->encodePassword($user, $user->getPlainPassword())
226
            );
227
        }
228
229
        $manager = $this->getDoctrine()->getManager();
230
        $manager->persist($user);
231
        $manager->flush();
232
    }
233
}
234