Completed
Push — master ( d67956...a656c9 )
by Piotr
11s
created

ActivationController::changePasswordAction()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 31
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 18
nc 3
nop 2
dl 0
loc 31
rs 8.5806
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * (c) FSi sp. z o.o. <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace FSi\Bundle\AdminSecurityBundle\Controller\Activation;
11
12
use FSi\Bundle\AdminBundle\Message\FlashMessages;
13
use FSi\Bundle\AdminSecurityBundle\Event\ActivationEvent;
14
use FSi\Bundle\AdminSecurityBundle\Event\AdminSecurityEvents;
15
use FSi\Bundle\AdminSecurityBundle\Event\ChangePasswordEvent;
16
use FSi\Bundle\AdminSecurityBundle\Security\User\ActivableInterface;
17
use FSi\Bundle\AdminSecurityBundle\Security\User\EnforceablePasswordChangeInterface;
18
use FSi\Bundle\AdminSecurityBundle\Security\User\UserRepositoryInterface;
19
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
20
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
21
use Symfony\Component\Form\FormFactoryInterface;
22
use Symfony\Component\HttpFoundation\RedirectResponse;
23
use Symfony\Component\HttpFoundation\Request;
24
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
25
use Symfony\Component\Routing\RouterInterface;
26
27
class ActivationController
28
{
29
    /**
30
     * @var EngineInterface
31
     */
32
    private $templating;
33
34
    /**
35
     * @var string
36
     */
37
    private $changePasswordActionTemplate;
38
39
    /**
40
     * @var UserRepositoryInterface
41
     */
42
    private $userRepository;
43
44
    /**
45
     * @var RouterInterface
46
     */
47
    private $router;
48
49
    /**
50
     * @var FormFactoryInterface
51
     */
52
    private $formFactory;
53
54
    /**
55
     * @var EventDispatcherInterface
56
     */
57
    private $eventDispatcher;
58
59
    /**
60
     * @var FlashMessages
61
     */
62
    private $flashMessages;
63
64
    /**
65
     * @var string
66
     */
67
    private $changePasswordFormType;
68
69
    /**
70
     * @var array
71
     */
72
    private $changePasswordFormValidationGroups;
73
74
    public function __construct(
75
        EngineInterface $templating,
76
        $changePasswordActionTemplate,
77
        UserRepositoryInterface $userRepository,
78
        RouterInterface $router,
79
        FormFactoryInterface $formFactory,
80
        EventDispatcherInterface $eventDispatcher,
81
        FlashMessages $flashMessages,
82
        string $changePasswordFormType,
83
        array $changePasswordFormValidationGroups
84
    ) {
85
        $this->templating = $templating;
86
        $this->changePasswordActionTemplate = $changePasswordActionTemplate;
87
        $this->userRepository = $userRepository;
88
        $this->router = $router;
89
        $this->formFactory = $formFactory;
90
        $this->eventDispatcher = $eventDispatcher;
91
        $this->flashMessages = $flashMessages;
92
        $this->changePasswordFormType = $changePasswordFormType;
93
        $this->changePasswordFormValidationGroups = $changePasswordFormValidationGroups;
94
    }
95
96
    public function activateAction($token)
97
    {
98
        $user = $this->tryFindUserByActivationToken($token);
99
100
        if ($this->isUserEnforcedToChangePassword($user)) {
101
            $this->flashMessages->info(
102
                'admin.activation.message.change_password',
103
                [],
104
                'FSiAdminSecurity'
105
            );
106
107
            return new RedirectResponse(
108
                $this->router->generate('fsi_admin_activation_change_password', ['token' => $token])
109
            );
110
        } else {
111
            $this->eventDispatcher->dispatch(
112
                AdminSecurityEvents::ACTIVATION,
113
                new ActivationEvent($user)
114
            );
115
116
            return $this->addFlashAndRedirect('success', 'admin.activation.message.success');
117
        }
118
    }
119
120
    public function changePasswordAction(Request $request, $token)
121
    {
122
        $user = $this->tryFindUserByActivationToken($token);
123
124
        if (!$this->isUserEnforcedToChangePassword($user)) {
125
            throw new NotFoundHttpException();
126
        }
127
128
        $form = $this->formFactory->create(
129
            $this->changePasswordFormType,
130
            $user,
131
            ['validation_groups' => $this->changePasswordFormValidationGroups]
132
        );
133
134
        if ($form->handleRequest($request)->isSubmitted() && $form->isValid()) {
135
            $this->eventDispatcher->dispatch(
136
                AdminSecurityEvents::ACTIVATION,
137
                new ActivationEvent($user)
138
            );
139
140
            $this->eventDispatcher->dispatch(
141
                AdminSecurityEvents::CHANGE_PASSWORD,
142
                new ChangePasswordEvent($user)
143
            );
144
145
            return $this->addFlashAndRedirect('success', 'admin.activation.message.change_password_success');
146
        }
147
148
        return $this->templating->renderResponse(
149
            $this->changePasswordActionTemplate,
150
            ['form' => $form->createView()]
151
        );
152
    }
153
154
    /**
155
     * @param $token
156
     * @return ActivableInterface|null
157
     */
158
    private function tryFindUserByActivationToken($token)
159
    {
160
        $user = $this->userRepository->findUserByActivationToken($token);
161
162
        if (!($user instanceof ActivableInterface)) {
163
            throw new NotFoundHttpException();
164
        }
165
166
        if ($user->isEnabled()) {
167
            throw new NotFoundHttpException();
168
        }
169
170
        if (!$user->getActivationToken()->isNonExpired()) {
171
            throw new NotFoundHttpException();
172
        }
173
174
        return $user;
175
    }
176
177
    /**
178
     * @param string $type
179
     * @param string $message
180
     * @return RedirectResponse
181
     */
182
    private function addFlashAndRedirect($type, $message)
183
    {
184
        $this->flashMessages->{$type}($message, [], 'FSiAdminSecurity');
185
186
        return new RedirectResponse($this->router->generate('fsi_admin_security_user_login'));
187
    }
188
189
    /**
190
     * @param $user
191
     * @return bool
192
     */
193
    private function isUserEnforcedToChangePassword($user)
194
    {
195
        return ($user instanceof EnforceablePasswordChangeInterface) && $user->isForcedToChangePassword();
196
    }
197
}
198