Enh: Separated password recovery and registration from AuthController

This commit is contained in:
Lucas Bartholemy 2015-12-26 19:26:38 +01:00
parent c7a43bcef4
commit de93b1b625
16 changed files with 311 additions and 252 deletions

View File

@ -9,26 +9,24 @@
namespace humhub\modules\user\controllers;
use Yii;
use yii\web\HttpException;
use yii\helpers\Url;
use humhub\components\Controller;
use humhub\modules\user\models\Invite;
use humhub\compat\HForm;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Password;
use humhub\modules\user\models\forms\AccountRecoverPassword;
/**
* AuthController handles all authentication tasks.
* AuthController handles login and logout
*
* @package humhub.modules_core.user.controllers
* @since 0.5
*/
class AuthController extends Controller
{
//public $layout = '//layouts/main1';
/**
* @inheritdoc
*/
public $layout = "@humhub/modules/user/views/layouts/main";
/**
* @inheritdoc
*/
public $subLayout = "_layout";
/**
@ -86,7 +84,6 @@ class AuthController extends Controller
} else {
return $this->render('register_success', ['model' => $registerModel]);
}
}
}
@ -97,214 +94,8 @@ class AuthController extends Controller
}
}
/**
* Recover Password Action
* Generates an password reset token and sends an e-mail to the user.
*/
public function actionRecoverPassword()
{
$model = new AccountRecoverPassword();
if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->recover()) {
if (Yii::$app->request->isAjax) {
return $this->renderAjax('recoverPassword_modal_success', array('model' => $model));
}
return $this->render('recoverPassword_success', array('model' => $model));
}
if (Yii::$app->request->isAjax) {
return $this->renderAjax('recoverPassword_modal', array('model' => $model));
}
return $this->render('recoverPassword', array('model' => $model));
}
/**
* Resets users password based on given token
*/
public function actionResetPassword()
{
$user = User::findOne(array('guid' => Yii::$app->request->get('guid')));
if ($user === null || !$this->checkPasswordResetToken($user, Yii::$app->request->get('token'))) {
throw new HttpException('500', 'It looks like you clicked on an invalid password reset link. Please try again.');
}
$model = new Password();
$model->scenario = 'registration';
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$user->setSetting('passwordRecoveryToken', '', 'user');
$model->user_id = $user->id;
$model->setPassword($model->newPassword);
$model->save();
return $this->render('resetPassword_success');
}
return $this->render('resetPassword', array('model' => $model));
}
private function checkPasswordResetToken($user, $token)
{
// Saved token - Format: randomToken.generationTime
$savedTokenInfo = $user->getSetting('passwordRecoveryToken', 'user');
if ($savedTokenInfo !== "") {
list($generatedToken, $generationTime) = explode('.', $savedTokenInfo);
if (\humhub\libs\Helpers::same($generatedToken, $token)) {
// Check token generation time
if ($generationTime + (24 * 60 * 60) >= time()) {
return true;
}
}
}
return false;
}
/**
* Create an account
*
* This action is called after e-mail validation.
*/
public function actionCreateAccount()
{
$needApproval = \humhub\models\Setting::Get('needApproval', 'authentication_internal');
if (!Yii::$app->user->isGuest)
throw new HttpException(401, 'Your are already logged in! - Logout first!');
$userInvite = Invite::findOne(['token' => Yii::$app->request->get('token')]);
if (!$userInvite)
throw new HttpException(404, 'Token not found!');
if ($userInvite->language)
Yii::$app->language = $userInvite->language;
$userModel = new User();
$userModel->scenario = 'registration';
$userModel->email = $userInvite->email;
$userPasswordModel = new Password();
$userPasswordModel->scenario = 'registration';
$profileModel = $userModel->profile;
$profileModel->scenario = 'registration';
// Build Form Definition
$definition = array();
$definition['elements'] = array();
$groupModels = \humhub\modules\user\models\Group::find()->orderBy('name ASC')->all();
$defaultUserGroup = \humhub\models\Setting::Get('defaultUserGroup', 'authentication_internal');
$groupFieldType = "dropdownlist";
if ($defaultUserGroup != "") {
$groupFieldType = "hidden";
} else if (count($groupModels) == 1) {
$groupFieldType = "hidden";
$defaultUserGroup = $groupModels[0]->id;
}
if ($groupFieldType == 'hidden') {
$userModel->group_id = $defaultUserGroup;
}
// Add User Form
$definition['elements']['User'] = array(
'type' => 'form',
'title' => Yii::t('UserModule.controllers_AuthController', 'Account'),
'elements' => array(
'username' => array(
'type' => 'text',
'class' => 'form-control',
'maxlength' => 25,
),
'group_id' => array(
'type' => $groupFieldType,
'class' => 'form-control',
'items' => \yii\helpers\ArrayHelper::map($groupModels, 'id', 'name'),
'value' => $defaultUserGroup,
),
),
);
// Add User Password Form
$definition['elements']['UserPassword'] = array(
'type' => 'form',
#'title' => 'Password',
'elements' => array(
'newPassword' => array(
'type' => 'password',
'class' => 'form-control',
'maxlength' => 255,
),
'newPasswordConfirm' => array(
'type' => 'password',
'class' => 'form-control',
'maxlength' => 255,
),
),
);
// Add Profile Form
$definition['elements']['Profile'] = array_merge(array('type' => 'form'), $profileModel->getFormDefinition());
// Get Form Definition
$definition['buttons'] = array(
'save' => array(
'type' => 'submit',
'class' => 'btn btn-primary',
'label' => Yii::t('UserModule.controllers_AuthController', 'Create account'),
),
);
$form = new HForm($definition);
$form->models['User'] = $userModel;
$form->models['UserPassword'] = $userPasswordModel;
$form->models['Profile'] = $profileModel;
if ($form->submitted('save') && $form->validate()) {
$this->forcePostRequest();
// Registe User
$form->models['User']->email = $userInvite->email;
$form->models['User']->language = Yii::$app->language;
if ($form->models['User']->save()) {
// Save User Profile
$form->models['Profile']->user_id = $form->models['User']->id;
$form->models['Profile']->save();
// Save User Password
$form->models['UserPassword']->user_id = $form->models['User']->id;
$form->models['UserPassword']->setPassword($form->models['UserPassword']->newPassword);
$form->models['UserPassword']->save();
// Autologin user
if (!$needApproval) {
Yii::$app->user->switchIdentity($form->models['User']);
return $this->redirect(Url::to(['/dashboard/dashboard']));
}
return $this->render('createAccount_success', array(
'form' => $form,
'needApproval' => $needApproval,
));
}
}
return $this->render('createAccount', array(
'hForm' => $form,
'needAproval' => $needApproval)
);
}
/**
* Logouts a User
*
*/
public function actionLogout()
{
@ -325,27 +116,6 @@ class AuthController extends Controller
$this->redirect(Yii::$app->homeUrl);
}
/**
* Check Login State
*
* Generates a JSON Output including the current session state.
* (Whether the user is logged in or not)
*
* Can also used as a kind of keep alive.
*/
public function actionCheckSessionState()
{
$out = array();
$out['loggedIn'] = false;
if (!Yii::$app->user->isGuest) {
$out['loggedIn'] = true;
}
print CJSON::encode($out);
Yii::$app->end();
}
/**
* Allows third party applications to convert a valid sessionId
* into a username.

View File

@ -0,0 +1,115 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\controllers;
use Yii;
use yii\web\HttpException;
use humhub\components\Controller;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Password;
use humhub\modules\user\models\forms\AccountRecoverPassword;
use humhub\modules\user\models\Auth;
/**
* Password Recovery
*
* @since 1.1
*/
class PasswordRecoveryController extends Controller
{
/**
* @inheritdoc
*/
public $layout = "@humhub/modules/user/views/layouts/main";
/**
* @inheritdoc
*/
public $subLayout = "_layout";
/**
* @inheritdoc
*/
public function actions()
{
return [
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
]
];
}
/**
* Recover Password Action
* Generates an password reset token and sends an e-mail to the user.
*/
public function actionIndex()
{
$model = new AccountRecoverPassword();
if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->recover()) {
if (Yii::$app->request->isAjax) {
return $this->renderAjax('success_modal', array('model' => $model));
}
return $this->render('success', array('model' => $model));
}
if (Yii::$app->request->isAjax) {
return $this->renderAjax('index_modal', array('model' => $model));
}
return $this->render('index', array('model' => $model));
}
/**
* Resets users password based on given token
*/
public function actionReset()
{
$user = User::findOne(array('guid' => Yii::$app->request->get('guid')));
if ($user === null || !$this->checkPasswordResetToken($user, Yii::$app->request->get('token'))) {
throw new HttpException('500', 'It looks like you clicked on an invalid password reset link. Please try again.');
}
$model = new Password();
$model->scenario = 'registration';
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$user->setSetting('passwordRecoveryToken', '', 'user');
$model->user_id = $user->id;
$model->setPassword($model->newPassword);
$model->save();
return $this->render('reset_success');
}
return $this->render('reset', array('model' => $model));
}
private function checkPasswordResetToken($user, $token)
{
// Saved token - Format: randomToken.generationTime
$savedTokenInfo = $user->getSetting('passwordRecoveryToken', 'user');
if ($savedTokenInfo !== "") {
list($generatedToken, $generationTime) = explode('.', $savedTokenInfo);
if (\humhub\libs\Helpers::same($generatedToken, $token)) {
// Check token generation time
if ($generationTime + (24 * 60 * 60) >= time()) {
return true;
}
}
}
return false;
}
}
?>

