This forum is in READ-ONLY mode.
You can look around, but if you want to ask a new question, please use Stack Overflow.

load-data and sfGuard symfony 1.2.5

Questions relating to sfGuardPlugin or other user management plugins

load-data and sfGuard symfony 1.2.5

by ivoba » Sat Apr 04, 2009 2:05 pm

hi everybody,
i have problems with the dump and load-data tasks of symfony and the sfGuard plugin:

after changes to the database and a build-all command all data gets killed, so i dump the data before using:
dump-data ...

the yml fixture then contains also the user data from sfGuard with tables like: sfGuardUser etc.

But when i push the data back using:
load-data ...
all data is back again but the user cant access no more!

Do i have to use a seperatly fixture for sfGuard like the sample fixture?
Or am i missing something fundeamental here?

i use sqlite
ivoba
Junior Member
 
Posts: 21
Joined: Tue Mar 24, 2009 2:36 pm
Location: Cologne

Re: load-data and sfGuard symfony 1.2.5

by smeves » Wed Apr 29, 2009 4:48 am

The problem is that when the data is dumped into the yml file, the passwords are dumped in their encrypted form, just as they are stored in the database. Then, when you load the data back into the database from the yml file, the encrypted passwords are then encrypted *again* before they are loaded back into the database.

This is because anytime setPassword() is called on an sfGuardUser object, it runs it through the encryption algorithm.
Image
Stereo :: Interactive & Design
http://stereointeractive.com/blog
User avatar
smeves
Member
 
Posts: 57
Joined: Mon Apr 03, 2006 8:02 pm
Location: New York, NY

Re: load-data and sfGuard symfony 1.2.5

by ivoba » Wed Apr 29, 2009 12:04 pm

allright thanx

now, what to do?

Seems that this is a bug?!
...to be honest, i dont feel like 'customizing' the load task.
There should be a general solution.

or is there a possibilty to turn that behaviour off?
or any work-around?

currently i stopped using the dump-load thing and alter the db manually.
ivoba
Junior Member
 
Posts: 21
Joined: Tue Mar 24, 2009 2:36 pm
Location: Cologne

Re: load-data and sfGuard symfony 1.2.5

by smeves » Wed Apr 29, 2009 4:46 pm

One solution would be to modify the setPassword() method inside of your sfGuardUser class and set up a condition where the password can be inserted directly into the object without getting filtered through the encryption method.

In the case of fixture loading, when a new user object is being created it already has a salt defined, so you could use this condition to assume the password is already encrypted.

Code: Select all
  public function setPassword($v)
  {
    if ($this->isNew() && $this->getSalt()) {
      $this->setEncryptedPassword($v);
    } else {
      parent::setPassword($v);
    }
  }


The new setEncryptedPassword() method is the exact same as the *BasesfGuardUser* (not the PluginsfGuardUser) implementation of setPassword() where it just sets the password straight up and does not run it through any encryption.

Code: Select all
/**
   * Due to the way the parent PluginsfGuardUser class overrides the setPassword method
   * we have to define our own way to set the password without it being encrypted.
   * Calling parent::setPassword() would execute what is defined in PluginsfGuardUser.
   */
  public function setEncryptedPassword($v)
  {
     if ($v !== null) {
        $v = (string) $v;
     }

     if ($this->password !== $v) {
        $this->password = $v;
        $this->modifiedColumns[] = sfGuardUserPeer::PASSWORD;
     }

     return $this;
  }
Image
Stereo :: Interactive & Design
http://stereointeractive.com/blog
User avatar
smeves
Member
 
Posts: 57
Joined: Mon Apr 03, 2006 8:02 pm
Location: New York, NY

Re: load-data and sfGuard symfony 1.2.5

by ivoba » Wed May 20, 2009 1:25 pm

thanx smeves
i modificated your suggestion:

the patch goes here:
plugins/sfGuardPlugin/lib/model/plugin/PluginsfGuardUser.php

Code: Select all
public function setPassword($password)
  {
    if (!$password && 0 == strlen($password))
    {
      return;
    }
/*
 * iba: if salt is set then probly the passwort is already encrpted
 * thus call setPassword without user_funx algorythm
 */
    $fromdump = false;
    if($this->isNew() && $this->getSalt()){
     $fromdump=true;
    }
    if (!$salt = $this->getSalt())
    {
      $salt = md5(rand(100000, 999999).$this->getUsername());
      $this->setSalt($salt);
    }
    $algorithm = sfConfig::get('app_sf_guard_plugin_algorithm_callable', 'sha1');
    $algorithmAsStr = is_array($algorithm) ? $algorithm[0].'::'.$algorithm[1] : $algorithm;
    if (!is_callable($algorithm))
    {
      throw new sfException(sprintf('The algorithm callable "%s" is not callable.', $algorithmAsStr));
    }
    $this->setAlgorithm($algorithmAsStr);
/*
 * iba: if passwort is already encrypted dont encrypt it again
 */
    if($fromdump){
     parent::setPassword($password);
    }
    else{
     parent::setPassword(call_user_func_array($algorithm, array($salt.$password)));
    }   
   
  }


