reset password validation in Yii2

rji rji picture rji rji · Apr 11, 2016 · Viewed 7k times · Source

I have a form in which I am trying to reset the password. I have 3 fields password, changepassword and re-enterpassword.

First I need to check whether the password field matches with database password.

While user signup I have used the default Yii2 functionality which generates random password and saves that password into database. Also I used the default login functionality while user login.

And now, for validating the password, I am trying to use the same default Yii2 validation which is used in login. But, it is not working fine. It is always giving validation true when I had echoed and checked in the controller with $user->validate(), which you will find in the below code.

I have a view resetProfilePassword.php in which I have a form

    <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
    <?php  
    echo $form->field($resetpasswordmodel, 'password');
    echo $form->field($resetpasswordmodel, 'changepassword');
    echo $form->field($resetpasswordmodel, 'reenterpassword');
    ?>
    <div class="form-group">
        <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
    </div>
    <?php ActiveForm::end(); ?>

I have a model resetProfilePasswordForm.php

  <?php
    namespace frontend\models;
    use common\models\User;
    use yii\base\Model;

    class ResetProfilePasswordForm extends Model
    {
      public $password;
      public $changepassword;
      public $reenterpassword;

      public function rules()
       {
        return [

        ['password', 'validatePassword'],
        ['changepassword', 'required'],
        ['reenterpassword', 'required'],
        ['reenterpassword', 'compare', 'compareAttribute'=>'changepassword', 'message'=>"Passwords don't match" ]
        ];
      }

public function attributeLabels()
{
    return [
        //'user_profile_id' => 'User Profile ID',
        //'user_ref_id' => 'User Ref ID',
        'password' => 'Password',
        'changepassword' => 'Change Password',
        'reenterpassword' => 'Re-enter Password',
        ];
       }

     public function validatePassword($attribute, $params)
     {
      if (!$this->hasErrors()) {
        $user = $this->getUser();
        if (!$user || !$user->validatePassword($this->password)) {
            $this->addError($attribute, 'Incorrect username or password.');
         }
        }
       }

      protected function getUser()
      {
        if ($this->_user === null) {
          $this->_user = User::findByUsername($this->username);
        }

        return $this->_user;
        }

    }

This is controller ProfileController.php

 public function actionResetProfilePassword()
   {
    $resetpasswordmodel = new ResetProfilePasswordForm();
    if ($resetpasswordmodel->load(Yii::$app->request->post())) {

        $user = User::find()->where(['id' => Yii::$app->user->identity->id])->one();
        if($user->validate()){
        $user->save(false);
        }
     }
             return $this->render('ResetProfilePassword', [
            'resetpasswordmodel' => $resetpasswordmodel
            ]);
     }

Please help me where I am facing the issue. If this is not the right way to validate, please help me in providing the better way to validate password

Answer

aderushev picture aderushev · Apr 12, 2016

To apply resetpasswordmodel validation - just run the validate() method and then - update user model like that:

public function actionResetProfilePassword()
{
    $resetpasswordmodel = new ResetProfilePasswordForm();
    if ($resetpasswordmodel->load(Yii::$app->request->post())) {
        $user = User::find()->where(['id' => Yii::$app->user->identity->id])->one();
        # here we run our validation rules on the model
        if ($resetpasswordmodel->validate()) {
            # if it is ok - setting the password property of user
            $user->password = $resetpasswordmodel->changepassword;
            # and finally save it
            $user->save();
     }
     return $this->render('ResetProfilePassword', [
         'resetpasswordmodel' => $resetpasswordmodel
     ]);
}