View File

@ -0,0 +1,180 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) 2015 HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\user\controllers;
use Yii;
use yii\web\HttpException;
use yii\helpers\Url;
use humhub\components\Controller;
use humhub\modules\user\models\Invite;
use humhub\compat\HForm;
use humhub\modules\user\models\User;
use humhub\modules\user\models\Password;
/**
* RegistrationController handles new user registration
*
* @since 1.1
*/
class RegistrationController extends Controller
{
/**
* @inheritdoc
*/
public $layout = "@humhub/modules/user/views/layouts/main";
/**
* @inheritdoc
*/
public $subLayout = "_layout";
/**
* Registration Form
*
* @return type
* @throws HttpException
*/
public function actionIndex()
{
$needApproval = \humhub\models\Setting::Get('needApproval', 'authentication_internal');
if (!Yii::$app->user->isGuest)
throw new HttpException(401, 'Your are already logged in! - Logout first!');
$userInvite = Invite::findOne(['token' => Yii::$app->request->get('token')]);
if (!$userInvite)
throw new HttpException(404, 'Token not found!');
if ($userInvite->language)
Yii::$app->language = $userInvite->language;
$userModel = new User();
$userModel->scenario = 'registration';
$userModel->email = $userInvite->email;
$userPasswordModel = new Password();
$userPasswordModel->scenario = 'registration';
$profileModel = $userModel->profile;
$profileModel->scenario = 'registration';
// Build Form Definition
$definition = array();
$definition['elements'] = array();
$groupModels = \humhub\modules\user\models\Group::find()->orderBy('name ASC')->all();
$defaultUserGroup = \humhub\models\Setting::Get('defaultUserGroup', 'authentication_internal');
$groupFieldType = "dropdownlist";
if ($defaultUserGroup != "") {
$groupFieldType = "hidden";
} else if (count($groupModels) == 1) {
$groupFieldType = "hidden";
$defaultUserGroup = $groupModels[0]->id;
}
if ($groupFieldType == 'hidden') {
$userModel->group_id = $defaultUserGroup;
}
// Add User Form
$definition['elements']['User'] = array(
'type' => 'form',
'title' => Yii::t('UserModule.controllers_AuthController', 'Account'),
'elements' => array(
'username' => array(
'type' => 'text',
'class' => 'form-control',
'maxlength' => 25,
),
'group_id' => array(
'type' => $groupFieldType,
'class' => 'form-control',
'items' => \yii\helpers\ArrayHelper::map($groupModels, 'id', 'name'),
'value' => $defaultUserGroup,
),
),
);
// Add User Password Form
$definition['elements']['UserPassword'] = array(
'type' => 'form',
#'title' => 'Password',
'elements' => array(
'newPassword' => array(
'type' => 'password',
'class' => 'form-control',
'maxlength' => 255,
),
'newPasswordConfirm' => array(
'type' => 'password',
'class' => 'form-control',
'maxlength' => 255,
),
),
);
// Add Profile Form
$definition['elements']['Profile'] = array_merge(array('type' => 'form'), $profileModel->getFormDefinition());
// Get Form Definition
$definition['buttons'] = array(
'save' => array(
'type' => 'submit',
'class' => 'btn btn-primary',
'label' => Yii::t('UserModule.controllers_AuthController', 'Create account'),
),
);
$form = new HForm($definition);
$form->models['User'] = $userModel;
$form->models['UserPassword'] = $userPasswordModel;
$form->models['Profile'] = $profileModel;
if ($form->submitted('save') && $form->validate()) {
$this->forcePostRequest();
// Registe User
$form->models['User']->email = $userInvite->email;
$form->models['User']->language = Yii::$app->language;
if ($form->models['User']->save()) {
// Save User Profile
$form->models['Profile']->user_id = $form->models['User']->id;
$form->models['Profile']->save();
// Save User Password
$form->models['UserPassword']->user_id = $form->models['User']->id;
$form->models['UserPassword']->setPassword($form->models['UserPassword']->newPassword);
$form->models['UserPassword']->save();
// Autologin user
if (!$needApproval) {
Yii::$app->user->switchIdentity($form->models['User']);
return $this->redirect(Url::to(['/dashboard/dashboard']));
}
return $this->render('success', array(
'form' => $form,
'needApproval' => $needApproval,
));
}
}
return $this->render('index', array(
'hForm' => $form,
'needAproval' => $needApproval)
);
}
}
?>

