Skip to content

Commit 2b7c39e

Browse files
Allow rehashing passwords when possible and needed
1 parent 4b68910 commit 2b7c39e

File tree

8 files changed

+49
-7
lines changed

8 files changed

+49
-7
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ env:
99
global:
1010
- PHPUNIT_FLAGS="-v"
1111
- SYMFONY_PHPUNIT_DIR="$HOME/symfony-bridge/.phpunit"
12+
- SYMFONY_REQUIRE='>=3.4'
1213

1314
matrix:
1415
fast_finish: true
@@ -30,6 +31,8 @@ matrix:
3031
# - env: STABILITY="dev"
3132

3233
before_install:
34+
- find ~/.phpenv -name xdebug.ini -delete
35+
- composer global require --no-progress --no-scripts --no-plugins symfony/flex dev-master
3336
- if ! [ -z "$STABILITY" ]; then composer config minimum-stability ${STABILITY}; fi;
3437
- |
3538
if [[ $deps = low ]]; then

phpunit.xml.dist

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
<php>
1111
<ini name="error_reporting" value="-1" />
1212
<env name="TEST_DATABASE_DSN" value="mysql://root:@127.0.0.1:3306/test_maker" />
13-
<!-- See #237 -->
14-
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak_vendors" />
1513
</php>
1614

1715
<testsuites>

src/Doctrine/EntityClassGenerator.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function __construct(Generator $generator)
2626
$this->generator = $generator;
2727
}
2828

29-
public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $apiResource): string
29+
public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $apiResource, bool $securityUser = false): string
3030
{
3131
$repoClassDetails = $this->generator->createClassNameDetails(
3232
$entityClassDetails->getRelativeName(),
@@ -51,6 +51,7 @@ public function generateEntityClass(ClassNameDetails $entityClassDetails, bool $
5151
'entity_full_class_name' => $entityClassDetails->getFullName(),
5252
'entity_class_name' => $entityClassDetails->getShortName(),
5353
'entity_alias' => $entityAlias,
54+
'security_user' => $securityUser,
5455
]
5556
);
5657

src/Doctrine/EntityRegenerator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ private function generateRepository(ClassMetadata $metadata)
234234
'entity_full_class_name' => $metadata->name,
235235
'entity_class_name' => $entityClassName,
236236
'entity_alias' => strtolower($entityClassName[0]),
237+
'security_user' => false,
237238
]
238239
);
239240

src/Maker/MakeUser.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Console\Input\InputOption;
3434
use Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder;
3535
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
36+
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
3637
use Symfony\Component\Yaml\Yaml;
3738

3839
/**
@@ -138,7 +139,8 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
138139
$entityClassGenerator = new EntityClassGenerator($generator);
139140
$classPath = $entityClassGenerator->generateEntityClass(
140141
$userClassNameDetails,
141-
false // api resource
142+
false, // api resource
143+
interface_exists(PasswordUpgraderInterface::class) // security user
142144
);
143145
} else {
144146
$classPath = $generator->generateClass($userClassNameDetails->getFullName(), 'Class.tpl.php');

src/Resources/skeleton/authenticator/LoginFormAuthenticator.tpl.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
use Symfony\Component\Security\Csrf\CsrfToken;
1818
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
1919
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
20+
<?= ($password_authenticated = $user_needs_encoder && interface_exists('Symfony\Component\Security\Guard\PasswordAuthenticatedInterface')) ? "use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;\n" : '' ?>
2021
use Symfony\Component\Security\Http\Util\TargetPathTrait;
2122

22-
class <?= $class_name; ?> extends AbstractFormLoginAuthenticator
23+
class <?= $class_name; ?> extends AbstractFormLoginAuthenticator<?= $password_authenticated ? " implements PasswordAuthenticatedInterface\n" : "\n" ?>
2324
{
2425
use TargetPathTrait;
2526

@@ -85,6 +86,13 @@ public function checkCredentials($credentials, UserInterface $user)
8586
throw new \Exception('TODO: check the credentials inside '.__FILE__);\n" ?>
8687
}
8788

89+
<?php if ($password_authenticated): ?>
90+
public function getPassword($credentials)
91+
{
92+
return $credentials['password'];
93+
}
94+
95+
<?php endif ?>
8896
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
8997
{
9098
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {

src/Resources/skeleton/doctrine/Repository.tpl.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,36 @@
55
use <?= $entity_full_class_name; ?>;
66
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
77
use Symfony\Bridge\Doctrine\RegistryInterface;
8+
<?= $security_user ? "use Symfony\Component\Security\Core\Exception\UnsupportedUserException;\n" : '' ?>
9+
<?= $security_user ? "use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;\n" : '' ?>
10+
<?= $security_user ? "use Symfony\Component\Security\Core\User\UserInterface;\n" : '' ?>
811

912
/**
1013
* @method <?= $entity_class_name; ?>|null find($id, $lockMode = null, $lockVersion = null)
1114
* @method <?= $entity_class_name; ?>|null findOneBy(array $criteria, array $orderBy = null)
1215
* @method <?= $entity_class_name; ?>[] findAll()
1316
* @method <?= $entity_class_name; ?>[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
1417
*/
15-
class <?= $class_name; ?> extends ServiceEntityRepository
18+
class <?= $class_name; ?> extends ServiceEntityRepository<?= $security_user ? " implements PasswordUpgraderInterface\n" : "\n" ?>
1619
{
1720
public function __construct(RegistryInterface $registry)
1821
{
1922
parent::__construct($registry, <?= $entity_class_name; ?>::class);
2023
}
2124

25+
<?php if ($security_user): ?>
26+
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
27+
{
28+
if (!$user instanceof User) {
29+
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user)));
30+
}
31+
32+
$user->setPassword($newEncodedPassword);
33+
$this->_em->persist($user);
34+
$this->_em->flush();
35+
}
36+
37+
<?php endif ?>
2238
// /**
2339
// * @return <?= $entity_class_name ?>[] Returns an array of <?= $entity_class_name ?> objects
2440
// */

src/Resources/skeleton/security/UserProvider.tpl.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44

55
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
66
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
7+
<?= ($password_upgrader = interface_exists('Symfony\Component\Security\Core\User\PasswordUpgraderInterface')) ? "use Symfony\Component\Security\Core\User\PasswordUpgraderInterface\n" : '' ?>
78
use Symfony\Component\Security\Core\User\UserInterface;
89
use Symfony\Component\Security\Core\User\UserProviderInterface;
910

10-
class <?= $class_name ?> implements UserProviderInterface
11+
class <?= $class_name ?> implements UserProviderInterface<?= $password_upgrader ? ", PasswordUpgraderInterface\n" : "\n" ?>
1112
{
1213
/**
1314
* Symfony calls this method if you use features like switch_user
@@ -60,4 +61,16 @@ public function supportsClass($class)
6061
{
6162
return <?= $user_short_name ?>::class === $class;
6263
}
64+
<?php if ($password_upgrader): ?>
65+
66+
/**
67+
* Upgrades the encoded password of a user, typically for using a better hash algorithm.
68+
*/
69+
public function upgradePassword(UserInterface $user, string $newEncodedPassword): void
70+
{
71+
// TODO: when encoded passwords are in use, this method should:
72+
// 1. persist the new password in the user storage
73+
// 2. update the $user object with $user->setPassword($newEncodedPassword);
74+
}
75+
<?php endif ?>
6376
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy