15

I'm moving from expressionengine to symfony2 and I'm looking for the best way to migrate the user passwords. The goal is to let legacy users log in with their existing credentials, while passwords for new users are created the default way.

I have looked at custom authentication providers and custom user providers and thought about wether or not to create a separate entity for the legacy users, but I don't know what'd be the best way/design to achieve the above.

FYI:

  • As far as I can see, expressionengine just encrypts the password using sha1 and that's it.
  • I am currently using FOSUserBundle.

Can anyone advice me on a solution?

Thomas K
  • 6,076
  • 5
  • 39
  • 56

2 Answers2

23

Figured it out!

Create a custom encoder and use FOSAdvancedEncoder bundle to select the appropriate encoder.

1. Create the encoder

    <?php

    namespace Acme\MyBundle\Security\Encoder;

    use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;

    class LegacyEncoder implements PasswordEncoderInterface {

        public function encodePassword($raw, $salt)
        {
            // Your Custom encoder logic
            return $something 
        }

        public function isPasswordValid($encoded, $raw, $salt)
        {
            return $encoded === $this->encodePassword($raw, $salt);
        }

    }

2. Register your encoder as service

services:
    acme.legacy_encoder:
        class: Acme\MyBundle\Security\Encoder\LegacyEncoder

3. Install FOSAdvancedEncoderBundle

Look here: https://github.com/friendsofsymfony/FOSAdvancedEncoderBundle/blob/master/Resources/doc/index.md

4. Configure your encoders

In app/config.yml:

fos_advanced_encoder:
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512
        legacy_encoder:
            id: acme.legacy_encoder

5. Implement the encoder aware interface in your User Class

use FOS\AdvancedEncoderBundle\Security\Encoder\EncoderAwareInterface;
use FOS\UserBundle\Entity\User as BaseUser;

class User extends BaseUser implements EncoderAwareInterface {

  ...

  public function getEncoderName() {

      if($this->islegacy()) {
          return "legacy_encoder";
      }

      return NULL;
  }

}

Remember to add a boolean field to administer if a user is a legacy user or not.

That's it.

Thomas K
  • 6,076
  • 5
  • 39
  • 56
-2

Maybe the thread about exporting members from ExpressionEngine to Wordpress will help you.

I don't see any difficulties other than exporting the results from a custom query to the FOSUserBundle structure.

Important things to remember:

  • As Derek Hogue greatly points out on that thread, users will most likely have to reset their passwords
  • You will have to understand the both structures really well in order to correctly import data
Community
  • 1
  • 1
Daniel Ribeiro
  • 10,156
  • 12
  • 47
  • 79
  • Sorry that won't work. As I state in my question: `The goal is to let legacy users log in with their existing credentials, while passwords for new users are created the default way.` – Thomas K Aug 22 '12 at 12:57
  • Yes, it will work. You can just keep the hash of each password instead of asking for the users to reset them. – Daniel Ribeiro Aug 22 '12 at 12:59
  • I have tested it, and it won't. That's because symfony bases the hashed password on a combination of the salt and the plain password. EE just uses sha1 hashed variant of the plain password – Thomas K Aug 22 '12 at 13:05
  • Of course it won't magically work. You are a developer, right? You are gonna have to do some adaption work in order for that to work as expected. You can either change the `security: encoders: FOS\UserBundle\Model\UserInterface: sha512` to the correct hash and be happy, or write some custom code to treat the case of new users and old users. – Daniel Ribeiro Aug 22 '12 at 13:07