View File

@ -77,7 +77,7 @@ class AccountRecoverPassword extends \yii\base\Model
$mail = Yii::$app->mailer->compose(['html' => '@humhub/modules/user/views/mails/RecoverPassword'], [
'user' => $user,
'linkPasswordReset' => Url::to(["/user/auth/reset-password", 'token' => $token, 'guid' => $user->guid], true)
'linkPasswordReset' => Url::to(["/user/password-recovery/reset", 'token' => $token, 'guid' => $user->guid], true)
]);
$mail->setFrom([\humhub\models\Setting::Get('systemEmailAddress', 'mailing') => \humhub\models\Setting::Get('systemEmailName', 'mailing')]);
$mail->setTo($user->email);

View File

@ -19,14 +19,9 @@ $this->pageTitle = Yii::t('UserModule.views_auth_login', 'Login');
<div class="panel-body">
<?php $form = ActiveForm::begin(['id' => 'account-login-form']); ?>
<p><?php echo Yii::t('UserModule.views_auth_login', "If you're already a member, please login with your username/email and password."); ?></p>
<?php echo $form->field($model, 'username')->textInput(['id' => 'login_username', 'placeholder' => Yii::t('UserModule.views_auth_login', 'username or email')]); ?>
<?php echo $form->field($model, 'password')->passwordInput(['id' => 'login_password', 'placeholder' => Yii::t('UserModule.views_auth_login', 'password')]); ?>
<?php echo $form->field($model, 'rememberMe')->checkbox(); ?>
<hr>
@ -38,13 +33,12 @@ $this->pageTitle = Yii::t('UserModule.views_auth_login', 'Login');
<small>
<?php echo Yii::t('UserModule.views_auth_login', 'Forgot your password?'); ?>
<a
href="<?php echo Url::toRoute('/user/auth/recover-password'); ?>"><br><?php echo Yii::t('UserModule.views_auth_login', 'Create a new one.') ?></a>
href="<?php echo Url::toRoute('/user/password-recovery'); ?>"><br><?php echo Yii::t('UserModule.views_auth_login', 'Create a new one.') ?></a>
</small>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>

