Thursday, June 24, 2010

Adding Foreign Keys Manually

Using MyISAM tables (in MySQL), I'm unable to set foreign keys in the database. However, I'm working with several tables which utilize foreign key type relationships. The problem was how to get Yii to recognize those relationships properly.

This one took me a while to figure out. With the help of the experts over at the Yii Forums, I was able to put together this solution.

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.

Thursday, June 10, 2010

Yii User Authentication using MySQL PASSWORD()

This is a pretty simple thing, but it hitched me up for a while, so I thought it worth sharing/recording the solution.

If you use passwords stored with the MySQL PASSWORD() function, the suggested methods of authentication with UserIdentity need to be tweaked.

There are two ways that I have come up with to run the comparison. The first way is more secure, as it doesn't ever send the encrypted password back through the connection, but the second way allows you a more specific 'user found, but password is wrong' error.