/** * Displays the 'login' page. */ public function actionLogin() { $modelClass = $this->module->getClassName(Module::CLASS_LOGIN_FORM); /** @var \nordsoftware\yii_account\models\form\LoginForm $model */ $model = new $modelClass(); $request = \Yii::app()->request; $this->runAjaxValidation($model, $this->loginFormId); if ($request->isPostRequest) { $model->attributes = $request->getPost(Helper::classNameToPostKey($modelClass)); if ($model->validate() && $model->login()) { /** @var \nordsoftware\yii_account\models\ar\Account $account */ $account = \Yii::app()->user->loadAccount(); // Check if the password has expired and require a password change if necessary. if ($model->hasPasswordExpired($account->id)) { $account->saveAttributes(array('requireNewPassword' => true)); } // Redirect the logged in user to change the password if it needs to be changed. if ($account->requireNewPassword) { $token = $this->module->generateToken(Module::TOKEN_CHANGE_PASSWORD, $account->id); // Logout the user to deny access to restricted actions until the password has been changed. \Yii::app()->user->logout(); $this->redirect(array('/account/password/change', 'token' => $token)); } $this->redirect(\Yii::app()->user->returnUrl); } } $this->render('login', array('model' => $model)); }
/** * Loads the user model for the logged in user. * * @throws \nordsoftware\yii_account\exceptions\Exception if the user is a guest. * @return \nordsoftware\yii_account\models\ar\Account the model. */ public function loadAccount() { if ($this->isGuest) { throw new Exception("Trying to load model for guest user."); } if (!isset($this->_model)) { $modelClass = Helper::getModule()->getClassName(Module::CLASS_ACCOUNT); $this->_model = \CActiveRecord::model($modelClass)->findByPk($this->id); } return $this->_model; }
/** * Creates a password history entry. * * @param int $accountId account id. * @param string $salt password salt. * @param string $password hashed password. * @throws \nordsoftware\yii_account\exceptions\Exception if the history entry cannot be saved. */ public function createHistoryEntry($accountId, $salt, $password) { $modelClass = Helper::getModule()->getClassName(Module::CLASS_PASSWORD_HISTORY); /** @var \nordsoftware\yii_account\models\ar\AccountPasswordHistory $model */ $model = new $modelClass(); $model->accountId = $accountId; $model->salt = $salt; $model->password = $password; if (!$model->save()) { throw new Exception('Failed to save password history entry.'); } }
/** * Creates a new account with the given username and password. * * @param string $username * @param string $password * @throws \nordsoftware\yii_account\exceptions\Exception */ public function actionCreate($username, $password) { $modelClass = Helper::getModule()->getClassName(Module::CLASS_ACCOUNT); /** @var \nordsoftware\yii_account\models\ar\Account $account */ $account = new $modelClass(); $account->username = $username; $account->password = $password; if (!$account->save(false)) { throw new Exception("Failed to create account."); } echo "Account {$username}:{$password} created.\n"; }
public static function createEntry($accountId, $success) { $modelClass = Helper::getModule()->getClassName(Module::CLASS_LOGIN_HISTORY); /** @var \nordsoftware\yii_account\models\ar\AccountLoginHistory $model */ $model = new $modelClass(); $model->accountId = $accountId; $model->success = $success; $model->numFailedAttempts = !$success ? $model->resolveNumFailedAttempts() : 0; if (!$model->save()) { throw new Exception('Failed to save login history entry.'); } }
/** * Displays the 'sign up' page. */ public function actionIndex() { $modelClass = $this->module->getClassName(Module::CLASS_SIGNUP_FORM); /** @var \nordsoftware\yii_account\models\form\SignupForm $model */ $model = new $modelClass(); if ($this->module->enableCaptcha) { $model->scenario = 'withCaptcha'; } $request = \Yii::app()->request; $this->runAjaxValidation($model, $this->formId); if ($request->isPostRequest) { $model->attributes = $request->getPost(Helper::classNameToPostKey($modelClass)); if ($model->validate()) { $accountClass = $this->module->getClassName(Module::CLASS_ACCOUNT); /** @var \nordsoftware\yii_account\models\ar\Account $account */ $account = new $accountClass(); $account->attributes = $model->attributes; if ($account->validate()) { if (!$account->save(false)) { $this->fatalError(); } $model->createHistoryEntry($account->id, $account->salt, $account->password); if (!$this->module->enableActivation) { $account->saveAttributes(array('status' => Account::STATUS_ACTIVATED)); $this->redirect(array('/account/authenticate/login')); } $this->sendActivationMail($account); $this->redirect(array('done')); } // todo: figure out how to avoid this, the problem is that password validation is done on the account foreach ($account->getErrors() as $attribute => $errors) { foreach ($errors as $error) { $model->addError($attribute, $error); } } } // reset the captcha if validation failed. $model->captcha = ''; } $this->render('index', array('model' => $model)); }
?> </p> <?php $form = $this->beginWidget('\\TbActiveForm', array('id' => $this->forgotFormId, 'enableAjaxValidation' => true)); ?> <fieldset> <?php echo $form->textFieldControlGroup($model, 'email', array('label' => false, 'placeholder' => $model->getAttributeLabel('email'), 'block' => true)); ?> </fieldset> <div class="row"> <div class="forgot-submit col-xs-8"> <?php echo TbHtml::submitButton(Helper::t('views', 'Recover Account'), array('color' => TbHtml::BUTTON_COLOR_PRIMARY, 'size' => TbHtml::BUTTON_SIZE_LARGE, 'block' => true)); ?> </div> <div class="forgot-cancel col-xs-4"> <?php echo TbHtml::linkButton(Helper::t('views', 'Cancel'), array('url' => array('/account/authenticate/login'), 'color' => TbHtml::BUTTON_COLOR_LINK, 'size' => TbHtml::BUTTON_SIZE_LARGE, 'block' => true)); ?> </div> </div> <?php $this->endWidget(); ?> </div>
/** * @inheritDoc */ public function attributeLabels() { return array_merge(parent::attributeLabels(), array('email' => Helper::t('labels', 'Email'), 'username' => Helper::t('labels', 'Username'))); }
/** * Performs logic to change the password for an account. * * @param \nordsoftware\yii_account\models\ar\AccountToken $tokenModel authentication token model. * @return \nordsoftware\yii_account\models\form\PasswordForm the form model. */ protected function changePasswordInternal(AccountToken $tokenModel) { $modelClass = $this->module->getClassName(Module::CLASS_PASSWORD_FORM); /** @var \nordsoftware\yii_account\models\form\PasswordForm $model */ $model = new $modelClass(); $request = \Yii::app()->request; $this->runAjaxValidation($model, $this->changeFormId); if ($request->isPostRequest) { $model->attributes = $request->getPost(Helper::classNameToPostKey($modelClass)); if ($model->validate()) { $accountClass = $this->module->getClassName(Module::CLASS_ACCOUNT); /** @var \nordsoftware\yii_account\models\ar\Account $account */ $account = \CActiveRecord::model($accountClass)->findByPk($tokenModel->accountId); // Check that the password has not been used in the past. if ($model->checkPasswordHistory($account, $model->password)) { $model->addError('password', Helper::t('errors', 'You have already used this password.')); } if (!$model->hasErrors() && $account->changePassword($model->password, true)) { $model->createHistoryEntry($account->id, $account->salt, $account->password); // We need to reset the requireNewPassword flag if applicable when the password has been changed. if ($account->requireNewPassword && !$account->saveAttributes(array('requireNewPassword' => false))) { $this->fatalError(); } if (!$tokenModel->saveAttributes(array('status' => AccountToken::STATUS_USED))) { $this->fatalError(); } $this->redirect(array('/account/authenticate/login')); } // todo: figure out how to avoid this, the problem is that password validation is done on the account $model->addError('password', $account->getError('password')); } } return $model; }
<?php echo Helper::t('views', 'Please enter a new password twice to change the password for your account.'); ?> </p> <?php $form = $this->beginWidget('\\TbActiveForm', array('id' => $this->changeFormId, 'enableAjaxValidation' => true)); ?> <fieldset> <?php echo $form->passwordFieldControlGroup($model, 'password', array('label' => false, 'placeholder' => $model->getAttributeLabel('password'), 'block' => true)); ?> <?php echo $form->passwordFieldControlGroup($model, 'verifyPassword', array('label' => false, 'placeholder' => $model->getAttributeLabel('verifyPassword'), 'block' => true)); ?> </fieldset> <div class="row"> <div class="forgot-submit col-xs-8"> <?php echo TbHtml::submitButton(Helper::t('views', 'Change Password'), array('color' => TbHtml::BUTTON_COLOR_PRIMARY, 'size' => TbHtml::BUTTON_SIZE_LARGE, 'block' => true)); ?> </div> </div> <?php $this->endWidget(); ?> </div>
?> <?php echo $form->passwordFieldControlGroup($model, 'password', array('label' => false, 'placeholder' => $model->getAttributeLabel('password'), 'block' => true)); ?> <?php echo $form->passwordFieldControlGroup($model, 'verifyPassword', array('label' => false, 'placeholder' => $model->getAttributeLabel('verifyPassword'), 'block' => true)); ?> <?php if ($model->scenario === 'withCaptcha') { ?> <?php echo $form->textFieldControlGroup($model, 'captcha', array('label' => false, 'placeholder' => $model->getAttributeLabel('captcha'), 'block' => true, 'controlOptions' => array('before' => $this->widget($this->module->getClassName(Module::CLASS_CAPTCHA_WIDGET), array(), true)))); ?> <?php } ?> </fieldset> <div class="row"> <div class="register-submit col-xs-8"> <?php echo TbHtml::submitButton(Helper::t('views', 'Create Account'), array('color' => TbHtml::BUTTON_COLOR_PRIMARY, 'size' => TbHtml::BUTTON_SIZE_LARGE, 'block' => true)); ?> </div> </div> <?php $this->endWidget(); ?> </div>
/** * @param string $email * @return \nordsoftware\yii_account\models\ar\Account * @throws \nordsoftware\yii_account\exceptions\Exception */ public function loadModel($email) { $modelClass = Helper::getModule()->getClassName(Module::CLASS_ACCOUNT); return \CActiveRecord::model($modelClass)->findByAttributes(array('email' => $email)); }
<?php use nordsoftware\yii_account\helpers\Helper; /* @var $this \nordsoftware\yii_account\controllers\SignupController */ /* @var $activateUrl string */ echo Helper::t('email', 'Thank you for signing up'); ?> <br> <br> <?php echo Helper::t('email', 'Please click the link below to activate your account:'); ?> <br> <?php echo CHtml::link($activateUrl, $activateUrl);
<?php use nordsoftware\yii_account\helpers\Helper; /* @var $this \nordsoftware\yii_account\controllers\PasswordController */ /* @var $resetUrl string */ echo Helper::t('email', 'Reset password'); ?> <br> <br> <?php echo Helper::t('email', 'Please click the link below to reset the password for your account:'); ?> <br> <?php echo CHtml::link($resetUrl, $resetUrl);
/** * @param string $message error message. * @throws \CHttpException when called. */ public function fatalError($message = null) { throw new \CHttpException(500, $message === null ? Helper::t('errors', 'Something went wrong.') : $message); }
/** * @inheritDoc */ public function attributeLabels() { return array('id' => Helper::t('labels', 'ID'), 'salt' => Helper::t('labels', 'Salt'), 'username' => Helper::t('labels', 'Username'), 'password' => Helper::t('labels', 'Password'), 'email' => Helper::t('labels', 'Email'), 'passwordStrategy' => Helper::t('labels', 'Password Strategy'), 'requireNewPassword' => Helper::t('labels', 'Require New Password'), 'lastLoginAt' => Helper::t('labels', 'Last Login At'), 'lastActiveAt' => Helper::t('labels', 'Last Active At'), 'status' => Helper::t('labels', 'Status')); }
/** * Returns whether the given token has expired. * * @param \CActiveRecord|\nordsoftware\yii_account\models\ar\AccountToken $tokenModel authentication token model. * @param int $expireTime number of seconds that the token is valid. * @return bool whether the token has expired. */ public function hasTokenExpired(\CActiveRecord $tokenModel, $expireTime) { return strtotime(Helper::sqlNow()) - strtotime($tokenModel->createdAt) > $expireTime; }
/** * @return \nordsoftware\yii_account\models\ar\Account|\YiiPassword\Behavior */ protected function loadAccount() { $modelClass = Helper::getModule()->getClassName(Module::CLASS_ACCOUNT); return \CActiveRecord::model($modelClass)->find(array('condition' => 'username=:username OR email=:email', 'params' => array(':username' => strtolower($this->username), ':email' => $this->username))); }
<div class="row"> <div class="login-submit col-xs-6"> <?php echo TbHtml::submitButton(Helper::t('views', 'Log In'), array('color' => TbHtml::BUTTON_COLOR_PRIMARY, 'size' => TbHtml::BUTTON_SIZE_LARGE, 'block' => true)); ?> </div> <div class="login-stay-logged-in col-xs-6"> <?php echo $form->checkBoxControlGroup($model, 'stayLoggedIn'); ?> </div> </div> <?php $this->endWidget(); ?> <ul class="login-links list-unstyled"> <li><?php echo TbHtml::link(Helper::t('views', 'Create an account'), array('/account/signup/index')); ?> </li> <li>|</li> <li><?php echo TbHtml::link(Helper::t('views', 'Forgot password'), array('/account/password/forgot')); ?> </li> </ul> </div>
<?php use nordsoftware\yii_account\helpers\Helper; /* @var $this \nordsoftware\yii_account\controllers\SignupController */ ?> <div class="register-controller done-action"> <h1><?php echo CHtml::encode(Yii::app()->name); ?> </h1> <p class="lead"><?php echo Helper::t('views', 'Thank you for registering!'); ?> </p> <p><?php echo Helper::t('views', 'You will soon receive an email with instructions on how to activate your account.'); ?> </p> </div>
/** * @inheritDoc */ public function attributeLabels() { return array('id' => Helper::t('labels', 'ID'), 'accountId' => Helper::t('labels', 'Account'), 'type' => Helper::t('labels', 'Type'), 'token' => Helper::t('labels', 'Token'), 'createdAt' => Helper::t('labels', 'Created At'), 'status' => Helper::t('labels', 'Status')); }