View File

@ -75,7 +75,7 @@ use yii\helpers\Url;
'type' => 'POST',
'beforeSend' => new yii\web\JsExpression('function(){ setModalLoader(); }'),
'success' => 'function(html){ $("#globalModal").html(html); }',
'url' => Url::to(['/user/auth/recover-password']),
'url' => Url::to(['/user/password-recovery']),
],
'htmlOptions' => [
'id' => 'recoverPasswordBtn'

View File

@ -122,7 +122,7 @@ use humhub\models\Setting;
style=" background-color:<?php echo Setting::Get('colorPrimary'); ?>; border-radius:5px; background-clip: padding-box;font-size:14px; font-family:Open Sans, Arial,Tahoma, Helvetica, sans-serif; text-align:center; color:#ffffff; font-weight: 600; padding-left:30px; padding-right:30px; padding-top: 5px; padding-bottom: 5px;">
<span style="color: #ffffff; font-weight: 300;">
<a href="<?php echo Url::toRoute(["/user/auth/create-account", 'token' => $token], true); ?>"
<a href="<?php echo Url::toRoute(['/user/registration', 'token' => $token], true); ?>"
style="text-decoration: none; color: #ffffff; font-weight: 300;">
<strong><?php echo Yii::t('UserModule.views_mails_UserInviteSelf', 'Sign up'); ?></strong>
</a>

View File

@ -221,7 +221,7 @@ use humhub\models\Setting;
<td width="auto" align="center" valign="middle" height="32" style=" background-color:<?php echo Setting::Get('colorPrimary'); ?>; border-radius:5px; background-clip: padding-box;font-size:14px; font-family:Open Sans, Arial,Tahoma, Helvetica, sans-serif; text-align:center; color:#ffffff; font-weight: 600; padding-left:30px; padding-right:30px; padding-top: 5px; padding-bottom: 5px;">
<span style="color: #ffffff; font-weight: 300;">
<a href="<?php echo Url::to(['/user/auth/create-account', 'token' => $token], true); ?>" style="text-decoration: none; color: #ffffff; font-weight: 300;">
<a href="<?php echo Url::to(['/user/registration', 'token' => $token], true); ?>" style="text-decoration: none; color: #ffffff; font-weight: 300;">
<strong><?php echo Yii::t('UserModule.views_mails_UserInviteSpace', 'Sign up now'); ?></strong>
</a>
</span>

View File

@ -41,7 +41,7 @@ use yii\helpers\Url;
'type' => 'POST',
'beforeSend' => new yii\web\JsExpression('function(){ setModalLoader(); }'),
'success' => 'function(html){ $("#globalModal").html(html); }',
'url' => Url::to(['/user/auth/recover-password']),
'url' => Url::to(['/user/password-recovery']),
],
'htmlOptions' => [
'class' => 'btn btn-primary', 'id' => 'recoverPasswordBtn'
@ -59,12 +59,12 @@ use yii\helpers\Url;
'class' => 'btn btn-primary', 'id' => 'backBtn'
]
]);
?>
?>
<?php CActiveForm::end() ?>
</div>
</div>
</div>
</div>
<script type="text/javascript">