Skip to content

Commit eb48706

Browse files
committed
feature #11306 [DX] New service to simplify password encoding (aferrandini)
This PR was merged into the 2.6-dev branch. Discussion ---------- [DX] New service to simplify password encoding | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #11299 | License | MIT | Doc PR | symfony/symfony-docs#3995 This new service siplifies the way to encode a password. Just get the `security.password_encoder` service and encode the `User` password. ```php $encoded = $this->container->get('security.password_encoder') ->encodePassword($user, $plainPassword); $user->setPassword($encoded); ``` Commits ------- 7bc190a New service to simplify password encoding
2 parents bf140a8 + 7bc190a commit eb48706

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<parameter key="security.user_checker.class">Symfony\Component\Security\Core\User\UserChecker</parameter>
1111

1212
<parameter key="security.encoder_factory.generic.class">Symfony\Component\Security\Core\Encoder\EncoderFactory</parameter>
13+
<parameter key="security.user_password_encoder.generic.class">Symfony\Component\Security\Core\Encoder\UserPasswordEncoder</parameter>
1314
<parameter key="security.encoder.digest.class">Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder</parameter>
1415
<parameter key="security.encoder.plain.class">Symfony\Component\Security\Core\Encoder\PlaintextPasswordEncoder</parameter>
1516
<parameter key="security.encoder.pbkdf2.class">Symfony\Component\Security\Core\Encoder\Pbkdf2PasswordEncoder</parameter>
@@ -80,6 +81,12 @@
8081

8182
<service id="security.encoder_factory" alias="security.encoder_factory.generic"></service>
8283

84+
<service id="security.user_password_encoder.generic" class="%security.user_password_encoder.generic.class%" public="false">
85+
<argument type="service" id="security.encoder_factory"></argument>
86+
</service>
87+
88+
<service id="security.password_encoder" alias="security.user_password_encoder.generic"></service>
89+
8390
<service id="security.user_checker" class="%security.user_checker.class%" public="false" />
8491

8592
<service id="security.expression_language" class="%security.expression_language.class%" public="false" />
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Encoder;
13+
14+
use Symfony\Component\Security\Core\User\UserInterface;
15+
16+
/**
17+
* A generic password encoder
18+
*
19+
* @author Ariel Ferrandini <arielferrandini@gmail.com>
20+
*/
21+
class UserPasswordEncoder implements UserPasswordEncoderInterface
22+
{
23+
/**
24+
* @var EncoderFactoryInterface
25+
*/
26+
private $encoderFactory;
27+
28+
/**
29+
* @param EncoderFactoryInterface $encoderFactory The encoder factory
30+
*/
31+
public function __construct(EncoderFactoryInterface $encoderFactory)
32+
{
33+
$this->encoderFactory = $encoderFactory;
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function encodePassword(UserInterface $user, $plainPassword)
40+
{
41+
$encoder = $this->encoderFactory->getEncoder($user);
42+
43+
return $encoder->encodePassword($plainPassword, $user->getSalt());
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function isPasswordValid(UserInterface $user, $raw)
50+
{
51+
$encoder = $this->encoderFactory->getEncoder($user);
52+
53+
return $encoder->isPasswordValid($user->getPassword(), $raw, $user->getSalt());
54+
}
55+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Encoder;
13+
14+
use Symfony\Component\Security\Core\User\UserInterface;
15+
16+
/**
17+
* UserPasswordEncoderInterface is the interface for the password encoder service.
18+
*
19+
* @author Ariel Ferrandini <arielferrandini@gmail.com>
20+
*/
21+
interface UserPasswordEncoderInterface
22+
{
23+
/**
24+
*
25+
* Encodes the plain password.
26+
*
27+
* @param UserInterface $user The user
28+
* @param string $plainPassword The password to encode
29+
*
30+
* @return string The encoded password
31+
*/
32+
public function encodePassword(UserInterface $user, $plainPassword);
33+
34+
/**
35+
* @param UserInterface $user The user
36+
* @param string $raw A raw password
37+
*
38+
* @return bool true if the password is valid, false otherwise
39+
*/
40+
public function isPasswordValid(UserInterface $user, $raw);
41+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Tests\Encoder;
13+
14+
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
15+
16+
class UserPasswordEncoderTest extends \PHPUnit_Framework_TestCase
17+
{
18+
public function testEncodePassword()
19+
{
20+
$userMock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
21+
$userMock->expects($this->any())
22+
->method('getSalt')
23+
->will($this->returnValue('userSalt'));
24+
25+
$mockEncoder = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface');
26+
$mockEncoder->expects($this->any())
27+
->method('encodePassword')
28+
->with($this->equalTo('plainPassword'), $this->equalTo('userSalt'))
29+
->will($this->returnValue('encodedPassword'));
30+
31+
$mockEncoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
32+
$mockEncoderFactory->expects($this->any())
33+
->method('getEncoder')
34+
->with($this->equalTo($userMock))
35+
->will($this->returnValue($mockEncoder));
36+
37+
$passwordEncoder = new UserPasswordEncoder($mockEncoderFactory);
38+
39+
$encoded = $passwordEncoder->encodePassword($userMock, 'plainPassword');
40+
$this->assertEquals('encodedPassword', $encoded);
41+
}
42+
43+
public function testIsPasswordValid()
44+
{
45+
$userMock = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
46+
$userMock->expects($this->any())
47+
->method('getSalt')
48+
->will($this->returnValue('userSalt'));
49+
$userMock->expects($this->any())
50+
->method('getPassword')
51+
->will($this->returnValue('encodedPassword'));
52+
53+
$mockEncoder = $this->getMock('Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface');
54+
$mockEncoder->expects($this->any())
55+
->method('isPasswordValid')
56+
->with($this->equalTo('encodedPassword'), $this->equalTo('plainPassword'), $this->equalTo('userSalt'))
57+
->will($this->returnValue(true));
58+
59+
$mockEncoderFactory = $this->getMock('Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface');
60+
$mockEncoderFactory->expects($this->any())
61+
->method('getEncoder')
62+
->with($this->equalTo($userMock))
63+
->will($this->returnValue($mockEncoder));
64+
65+
$passwordEncoder = new UserPasswordEncoder($mockEncoderFactory);
66+
67+
$isValid = $passwordEncoder->isPasswordValid($userMock, 'plainPassword');
68+
$this->assertTrue($isValid);
69+
}
70+
}

0 commit comments

Comments
 (0)