chore(fixtures) : make AppFixtures idempotent on --append
admin / alice / bob sont desormais resolus via un lookup par username (ensureUser) avant creation, sur le modele de ensureSystemRole (meme fichier) et RbacDemoFixtures::ensureDemoUsers. Sans ce lookup, doctrine:fixtures:load --append (sans purge) violait l'unicite de username en recreant ces comptes. Resultat : tout le jeu de fixtures est rejouable en --append sans erreur ni doublon (verifie : 2 runs consecutifs -> 7 users stables). Le flow canonical make db-reset (purge + load) est inchange.
This commit is contained in:
@@ -28,6 +28,11 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
|||||||
* systeme de maniere idempotente avant de rattacher les utilisateurs, afin
|
* systeme de maniere idempotente avant de rattacher les utilisateurs, afin
|
||||||
* que le workflow "make db-reset && make fixtures" reste one-shot.
|
* que le workflow "make db-reset && make fixtures" reste one-shot.
|
||||||
*
|
*
|
||||||
|
* Idempotence complete (y compris `doctrine:fixtures:load --append`, sans
|
||||||
|
* purge) : roles via ensureSystemRole, utilisateurs via ensureUser (lookup par
|
||||||
|
* username). Rejouer la fixture ne cree donc aucun doublon ni violation
|
||||||
|
* d'unicite de username.
|
||||||
|
*
|
||||||
* Dependance explicite a SitesFixtures (ticket 2) : les 3 sites Chatellerault,
|
* Dependance explicite a SitesFixtures (ticket 2) : les 3 sites Chatellerault,
|
||||||
* Saint-Jean et Pommevic doivent etre presents en base avant d'etre rattaches
|
* Saint-Jean et Pommevic doivent etre presents en base avant d'etre rattaches
|
||||||
* aux users. L'inversion volontaire de l'ordre (AppFixtures ← SitesFixtures)
|
* aux users. L'inversion volontaire de l'ordre (AppFixtures ← SitesFixtures)
|
||||||
@@ -75,8 +80,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
|||||||
$saintJean = $this->requireSite('Saint-Jean');
|
$saintJean = $this->requireSite('Saint-Jean');
|
||||||
$pommevic = $this->requireSite('Pommevic');
|
$pommevic = $this->requireSite('Pommevic');
|
||||||
|
|
||||||
$admin = new User();
|
$admin = $this->ensureUser($manager, 'admin');
|
||||||
$admin->setUsername('admin');
|
|
||||||
$admin->setIsAdmin(true);
|
$admin->setIsAdmin(true);
|
||||||
$admin->setPassword($this->passwordHasher->hashPassword($admin, 'admin'));
|
$admin->setPassword($this->passwordHasher->hashPassword($admin, 'admin'));
|
||||||
$admin->addRbacRole($adminRole);
|
$admin->addRbacRole($adminRole);
|
||||||
@@ -87,8 +91,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
|||||||
$admin->setCurrentSite($chatellerault);
|
$admin->setCurrentSite($chatellerault);
|
||||||
$manager->persist($admin);
|
$manager->persist($admin);
|
||||||
|
|
||||||
$alice = new User();
|
$alice = $this->ensureUser($manager, 'alice');
|
||||||
$alice->setUsername('alice');
|
|
||||||
$alice->setPassword($this->passwordHasher->hashPassword($alice, 'alice'));
|
$alice->setPassword($this->passwordHasher->hashPassword($alice, 'alice'));
|
||||||
$alice->addRbacRole($userRole);
|
$alice->addRbacRole($userRole);
|
||||||
// Alice : un seul site, site courant = ce site.
|
// Alice : un seul site, site courant = ce site.
|
||||||
@@ -96,8 +99,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
|||||||
$alice->setCurrentSite($chatellerault);
|
$alice->setCurrentSite($chatellerault);
|
||||||
$manager->persist($alice);
|
$manager->persist($alice);
|
||||||
|
|
||||||
$bob = new User();
|
$bob = $this->ensureUser($manager, 'bob');
|
||||||
$bob->setUsername('bob');
|
|
||||||
$bob->setPassword($this->passwordHasher->hashPassword($bob, 'bob'));
|
$bob->setPassword($this->passwordHasher->hashPassword($bob, 'bob'));
|
||||||
$bob->addRbacRole($userRole);
|
$bob->addRbacRole($userRole);
|
||||||
// Bob : site different de Alice, pour prouver le filtrage par site
|
// Bob : site different de Alice, pour prouver le filtrage par site
|
||||||
@@ -135,6 +137,27 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
|||||||
return $role;
|
return $role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne l'utilisateur correspondant au username, en le creant s'il
|
||||||
|
* n'existe pas encore. Rend la fixture idempotente y compris en
|
||||||
|
* `doctrine:fixtures:load --append` (sans purge) : sans ce lookup, recreer
|
||||||
|
* « admin » / « alice » / « bob » violerait l'unicite de username. Meme
|
||||||
|
* esprit que ensureSystemRole ci-dessus et RbacDemoFixtures::ensureDemoUsers.
|
||||||
|
*/
|
||||||
|
private function ensureUser(ObjectManager $manager, string $username): User
|
||||||
|
{
|
||||||
|
$user = $manager->getRepository(User::class)->findOneBy(['username' => $username]);
|
||||||
|
|
||||||
|
if (null !== $user) {
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
$user->setUsername($username);
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
private function requireSite(string $name): SiteInterface
|
private function requireSite(string $name): SiteInterface
|
||||||
{
|
{
|
||||||
$site = $this->siteProvider->findByName($name);
|
$site = $this->siteProvider->findByName($name);
|
||||||
|
|||||||
Reference in New Issue
Block a user