tags:

views:

372

answers:

2

Hi,

i have installed sfDoctrineGuardUser and have created this model that inherits sfGuardUser model:

Usuario:
   inheritance:
     extends: sfGuardUser
     type: simple
   columns:
     nombre_apellidos: string(60)
     sexo: boolean
     fecha_nac: date
     provincia: string(60)
     localidad: string(255)
     email_address: string(255)
     avatar: string(255)
     avatar_mensajes: string(255)

I have also created a module called 'miembros' based on that model.

Well, I log normally through sfGuardAuth/signin, then i go to "miembros/edit/id/$id_of_the_member_i_used_to_log_in" and push 'Save' button. Then i logout.

If i try to log in again, it says: "The username and/or password is invalid".

Later, i have realized that when click 'Save' the value of the field 'password' changes (well its encrypted version). So that is the reason why i can not then log in.

But, why the value of the password change when i click on 'Save' ???

Regards

Javi

A: 

The sf_guard_user object isn't intended to be extended like this via inheritance. A mechanism is provided to let you link a "profile" object to a user. I have seen people use a method similar to yours, but haven't tried it myself, so not sure if this is a common issue with doing that. But I'd check that all your model and form classes properly inherit each other, including the Pluginxxxx classes from the plugin folder.

benlumley
A: 

Did you display the old password in the password form field ? in this case it could be displayed encrypted and thus encrypted a second time on saving.

Hashes are typically not decypherable, so you should not display the password on a field.

This is a common problem when working with sfGuard. Here are 2 solutions, there is probably others that will answer this issue :

  1. Do not let user changer user's password in this form and create a separate form for password reset
  2. Let password form field empty by default, and save it only when the user types in a new password

I usually get into the second way, here is the form class used :

class ewaSfGuardUserForm extends sfGuardUserForm
{
  public function configure()
  {
  //  parent::configure();

    //"virtual" new password fields, empty by default
    $this->widgetSchema['new_password'] = new sfWidgetFormInputPassword();
    $this->widgetSchema['new_password_bis'] = new sfWidgetFormInputPassword();

    $error_messages = array('min_length' => 'Passwords must be at least 4 characters long.');
    $this->validatorSchema['new_password'] = new sfValidatorString(array('required' => false, 'min_length' => 4), $error_messages);
    $this->validatorSchema['new_password_bis'] = new sfValidatorString(array('required' => false, 'min_length' => 4), $error_messages);

    $error_messages = array('invalid' => 'New password didn\'t match confirmation');

    //validate identical password
    $this->validatorSchema->setPostValidator(new sfValidatorSchemaCompare('new_password', '==', 'new_password_bis', array(), $error_messages));
    $this->validatorSchema->setPostValidator(
      new sfValidatorAnd(array(
        new sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('email_address'))),
        new sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('username')), array('invalid' => 'Email is already in use for another account')),
        new sfValidatorSchemaCompare('new_password', '==', 'new_password_bis', array(), $error_messages)
      ))
    );
    //unused fields
    unset(
      $this['groups_list'],
      $this['permissions_list'],
      $this['password'],
      $this['created_at'],
      $this['updated_at'],
      $this['last_login'],
      $this['salt'],
      $this['algorithm']
    );

    //putting back validator for real password field
    $this->validatorSchema['password'] = new sfValidatorPass();
  }
}

The other part is in action class sf_guard_userActions

  protected function processForm(sfWebRequest $request, sfForm $form)
  {
    $requestParams = $request->getParameter($form->getName());
    $requestParams['password'] = $requestParams['new_password'];
    $requestParams['email_address'] = $requestParams['username'];
    $form->bind($requestParams, $request->getFiles($form->getName()));
    if ($form->isValid())
    {
        [....] Copy of generated code

    }
  }

The specificity of my implementation is it always force uses email == username.

I do not use an extended model for storing user's profile, but I override defaut sfGuardUser doctrine table to add extra fields like first name, last name, etc. It works this way, perhaps doctrine inheritance would have been better.

Benoit