i tested it here local and it seems to work
for dump & load, and for the normal create user task

is this worth a ticket?
ivoba
Junior Member
 
Posts: 21
Joined: Tue Mar 24, 2009 2:36 pm
Location: Cologne

Re: load-data and sfGuard symfony 1.2.5

by jfsimon » Fri Jul 03, 2009 10:33 am

Thanx you rox !
jfsimon
Junior Member
 
Posts: 12
Joined: Fri Jul 03, 2009 10:11 am

Re: load-data and sfGuard symfony 1.2.5

by goofy » Sun Aug 16, 2009 2:45 am

This is the sfDoctrineGuardPlugin Version :

Code: Select all
  public function setPassword($password)
  {
    if (!$password && 0 == strlen($password))
    {
      return;
    }

    $fromdump = false;
    if($this->isNew() && $this->getSalt()){
     $fromdump=true;
    }

    if (!$salt = $this->getSalt())
    {
      $salt = md5(rand(100000, 999999).$this->getUsername());
      $this->setSalt($salt);
    }
    $modified = $this->getModified();
    if ((!$algorithm = $this->getAlgorithm()) || (isset($modified['algorithm']) && $modified['algorithm'] == $this->getTable()->getDefaultValueOf('algorithm')))
    {
      $algorithm = sfConfig::get('app_sf_guard_plugin_algorithm_callable', 'sha1');
    }
    $algorithmAsStr = is_array($algorithm) ? $algorithm[0].'::'.$algorithm[1] : $algorithm;
    if (!is_callable($algorithm))
    {
      throw new sfException(sprintf('The algorithm callable "%s" is not callable.', $algorithmAsStr));
    }
    $this->setAlgorithm($algorithmAsStr);

    if($fromdump){
     parent::_set('password',$password);
    }
    else{
     parent::_set('password', call_user_func_array($algorithm, array($salt.$password)));
    }
   
  }
goofy
Junior Member
 
Posts: 16
Joined: Fri Mar 09, 2007 3:34 pm

Re: load-data and sfGuard symfony 1.2.5

by spike » Wed Mar 03, 2010 10:51 pm

To get this to work for me (symfony 1.4.2) I had to change the setEncryptedPassword() method to:

Code: Select all
<?php

  public function setEncryptedPassword($v)
  {
     if ($v !== null) {
        $v = (string) $v;
     }

     if ($this->password !== $v) {
        parent::_set('password', $v);
     }

     return $this;
  }

?>
spike
Junior Member
 
Posts: 1
Joined: Wed Mar 03, 2010 10:50 pm

Re: load-data and sfGuard symfony 1.2.5

by frozar » Tue Aug 16, 2011 8:05 am

I'm using symfony 1.4.11 and I use the solution given by ivoba.

But my file is slightly different (certainly due to the upgrades ;) ):
plugins/sfDoctrineGuardPlugin/lib/model/doctrine/PluginsfGuardUser.class.php
Code: Select all
public function setPassword($password)
{
  if (!$password && 0 == strlen($password))
  {
    return;
  }

  $fromdump = false;
  if($this->isNew() && $this->getSalt()){
    $fromdump=true;
  }

  if (!$salt = $this->getSalt())
  {
    $salt = md5(rand(100000, 999999).$this->getUsername());
    $this->setSalt($salt);
  }
  $modified = $this->getModified();
  if ((!$algorithm = $this->getAlgorithm()) || (isset($modified['algorithm']) && $modified['algorithm'] == $this->getTable()->getDefaultValueOf('algorithm\
')))
  {
    $algorithm = sfConfig::get('app_sf_guard_plugin_algorithm_callable', 'sha1');
  }
  $algorithmAsStr = is_array($algorithm) ? $algorithm[0].'::'.$algorithm[1] : $algorithm;
  if (!is_callable($algorithm))
  {
    throw new sfException(sprintf('The algorithm callable "%s" is not callable.', $algorithmAsStr));
  }
  $this->setAlgorithm($algorithmAsStr);

  // You care if the password is new or not (task doctrine:data-load)
  if($fromdump){
    $this->_set('password', $password);
  }
  else{
    $this->_set('password', call_user_func_array($algorithm, array($salt.$password)));
  }
}
frozar
Junior Member
 
Posts: 1
Joined: Tue Aug 16, 2011 7:47 am