|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace app\modules\user\controllers; |
|
4
|
|
|
|
|
5
|
|
|
use app\components\AuthClientHelper; |
|
6
|
|
|
use app\modules\user\actions\AuthAction; |
|
7
|
|
|
use app\modules\user\models\LoginForm; |
|
8
|
|
|
use app\modules\user\models\PasswordResetRequestForm; |
|
9
|
|
|
use app\modules\user\models\RegistrationForm; |
|
10
|
|
|
use app\modules\user\models\ResetPasswordForm; |
|
11
|
|
|
use app\modules\user\models\User; |
|
12
|
|
|
use app\modules\user\models\UserService; |
|
13
|
|
|
use Yii; |
|
14
|
|
|
use yii\base\ErrorException; |
|
15
|
|
|
use yii\base\InvalidParamException; |
|
16
|
|
|
use yii\caching\TagDependency; |
|
17
|
|
|
use yii\filters\AccessControl; |
|
18
|
|
|
use yii\helpers\ArrayHelper; |
|
19
|
|
|
use yii\web\BadRequestHttpException; |
|
20
|
|
|
use yii\web\Controller; |
|
21
|
|
|
use yii\web\NotFoundHttpException; |
|
22
|
|
|
use yii\web\Response; |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* Base DotPlant2 controller for handling user's login/signup/logout and etc. functions |
|
26
|
|
|
* @package app\controllers |
|
27
|
|
|
*/ |
|
28
|
|
|
class UserController extends Controller |
|
29
|
|
|
{ |
|
30
|
|
|
/** |
|
31
|
|
|
* @inheritdoc |
|
32
|
|
|
*/ |
|
33
|
|
|
public function behaviors() |
|
34
|
|
|
{ |
|
35
|
|
|
return [ |
|
36
|
|
|
'access' => [ |
|
37
|
|
|
'class' => AccessControl::className(), |
|
38
|
|
|
'only' => ['change-password', 'signup', 'profile'], |
|
39
|
|
|
'rules' => [ |
|
40
|
|
|
[ |
|
41
|
|
|
'actions' => ['signup'], |
|
42
|
|
|
'allow' => true, |
|
43
|
|
|
'roles' => ['?'], |
|
44
|
|
|
], |
|
45
|
|
|
[ |
|
46
|
|
|
'actions' => ['profile', 'change-password'], |
|
47
|
|
|
'allow' => true, |
|
48
|
|
|
'roles' => ['@'], |
|
49
|
|
|
], |
|
50
|
|
|
], |
|
51
|
|
|
], |
|
52
|
|
|
]; |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
/** |
|
56
|
|
|
* @inheritdoc |
|
57
|
|
|
*/ |
|
58
|
|
|
public function actions() |
|
59
|
|
|
{ |
|
60
|
|
|
return [ |
|
61
|
|
|
'auth' => [ |
|
62
|
|
|
'class' => 'app\modules\user\actions\AuthAction', |
|
63
|
|
|
'successCallback' => [$this, 'successCallback'], |
|
64
|
|
|
], |
|
65
|
|
|
]; |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* Action for loggin in users |
|
70
|
|
|
* @param null $returnUrl |
|
71
|
|
|
* @return string|Response |
|
72
|
|
|
*/ |
|
73
|
|
|
public function actionLogin($returnUrl = null) |
|
74
|
|
|
{ |
|
75
|
|
|
TagDependency::invalidate(Yii::$app->cache, ['Session:'.Yii::$app->session->id]); |
|
76
|
|
|
if (\Yii::$app->user->isGuest === false) { |
|
77
|
|
|
$this->goHome(); |
|
78
|
|
|
} |
|
79
|
|
|
$model = new LoginForm(); |
|
80
|
|
|
if ($model->load(Yii::$app->request->post()) && $model->login()) { |
|
81
|
|
|
return $this->goBack($returnUrl); |
|
82
|
|
|
} else { |
|
83
|
|
|
return $this->render( |
|
84
|
|
|
'login', |
|
85
|
|
|
[ |
|
86
|
|
|
'model' => $model, |
|
87
|
|
|
] |
|
88
|
|
|
); |
|
89
|
|
|
} |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
/** |
|
93
|
|
|
* Action for user's logout |
|
94
|
|
|
* @return Response |
|
95
|
|
|
*/ |
|
96
|
|
|
public function actionLogout() |
|
97
|
|
|
{ |
|
98
|
|
|
if (!Yii::$app->user->isGuest) { |
|
99
|
|
|
TagDependency::invalidate(Yii::$app->cache, ['Session:' . Yii::$app->session->id]); |
|
100
|
|
|
Yii::$app->user->logout(); |
|
101
|
|
|
} |
|
102
|
|
|
return $this->goHome(); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
/** |
|
106
|
|
|
* Action for standard registration handling |
|
107
|
|
|
* @return string|Response |
|
108
|
|
|
* @throws ErrorException |
|
109
|
|
|
*/ |
|
110
|
|
|
public function actionSignup() |
|
111
|
|
|
{ |
|
112
|
|
|
TagDependency::invalidate(Yii::$app->cache, ['Session:'.Yii::$app->session->id]); |
|
113
|
|
|
$model = new RegistrationForm(); |
|
114
|
|
|
if ($model->load(Yii::$app->request->post())) { |
|
115
|
|
|
$user = $model->signup(); |
|
116
|
|
|
if ($user !== null) { |
|
117
|
|
|
if (Yii::$app->getUser()->login($user)) { |
|
118
|
|
|
return $this->goHome(); |
|
119
|
|
|
} |
|
120
|
|
|
} else { |
|
|
|
|
|
|
121
|
|
|
// there were errors |
|
122
|
|
|
} |
|
123
|
|
|
} |
|
124
|
|
|
return $this->render('signup', [ |
|
125
|
|
|
'model' => $model, |
|
126
|
|
|
]); |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
/** |
|
130
|
|
|
* Action for retrieving needed information from user that wasn't got from social network |
|
131
|
|
|
* @return string|Response |
|
132
|
|
|
*/ |
|
133
|
|
|
public function actionCompleteRegistration() |
|
134
|
|
|
{ |
|
135
|
|
|
/** @var \app\modules\user\models\User $model */ |
|
136
|
|
|
$model = Yii::$app->user->identity; |
|
137
|
|
|
if (intval($model->username_is_temporary) === 1) { |
|
138
|
|
|
// reset username |
|
139
|
|
|
$model->username = ''; |
|
140
|
|
|
} |
|
141
|
|
|
$model->setScenario('completeRegistration'); |
|
142
|
|
|
$model->load(Yii::$app->request->post()); |
|
143
|
|
|
if (Yii::$app->request->isPost && $model->validate()) { |
|
144
|
|
|
$model->username_is_temporary = 0; |
|
145
|
|
|
$model->save(); |
|
146
|
|
|
$auth_action = new AuthAction('post-registration', $this); |
|
147
|
|
|
return $auth_action->redirect('/'); |
|
148
|
|
|
} else { |
|
149
|
|
|
$this->layout = $this->module->postRegistrationLayout; |
|
150
|
|
|
return $this->render('post-registration', [ |
|
151
|
|
|
'model' => $model, |
|
152
|
|
|
]); |
|
153
|
|
|
} |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
/** |
|
157
|
|
|
* Success callback for social networks authentication |
|
158
|
|
|
* @param $client |
|
159
|
|
|
* @throws ErrorException |
|
160
|
|
|
* @throws \yii\base\ExitException |
|
161
|
|
|
*/ |
|
162
|
|
|
public function successCallback($client) |
|
163
|
|
|
{ |
|
164
|
|
|
$model = AuthClientHelper::findUserByService($client); |
|
165
|
|
|
if (is_object($model) === false) { |
|
166
|
|
|
// user not found, retrieve additional data |
|
167
|
|
|
$client = AuthClientHelper::retrieveAdditionalData($client); |
|
168
|
|
|
$attributes = AuthClientHelper::mapUserAttributesWithService($client); |
|
169
|
|
|
// check if it is anonymous user |
|
170
|
|
|
if (Yii::$app->user->isGuest === true) { |
|
171
|
|
|
$model = new User(['scenario' => 'registerService']); |
|
172
|
|
|
$security = Yii::$app->security; |
|
173
|
|
|
$model->setAttributes($attributes['user']); |
|
174
|
|
|
$model->status = User::STATUS_ACTIVE; |
|
175
|
|
|
if (empty($model->username) === true) { |
|
176
|
|
|
// if we doesn't have username - generate unique random temporary username |
|
177
|
|
|
// it will be needed for saving purposes |
|
178
|
|
|
$model->username = $security->generateRandomString(18); |
|
179
|
|
|
$model->username_is_temporary = 1; |
|
180
|
|
|
} |
|
181
|
|
|
$model->setPassword($security->generateRandomString(16)); |
|
182
|
|
|
$model->generateAuthKey(); |
|
183
|
|
|
if ($model->save() === false) { |
|
184
|
|
|
if (isset($model->errors['username'])) { |
|
185
|
|
|
// regenerate username |
|
186
|
|
|
$model->username = $security->generateRandomString(18); |
|
187
|
|
|
$model->username_is_temporary = 1; |
|
188
|
|
|
$model->save(); |
|
189
|
|
|
} |
|
190
|
|
|
if (isset($model->errors['email'])) { |
|
191
|
|
|
// empty email |
|
192
|
|
|
$model->email = null; |
|
193
|
|
|
$model->save(); |
|
194
|
|
|
} |
|
195
|
|
|
if (count($model->errors) > 0) { |
|
196
|
|
|
throw new ErrorException(Yii::t('app', "Temporary error signing up user")); |
|
197
|
|
|
} |
|
198
|
|
|
} |
|
199
|
|
|
} else { |
|
200
|
|
|
// non anonymous - link to existing account |
|
201
|
|
|
/** @var \app\modules\user\models\User $model */ |
|
202
|
|
|
$model = Yii::$app->user->identity; |
|
203
|
|
|
} |
|
204
|
|
|
$service = new UserService(); |
|
205
|
|
|
$service->service_type = $client->className(); |
|
206
|
|
|
$service->service_id = '' . $attributes['service']['service_id']; |
|
207
|
|
|
$service->user_id = $model->id; |
|
208
|
|
|
if ($service->save() === false) { |
|
209
|
|
|
throw new ErrorException(Yii::t('app', "Temporary error saving social service")); |
|
210
|
|
|
} |
|
211
|
|
|
} elseif (Yii::$app->user->isGuest === false) { |
|
212
|
|
|
// service exists and user logged in |
|
213
|
|
|
// check if this service is binded to current user |
|
214
|
|
|
if ($model->id != Yii::$app->user->id) { |
|
215
|
|
|
throw new ErrorException(Yii::t('app', "This service is already binded to another user")); |
|
216
|
|
|
} else { |
|
217
|
|
|
$attributes = AuthClientHelper::mapUserAttributesWithService($client); |
|
218
|
|
|
if (isset($attributes['service']['service_id'])) { |
|
219
|
|
|
UserService::deleteAll( |
|
220
|
|
|
[ |
|
221
|
|
|
'user_id' => $model->id, |
|
222
|
|
|
'service_type' => $client->className(), |
|
223
|
|
|
'service_id' => '' . $attributes['service']['service_id'], |
|
224
|
|
|
] |
|
225
|
|
|
); |
|
226
|
|
|
} |
|
227
|
|
|
} |
|
228
|
|
|
} |
|
229
|
|
|
TagDependency::invalidate(Yii::$app->cache, ['Session:'.Yii::$app->session->id]); |
|
230
|
|
|
Yii::$app->user->login($model, 86400); |
|
231
|
|
|
if ($model->username_is_temporary == 1 || empty($model->email)) { |
|
232
|
|
|
// show post-registration form |
|
233
|
|
|
$this->layout = $this->module->postRegistrationLayout; |
|
234
|
|
|
$model->setScenario('completeRegistration'); |
|
235
|
|
|
echo $this->render('post-registration', [ |
|
236
|
|
|
'model' => $model, |
|
237
|
|
|
]); |
|
238
|
|
|
Yii::$app->end(); |
|
239
|
|
|
return; |
|
240
|
|
|
} |
|
241
|
|
|
} |
|
242
|
|
|
|
|
243
|
|
|
/** |
|
244
|
|
|
* Action for requesting password rest |
|
245
|
|
|
* @return string|Response |
|
246
|
|
|
*/ |
|
247
|
|
|
public function actionRequestPasswordReset() |
|
248
|
|
|
{ |
|
249
|
|
|
$model = new PasswordResetRequestForm(); |
|
250
|
|
|
if ($model->load(Yii::$app->request->post()) && $model->validate()) { |
|
251
|
|
|
if ($model->sendEmail()) { |
|
252
|
|
|
Yii::$app->getSession()->setFlash( |
|
253
|
|
|
'success', |
|
254
|
|
|
Yii::t('app', 'Check your email for further instructions.') |
|
255
|
|
|
); |
|
256
|
|
|
return $this->goHome(); |
|
257
|
|
|
} else { |
|
258
|
|
|
Yii::$app->getSession()->setFlash( |
|
259
|
|
|
'error', |
|
260
|
|
|
Yii::t('app', 'Sorry, we are unable to reset password for email provided.') |
|
261
|
|
|
); |
|
262
|
|
|
} |
|
263
|
|
|
} |
|
264
|
|
|
|
|
265
|
|
|
return $this->render('requestPasswordResetToken', [ |
|
266
|
|
|
'model' => $model, |
|
267
|
|
|
]); |
|
268
|
|
|
} |
|
269
|
|
|
|
|
270
|
|
|
/** |
|
271
|
|
|
* Action for reset password - user follows here by link from email message. |
|
272
|
|
|
* @param $token |
|
273
|
|
|
* @return string|Response |
|
274
|
|
|
* @throws BadRequestHttpException |
|
275
|
|
|
*/ |
|
276
|
|
|
public function actionResetPassword($token) |
|
277
|
|
|
{ |
|
278
|
|
|
try { |
|
279
|
|
|
$model = new ResetPasswordForm($token); |
|
280
|
|
|
} catch (InvalidParamException $e) { |
|
|
|
|
|
|
281
|
|
|
throw new BadRequestHttpException($e->getMessage()); |
|
282
|
|
|
} |
|
283
|
|
|
|
|
284
|
|
|
if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { |
|
285
|
|
|
Yii::$app->getSession()->setFlash( |
|
286
|
|
|
'success', |
|
287
|
|
|
Yii::t('app', 'New password was saved.') |
|
288
|
|
|
); |
|
289
|
|
|
|
|
290
|
|
|
return $this->goHome(); |
|
291
|
|
|
} |
|
292
|
|
|
|
|
293
|
|
|
return $this->render('resetPassword', [ |
|
294
|
|
|
'model' => $model, |
|
295
|
|
|
]); |
|
296
|
|
|
} |
|
297
|
|
|
|
|
298
|
|
|
/** |
|
299
|
|
|
* Action for changing profile fields |
|
300
|
|
|
* @return string |
|
301
|
|
|
*/ |
|
302
|
|
|
public function actionProfile() |
|
303
|
|
|
{ |
|
304
|
|
|
/** @var \app\modules\user\models\User|app\properties\HasProperties $model */ |
|
305
|
|
|
$model = User::findIdentity(Yii::$app->user->id); |
|
306
|
|
|
$model->scenario = 'updateProfile'; |
|
307
|
|
|
$model->getPropertyGroups(false, false, true); |
|
308
|
|
|
$model->abstractModel->setAttributesValues(Yii::$app->request->post()); |
|
309
|
|
|
if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->abstractModel->validate()) { |
|
310
|
|
|
if ($model->save()) { |
|
311
|
|
|
$model->saveProperties(Yii::$app->request->post()); |
|
312
|
|
|
Yii::$app->session->setFlash('success', Yii::t('app', 'Your profile has been updated')); |
|
313
|
|
|
$this->refresh(); |
|
314
|
|
|
} else { |
|
315
|
|
|
Yii::$app->session->setFlash('error', Yii::t('app', 'Internal error')); |
|
316
|
|
|
} |
|
317
|
|
|
} |
|
318
|
|
|
|
|
319
|
|
|
|
|
320
|
|
|
return $this->render( |
|
321
|
|
|
'profile', |
|
322
|
|
|
[ |
|
323
|
|
|
'model' => $model, |
|
324
|
|
|
'services' => ArrayHelper::map($model->services, 'id', 'service_type'), |
|
325
|
|
|
] |
|
326
|
|
|
); |
|
327
|
|
|
} |
|
328
|
|
|
|
|
329
|
|
|
/** |
|
330
|
|
|
* Action for handling password changing |
|
331
|
|
|
* @return string |
|
332
|
|
|
* @throws NotFoundHttpException |
|
333
|
|
|
*/ |
|
334
|
|
|
public function actionChangePassword() |
|
335
|
|
|
{ |
|
336
|
|
|
/** @var app\modules\user\models\User|\yii\web\IdentityInterface $model */ |
|
337
|
|
|
$model = User::findIdentity(Yii::$app->user->id); |
|
338
|
|
|
if (is_null($model)) { |
|
339
|
|
|
throw new NotFoundHttpException; |
|
340
|
|
|
} |
|
341
|
|
|
$model->scenario = 'changePassword'; |
|
342
|
|
|
if (Yii::$app->request->isPost) { |
|
343
|
|
|
$model->load(Yii::$app->request->post()); |
|
344
|
|
|
$formIsValid = $model->validate(); |
|
345
|
|
|
$passwordIsValid = $model->validatePassword($model->password); |
|
346
|
|
|
if (!$passwordIsValid) { |
|
347
|
|
|
$model->addError('password', Yii::t('app', 'Wrong password')); |
|
348
|
|
|
} |
|
349
|
|
|
if ($formIsValid && $passwordIsValid) { |
|
350
|
|
|
$model->setPassword($model->newPassword); |
|
351
|
|
|
if ($model->save(true, ['password_hash'])) { |
|
352
|
|
|
Yii::$app->session->setFlash('success', Yii::t('app', 'Password has been changed')); |
|
353
|
|
|
return $this->refresh(); |
|
354
|
|
|
} else { |
|
355
|
|
|
Yii::$app->session->setFlash('error', Yii::t('app', 'Internal error')); |
|
356
|
|
|
} |
|
357
|
|
|
} |
|
358
|
|
|
} |
|
359
|
|
|
return $this->render('change-password', ['model' => $model]); |
|
360
|
|
|
} |
|
361
|
|
|
} |
|
362
|
|
|
|
This check looks for the
elsebranches ofifstatements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
elsebranches can be removed.could be turned into
This is much more concise to read.