feat: sync temps réel Domain/DomainEmail vers Dovecot via listeners
DomainSyncListener (postPersist, postRemove sur Domain) : - postPersist : crée le domaine dans esymail si inexistant - postRemove : supprime le domaine dans esymail (cascade mailboxes) DomainEmailSyncListener (postPersist, postUpdate, postRemove sur DomainEmail) : - postPersist : crée le domaine si besoin + crée la boîte mail dans esymail avec mot de passe temporaire (bcrypt BLF-CRYPT) - postUpdate : met à jour displayName, quota, isActive dans esymail - postRemove : supprime la boîte dans esymail Flux : Doctrine flush → Listener → EsyMailService → base esymail → Dovecot Les listeners vérifient isAvailable() avant chaque opération (no-op si ESYMAIL_DATABASE_URL non configuré) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
73
src/EventListener/DomainEmailSyncListener.php
Normal file
73
src/EventListener/DomainEmailSyncListener.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\EventListener;
|
||||
|
||||
use App\Entity\DomainEmail;
|
||||
use App\Service\EsyMailService;
|
||||
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
|
||||
use Doctrine\ORM\Event\PostPersistEventArgs;
|
||||
use Doctrine\ORM\Event\PostRemoveEventArgs;
|
||||
use Doctrine\ORM\Event\PostUpdateEventArgs;
|
||||
use Doctrine\ORM\Events;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
#[AsEntityListener(event: Events::postPersist, entity: DomainEmail::class)]
|
||||
#[AsEntityListener(event: Events::postUpdate, entity: DomainEmail::class)]
|
||||
#[AsEntityListener(event: Events::postRemove, entity: DomainEmail::class)]
|
||||
class DomainEmailSyncListener
|
||||
{
|
||||
public function __construct(
|
||||
private EsyMailService $esyMail,
|
||||
private LoggerInterface $logger,
|
||||
) {
|
||||
}
|
||||
|
||||
public function postPersist(DomainEmail $email, PostPersistEventArgs $event): void
|
||||
{
|
||||
if (!$this->esyMail->isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fullEmail = $email->getFullEmail();
|
||||
$domain = $email->getDomain()->getFqdn();
|
||||
|
||||
if (!$this->esyMail->domainExists($domain)) {
|
||||
$this->esyMail->createDomain($domain);
|
||||
}
|
||||
|
||||
$tempPassword = bin2hex(random_bytes(8));
|
||||
|
||||
if ($this->esyMail->createMailbox($fullEmail, $tempPassword, $email->getName(), $email->getQuotaMb())) {
|
||||
$this->logger->info('EsyMail sync: boite creee '.$fullEmail);
|
||||
}
|
||||
}
|
||||
|
||||
public function postUpdate(DomainEmail $email, PostUpdateEventArgs $event): void
|
||||
{
|
||||
if (!$this->esyMail->isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fullEmail = $email->getFullEmail();
|
||||
|
||||
if (!$this->esyMail->mailboxExists($fullEmail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->esyMail->updateMailbox($fullEmail, $email->getName(), $email->getQuotaMb(), $email->isActive());
|
||||
$this->logger->info('EsyMail sync: boite mise a jour '.$fullEmail);
|
||||
}
|
||||
|
||||
public function postRemove(DomainEmail $email, PostRemoveEventArgs $event): void
|
||||
{
|
||||
if (!$this->esyMail->isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fullEmail = $email->getFullEmail();
|
||||
|
||||
if ($this->esyMail->deleteMailbox($fullEmail)) {
|
||||
$this->logger->info('EsyMail sync: boite supprimee '.$fullEmail);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/EventListener/DomainSyncListener.php
Normal file
49
src/EventListener/DomainSyncListener.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\EventListener;
|
||||
|
||||
use App\Entity\Domain;
|
||||
use App\Service\EsyMailService;
|
||||
use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener;
|
||||
use Doctrine\ORM\Event\PostPersistEventArgs;
|
||||
use Doctrine\ORM\Event\PostRemoveEventArgs;
|
||||
use Doctrine\ORM\Events;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
#[AsEntityListener(event: Events::postPersist, entity: Domain::class)]
|
||||
#[AsEntityListener(event: Events::postRemove, entity: Domain::class)]
|
||||
class DomainSyncListener
|
||||
{
|
||||
public function __construct(
|
||||
private EsyMailService $esyMail,
|
||||
private LoggerInterface $logger,
|
||||
) {
|
||||
}
|
||||
|
||||
public function postPersist(Domain $domain, PostPersistEventArgs $event): void
|
||||
{
|
||||
if (!$this->esyMail->isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fqdn = $domain->getFqdn();
|
||||
|
||||
if (!$this->esyMail->domainExists($fqdn)) {
|
||||
$this->esyMail->createDomain($fqdn);
|
||||
$this->logger->info('EsyMail sync: domaine cree '.$fqdn);
|
||||
}
|
||||
}
|
||||
|
||||
public function postRemove(Domain $domain, PostRemoveEventArgs $event): void
|
||||
{
|
||||
if (!$this->esyMail->isAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fqdn = $domain->getFqdn();
|
||||
|
||||
if ($this->esyMail->deleteDomain($fqdn)) {
|
||||
$this->logger->info('EsyMail sync: domaine supprime '.$fqdn);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user