RecoveryController   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 95.92%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 10
dl 0
loc 150
ccs 47
cts 49
cp 0.9592
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A behaviors() 0 15 1
A actionRequest() 0 33 5
B actionReset() 0 51 8
1
<?php
2
3
/*
4
 * This file is part of the 2amigos/yii2-usuario project.
5
 *
6
 * (c) 2amigOS! <http://2amigos.us/>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Da\User\Controller;
13
14
use Da\User\Event\FormEvent;
15
use Da\User\Event\ResetPasswordEvent;
16
use Da\User\Factory\MailFactory;
17
use Da\User\Form\RecoveryForm;
18
use Da\User\Model\Token;
19
use Da\User\Module;
20
use Da\User\Query\TokenQuery;
21
use Da\User\Query\UserQuery;
22
use Da\User\Service\PasswordRecoveryService;
23
use Da\User\Service\ResetPasswordService;
24
use Da\User\Traits\ContainerAwareTrait;
25
use Da\User\Traits\ModuleAwareTrait;
26
use Da\User\Validator\AjaxRequestModelValidator;
27
use Yii;
28
use yii\base\InvalidConfigException;
29
use yii\base\InvalidParamException;
30
use yii\filters\AccessControl;
31
use yii\web\Controller;
32
use yii\web\NotFoundHttpException;
33
34
class RecoveryController extends Controller
35
{
36
    use ContainerAwareTrait;
37
    use ModuleAwareTrait;
38
39
    protected $userQuery;
40
    protected $tokenQuery;
41
42
    /**
43
     * RecoveryController constructor.
44
     *
45
     * @param string     $id
46
     * @param Module     $module
47
     * @param UserQuery  $userQuery
48
     * @param TokenQuery $tokenQuery
49
     * @param array      $config
50
     */
51 1
    public function __construct($id, Module $module, UserQuery $userQuery, TokenQuery $tokenQuery, array $config = [])
52
    {
53 1
        $this->userQuery = $userQuery;
54 1
        $this->tokenQuery = $tokenQuery;
55 1
        parent::__construct($id, $module, $config);
56 1
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 1
    public function behaviors()
62
    {
63
        return [
64 1
            'access' => [
65
                'class' => AccessControl::class,
66
                'rules' => [
67
                    [
68
                        'allow' => true,
69
                        'actions' => ['request', 'reset'],
70
                        'roles' => ['?'],
71
                    ],
72
                ],
73
            ],
74
        ];
75
    }
76
77
    /**
78
     * Displays / handles user password recovery request.
79
     *
80
     * @throws NotFoundHttpException
81
     * @throws InvalidConfigException
82
     * @throws InvalidParamException
83
     * @return string
84
     *
85
     */
86 1
    public function actionRequest()
87
    {
88 1
        if (!$this->module->allowPasswordRecovery) {
89
            throw new NotFoundHttpException();
90
        }
91
92
        /** @var RecoveryForm $form */
93 1
        $form = $this->make(RecoveryForm::class, [], ['scenario' => RecoveryForm::SCENARIO_REQUEST]);
94
95 1
        $event = $this->make(FormEvent::class, [$form]);
96
97 1
        $this->make(AjaxRequestModelValidator::class, [$form])->validate();
98
99 1
        if ($form->load(Yii::$app->request->post()) && $form->validate()) {
100 1
            $this->trigger(FormEvent::EVENT_BEFORE_REQUEST, $event);
101
102 1
            $mailService = MailFactory::makeRecoveryMailerService($form->email);
103
104 1
            if ($this->make(PasswordRecoveryService::class, [$form->email, $mailService])->run()) {
105 1
                $this->trigger(FormEvent::EVENT_AFTER_REQUEST, $event);
106
            }
107
108 1
            return $this->render(
109 1
                '/shared/message',
110
                [
111 1
                    'title' => Yii::t('usuario', 'Recovery message sent'),
112 1
                    'module' => $this->module,
113
                ]
114
            );
115
        }
116
117 1
        return $this->render('request', ['model' => $form]);
118
    }
119
120
    /**
121
     * Displays / handles user password reset.
122
     *
123
     * @param $id
124
     * @param $code
125
     *
126
     * @throws NotFoundHttpException
127
     * @throws InvalidConfigException
128
     * @throws InvalidParamException
129
     * @return string
130
     *
131
     */
132 1
    public function actionReset($id, $code)
133
    {
134 1
        if (!$this->module->allowPasswordRecovery && !$this->module->allowAdminPasswordRecovery) {
135
            throw new NotFoundHttpException();
136
        }
137
        /** @var Token $token */
138 1
        $token = $this->tokenQuery->whereUserId($id)->whereCode($code)->whereIsRecoveryType()->one();
139
        /** @var ResetPasswordEvent $event */
140 1
        $event = $this->make(ResetPasswordEvent::class, [$token]);
141
142 1
        $this->trigger(ResetPasswordEvent::EVENT_BEFORE_TOKEN_VALIDATE, $event);
143
144 1
        if ($token === null || $token->getIsExpired() || $token->user === null) {
145 1
            Yii::$app->session->setFlash(
146 1
                'danger',
147 1
                Yii::t('usuario', 'Recovery link is invalid or expired. Please try requesting a new one.')
148
            );
149
150 1
            return $this->render(
151 1
                '/shared/message',
152
                [
153 1
                    'title' => Yii::t('usuario', 'Invalid or expired link'),
154 1
                    'module' => $this->module,
155
                ]
156
            );
157
        }
158
159
        /** @var RecoveryForm $form */
160 1
        $form = $this->make(RecoveryForm::class, [], ['scenario' => RecoveryForm::SCENARIO_RESET]);
161 1
        $event = $event->updateForm($form);
162
163 1
        $this->make(AjaxRequestModelValidator::class, [$form])->validate();
164
165 1
        if ($form->load(Yii::$app->getRequest()->post())) {
166 1
            if ($this->make(ResetPasswordService::class, [$form->password, $token->user])->run()) {
167 1
                $this->trigger(ResetPasswordEvent::EVENT_AFTER_RESET, $event);
168
169 1
                Yii::$app->session->setFlash('success', Yii::t('usuario', 'Password has been changed'));
170
171 1
                return $this->render(
172 1
                    '/shared/message',
173
                    [
174 1
                        'title' => Yii::t('usuario', 'Password has been changed'),
175 1
                        'module' => $this->module,
176
                    ]
177
                );
178
            }
179
        }
180
181 1
        return $this->render('reset', ['model' => $form]);
182
    }
183
}
184