Tuesday, June 22, 2010

Saving encrypted passwords for new users

When using PASSWORD() encrypted passwords for users, I need to save the encrypted version when the file is created or when the password is changed. However, I don't want it to run the encryption every time the file is saved if it's pulled in the encrypted value already.

Putting the job of encrypting the password on the User model, I've added an encryptPassword() function to the model, which can be called by the controller after it receives the post data as such:

public function encryptPassword()
{
    $p = $this->userpass;
    $this->userpass = new CDbExpression('PASSWORD(:up)', array(':up'=>$p));
}

And modify the actionCreate as such:
...
$model->attributes = $_POST['User']; // existing line
if ( $model->validate()){    
   $model->encryptPassword();
   if ( $model->save( false )){   // modify existing line to pass in false param
      // .. existing code here
   }
} 
- OR -
To automate the process, alter the User model further by adding:
protected function beforeSave()
{
  if ( $this->isNewRecord )
     $this->encryptPassword();
  return parent::beforeSave();
}

Then, if you have a change password form, you can handle it in the same fashion.