8000 [Security] Added named encoders to EncoderFactory by tamirvs · Pull Request #10005 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Security] Added named encoders to EncoderFactory #10005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added named encoders to EncoderFactory
  • Loading branch information
tamirvs committed Jan 9, 2014
commit 0f6cde75a38b5b11a00506d2b13d8438970e5e69
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Security\Core\Encoder;

/**
* @author Christophe Coevoet <stof@notk.org>
*/
interface EncoderAwareInterface
{
/**
* Gets the name of the encoder used to encode the password.
*
* If the method returns null, the standard way to retrieve the encoder
* will be used instead.
*
* @return string
*/
public function getEncoderName();
}
33 changes: 23 additions & 10 deletions src/Symfony/Component/Security/Core/Encoder/EncoderFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,32 @@ public function __construct(array $encoders)
*/
public function getEncoder($user)
{
foreach ($this->encoders as $class => $encoder) {
if ((is_object($user) && !$user instanceof $class) || (!is_object($user) && !is_subclass_of($user, $class) && $user != $class)) {
continue;
$encoderKey = null;

if ($user instanceof EncoderAwareInterface && (null !== $encoderName = $user->getEncoderName())) {
if (!array_key_exists($encoderName, $this->encoders)) {
throw new \RuntimeException(sprintf('The encoder "%s" was not configured.', $encoderName));
}

if (!$encoder instanceof PasswordEncoderInterface) {
return $this->encoders[$class] = $this->createEncoder($encoder);

$encoderKey = $encoderName;
} else {
foreach ($this->encoders as $class => $encoder) {
if((is_object($user) && $user instanceof $class) || (!is_object($user) && (is_subclass_of($user, $class) || $user == $class))) {
$encoderKey = $class;
break;
}
}

return $this->encoders[$class];
}

throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user));

if (null === $encoderKey) {
throw new \RuntimeException(sprintf('No encoder has been configured for account "%s".', is_object($user) ? get_class($user) : $user));
}

if (!$this->encoders[$encoderKey] instanceof PasswordEncoderInterface) {
$this->encoders[$encoderKey] = $this->createEncoder($this->encoders[$encoderKey]);
}

return $this->encoders[$encoderKey];
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface;
use Symfony\Component\Security\Core\User\User;
use Symfony\Component\Security\Core\User\UserInterface;

Expand Down Expand Up @@ -78,6 +79,59 @@ public function testGetEncoderConfiguredForConcreteClassWithClassName()
$expectedEncoder = new MessageDigestPasswordEncoder('sha1');
$this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
}

public function testGetNamedEncoderForEncoderAware()
{
$factory = new EncoderFactory(array(
'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha256'),
'encoder_name' => new MessageDigestPasswordEncoder('sha1')
));

$encoder = $factory->getEncoder(new EncAwareUser('user', 'pass'));
$expectedEncoder = new MessageDigestPasswordEncoder('sha1');
$this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
}

public function testGetNullNamedEncoderForEncoderAware()
{
$factory = new EncoderFactory(array(
'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'),
'encoder_name' => new MessageDigestPasswordEncoder('sha256')
));

$user = new EncAwareUser('user', 'pass');
$user->encoderName = null;
$encoder = $factory->getEncoder($user);
$expectedEncoder = new MessageDigestPasswordEncoder('sha1');
$this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
}

/**
* @expectedException RuntimeException
*/
public function testGetInvalidNamedEncoderForEncoderAware()
{
$factory = new EncoderFactory(array(
'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'),
'encoder_name' => new MessageDigestPasswordEncoder('sha256')
));

$user = new EncAwareUser('user', 'pass');
$user->encoderName = 'invalid_encoder_name';
$encoder = $factory->getEncoder($user);
}

public function testGetEncoderForEncoderAwareWithClassName()
{
$factory = new EncoderFactory(array(
75E8 'Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser' => new MessageDigestPasswordEncoder('sha1'),
'encoder_name' => new MessageDigestPasswordEncoder('sha256')
));

$encoder = $factory->getEncoder('Symfony\Component\Security\Core\Tests\Encoder\EncAwareUser');
$expectedEncoder = new MessageDigestPasswordEncoder('sha1');
$this->assertEquals($expectedEncoder->encodePassword('foo', ''), $encoder->encodePassword('foo', ''));
}
}

class SomeUser implements UserInterface
Expand All @@ -92,3 +146,13 @@ public function eraseCredentials() {}
class SomeChildUser extends SomeUser
{
}

class EncAwareUser extends SomeUser implements EncoderAwareInterface
{
public $encoderName = 'encoder_name';

public function getEncoderName()
{
return $this->encoderName;
}
}
0