1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace app\modules\user\controllers; |
4
|
|
|
|
5
|
|
|
use app\modules\mailTemplate\models\Mail; |
6
|
|
|
use app\modules\mailTemplate\models\MailTemplate; |
7
|
|
|
use app\modules\user\models\forms\ChangePasswordForm; |
8
|
|
|
use app\modules\user\models\forms\LoginForm; |
9
|
|
|
use app\modules\user\models\forms\RecoveryForm; |
10
|
|
|
use app\modules\user\models\Hash; |
11
|
|
|
use app\modules\user\models\User; |
12
|
|
|
use BadMethodCallException; |
13
|
|
|
use Yii; |
14
|
|
|
use yii\authclient\BaseClient; |
15
|
|
|
use yii\base\Exception; |
16
|
|
|
use yii\filters\AccessControl; |
17
|
|
|
use yii\helpers\ArrayHelper; |
18
|
|
|
use yii\helpers\Url; |
19
|
|
|
use yii\web\BadRequestHttpException; |
20
|
|
|
use yii\web\Controller; |
21
|
|
|
use app\modules\user\models\forms\RegistrationForm; |
22
|
|
|
use yii\web\ServerErrorHttpException; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* AuthController for the `user` module |
26
|
|
|
*/ |
27
|
|
|
class AuthController extends Controller |
28
|
|
|
{ |
29
|
|
|
/** |
30
|
|
|
* @inheritdoc |
31
|
|
|
*/ |
32
|
58 |
|
public function behaviors() |
33
|
|
|
{ |
34
|
|
|
return [ |
35
|
|
|
'access' => [ |
36
|
58 |
|
'class' => AccessControl::className(), |
37
|
|
|
'only' => ['registration', 'recovery'], |
38
|
|
|
'rules' => [ |
39
|
|
|
[ |
40
|
|
|
'actions' => ['registration', 'recovery'], |
41
|
|
|
'allow' => true, |
42
|
|
|
'roles' => ['?'], |
43
|
|
|
], |
44
|
|
|
], |
45
|
58 |
|
], |
46
|
|
|
]; |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @inheritdoc |
51
|
|
|
*/ |
52
|
58 |
|
public function actions() |
53
|
|
|
{ |
54
|
|
|
return [ |
55
|
|
|
'error' => [ |
56
|
|
|
'class' => 'yii\web\ErrorAction', |
57
|
58 |
|
], |
58
|
|
|
'auth' => [ |
59
|
58 |
|
'class' => 'yii\authclient\AuthAction', |
60
|
58 |
|
'successCallback' => [$this, 'onAuthSuccess'], |
61
|
|
|
], |
62
|
|
|
'upload-avatar' => [ |
63
|
|
|
'class' => 'app\widgets\crop\actions\CropAction', |
64
|
|
|
'url' => '/uploads/avatars', |
65
|
|
|
'path' => '@app/web/uploads/avatars', |
66
|
|
|
], |
67
|
|
|
]; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* This function will be triggered when user is successfully authenticated using some oAuth client. |
72
|
|
|
* |
73
|
|
|
* @param $client |
74
|
|
|
* @return bool |
75
|
|
|
* @throws \BadMethodCallException |
76
|
|
|
*/ |
77
|
|
|
public function onAuthSuccess(BaseClient $client) |
78
|
|
|
{ |
79
|
|
|
$userAttributes = $client->getUserAttributes(); |
80
|
|
|
$user = User::findByEmail(ArrayHelper::getValue($userAttributes, 'email')) ?: new User(); |
81
|
|
|
$isNewUser = $user->isNewRecord; |
82
|
|
|
|
83
|
|
|
if (User::STATUS_BLOCKED === $user->status) { |
84
|
|
|
Yii::$app->session->setFlash('danger', Yii::t('user', 'Your account is blocked.')); |
85
|
|
|
return false; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
$userAttributes['authProvider'] = $client->getName(); |
89
|
|
|
if (!$user->saveSocialAccountInfo($userAttributes)) { |
90
|
|
|
throw new BadMethodCallException('Social data could not be saved.'); |
91
|
|
|
} |
92
|
|
|
if ($isNewUser) { |
93
|
|
|
$user->setRole(User::ROLE_USER); |
94
|
|
|
} |
95
|
|
|
return $user->login(); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @return string|\yii\web\Response |
100
|
|
|
* @throws Exception |
101
|
|
|
* @throws ServerErrorHttpException |
102
|
|
|
*/ |
103
|
4 |
|
public function actionRegistration() |
104
|
|
|
{ |
105
|
4 |
|
$registrationForm = new RegistrationForm(); |
106
|
|
|
|
107
|
4 |
|
if ($registrationForm->load(Yii::$app->request->post()) && $registrationForm->validate()) { |
108
|
1 |
|
$user = new User(); |
109
|
|
|
|
110
|
1 |
|
if (!$user = $user->create($registrationForm)) { |
111
|
|
|
throw new Exception('User could not be created.'); |
112
|
|
|
} |
113
|
|
|
|
114
|
1 |
|
if (!$mailTemplate = MailTemplate::findByKey(MailTemplate::REGISTER_CONFIRM)) { |
115
|
|
|
throw new ServerErrorHttpException('The server encountered an internal error and could not complete your request.'); |
116
|
|
|
} |
117
|
|
|
|
118
|
1 |
|
$hash = new Hash(); |
119
|
1 |
|
$mailTemplate->replacePlaceholders([ |
120
|
1 |
|
'name' => $user->first_name, |
121
|
1 |
|
'link' => Yii::$app->urlManager->createAbsoluteUrl([ |
122
|
1 |
|
'user/auth/confirm-registration', |
123
|
1 |
|
'hash' => $hash->generate(Hash::TYPE_REGISTER, $user->id), |
124
|
|
|
]), |
125
|
|
|
]); |
126
|
|
|
|
127
|
1 |
|
$mail = new Mail(); |
128
|
1 |
|
$mail->setTemplate($mailTemplate); |
129
|
1 |
|
$mail->sendTo($user->email); |
130
|
|
|
|
131
|
1 |
|
Yii::$app->session->setFlash( |
132
|
1 |
|
'success', |
133
|
1 |
|
Yii::t('user', 'Please, check your email to confirm registration.') |
134
|
|
|
); |
135
|
1 |
|
return $this->redirect(Url::home()); |
136
|
|
|
} |
137
|
|
|
|
138
|
4 |
|
return $this->render('registration', [ |
139
|
4 |
|
'model' => $registrationForm, |
140
|
|
|
]); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @return \yii\web\Response |
145
|
|
|
* @throws BadRequestHttpException |
146
|
|
|
* @throws ServerErrorHttpException |
147
|
|
|
*/ |
148
|
|
|
public function actionConfirmRegistration() |
149
|
|
|
{ |
150
|
|
|
if (!$hash = Yii::$app->request->get('hash')) { |
151
|
|
|
throw new BadRequestHttpException(); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
if (!$user = User::findByHash($hash)) { |
155
|
|
|
throw new ServerErrorHttpException('The server encountered an internal error and could not complete your request.'); |
156
|
|
|
} |
157
|
|
|
$user->status = User::STATUS_ACTIVE; |
158
|
|
|
$user->update(); |
159
|
|
|
Hash::findByUserId($user->id)->delete(); |
160
|
|
|
$user->login(); |
161
|
|
|
|
162
|
|
|
return $this->goHome(); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* @return string|\yii\web\Response |
167
|
|
|
* @throws Exception |
168
|
|
|
*/ |
169
|
46 |
|
public function actionLogin() |
170
|
|
|
{ |
171
|
46 |
|
if (!Yii::$app->user->isGuest) { |
172
|
|
|
return $this->goHome(); |
173
|
|
|
} |
174
|
|
|
|
175
|
46 |
|
$loginForm = new LoginForm(); |
176
|
46 |
|
if ($loginForm->load(Yii::$app->request->post()) && $loginForm->validate()) { |
177
|
|
|
|
178
|
1 |
|
$user = User::findByEmail($loginForm->email); |
179
|
|
|
|
180
|
1 |
|
if (!$user || $user->hasEmptyPassword() || !$user->validatePassword($loginForm->password)) { |
181
|
|
|
Yii::$app->session->setFlash('danger', Yii::t('user', 'Incorrect email or password.')); |
182
|
1 |
|
} elseif (User::STATUS_ACTIVE !== $user->status) { |
183
|
|
|
Yii::$app->session->setFlash('danger', Yii::t('user', 'Your account is not active.')); |
184
|
|
|
} else { |
185
|
1 |
|
$user->rememberMe = $loginForm->rememberMe; |
186
|
1 |
|
$user->login(); |
187
|
1 |
|
return $this->goBack(); |
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
|
191
|
46 |
|
return $this->render('login', [ |
192
|
46 |
|
'model' => $loginForm, |
193
|
|
|
]); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Sends link for password recovery on user email |
198
|
|
|
* |
199
|
|
|
* @return string|\yii\web\Response |
200
|
|
|
* @throws ServerErrorHttpException |
201
|
|
|
*/ |
202
|
4 |
|
public function actionRecovery() |
203
|
|
|
{ |
204
|
4 |
|
$recoveryForm = new RecoveryForm(); |
205
|
|
|
|
206
|
4 |
|
if ($recoveryForm->load(Yii::$app->request->post()) && $recoveryForm->validate()) { |
207
|
|
|
|
208
|
1 |
|
if (!$user = User::findByEmail($recoveryForm->email)) { |
209
|
|
|
Yii::$app->session->setFlash('danger', Yii::t('user', 'User does not exist.')); |
210
|
1 |
|
} elseif (User::STATUS_ACTIVE !== $user->status) { |
211
|
|
|
Yii::$app->session->setFlash('danger', Yii::t('user', 'User is not active.')); |
212
|
|
|
} else { |
213
|
|
|
|
214
|
1 |
|
if (!$mailTemplate = MailTemplate::findByKey(MailTemplate::RECOVERY_PASSWORD)) { |
215
|
|
|
throw new ServerErrorHttpException('The server encountered an internal error and could not complete your request.'); |
216
|
|
|
} |
217
|
|
|
|
218
|
1 |
|
$hash = new Hash(); |
219
|
1 |
|
$mailTemplate->replacePlaceholders([ |
220
|
1 |
|
'name' => $user->first_name, |
221
|
1 |
|
'link' => Yii::$app->urlManager->createAbsoluteUrl([ |
222
|
1 |
|
'user/auth/forgot-password', |
223
|
1 |
|
'hash' => $hash->generate(Hash::TYPE_RECOVER, $user->id), |
224
|
|
|
]), |
225
|
|
|
]); |
226
|
|
|
|
227
|
1 |
|
$mail = new Mail(); |
228
|
1 |
|
$mail->setTemplate($mailTemplate); |
229
|
1 |
|
$mail->sendTo($user->email); |
230
|
|
|
|
231
|
1 |
|
Yii::$app->session->setFlash( |
232
|
1 |
|
'success', |
233
|
1 |
|
Yii::t('user', 'Please check your email and follow instructions to recover password.') |
234
|
|
|
); |
235
|
1 |
|
return $this->redirect(Url::home()); |
236
|
|
|
} |
237
|
|
|
} |
238
|
4 |
|
return $this->render('recovery', [ |
239
|
4 |
|
'model' => $recoveryForm, |
240
|
|
|
]); |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @return string|\yii\web\Response |
245
|
|
|
* @throws BadRequestHttpException |
246
|
|
|
* @throws ServerErrorHttpException |
247
|
|
|
*/ |
248
|
5 |
View Code Duplication |
public function actionForgotPassword() |
|
|
|
|
249
|
|
|
{ |
250
|
5 |
|
if (!$hash = Yii::$app->request->get('hash')) { |
251
|
|
|
throw new BadRequestHttpException(); |
252
|
|
|
} |
253
|
5 |
|
if (!$user = User::findByHash($hash)) { |
254
|
|
|
throw new ServerErrorHttpException('The server encountered an internal error and could not complete your request.'); |
255
|
|
|
} |
256
|
5 |
|
$changePasswordForm = new ChangePasswordForm(); |
257
|
5 |
|
if ($user->changePassword($changePasswordForm)) { |
258
|
1 |
|
$user->login(); |
259
|
1 |
|
return $this->goHome(); |
260
|
|
|
} |
261
|
5 |
|
return $this->render('forgot-password', [ |
262
|
5 |
|
'model' => $changePasswordForm, |
263
|
|
|
]); |
264
|
|
|
} |
265
|
|
|
} |
266
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.