mailwolt/app/Observers/DomainObserver.php

180 lines
6.6 KiB
PHP

<?php
namespace App\Observers;
use App\Models\DkimKey;
use App\Models\Domain;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Process;
class DomainObserver
{
/**
* DKIM bei neuen Domains erzeugen + in OpenDKIM installieren.
* Läuft NUR, wenn die Domain aktiv ist (anpassbar).
*/
public function created(Domain $domain): void
{
if ($domain->is_server) return;
$selector = (string) config('mailpool.defaults.dkim_selector', 'mwl1');
$bits = (int) config('mailpool.defaults.dkim_bits', 2048);
// Service erledigt: Key generieren, DB (upsert) pflegen, Helper ausführen, OpenDKIM reloaden
app(\App\Services\DkimService::class)->generateForDomain($domain, $bits, $selector);
// DNS-Records: aktiven Key aus DB lesen und provisionieren
$active = $domain->dkimKeys()->where('is_active', true)->latest()->first();
if ($active) {
app(\App\Services\DnsRecordService::class)->provision(
$domain,
$active->selector,
"v=DKIM1; k=rsa; p={$active->public_key_txt}",
[
'spf_tail' => \App\Models\Setting::get('mailpool.spf_tail', '~all'),
'spf_extra' => \App\Models\Setting::get('mailpool.spf_extra', []),
'dmarc_policy' => \App\Models\Setting::get('mailpool.dmarc_policy', 'none'),
'rua' => \App\Models\Setting::get('mailpool.rua', null),
]
);
}
}
/**
* Beim Löschen alle DKIM-Selector dieser Domain aus OpenDKIM entfernen.
*/
public function deleting(Domain $domain): void
{
try {
$svc = app(\App\Services\DkimService::class);
// Selector VOR dem Delete einsammeln (Relation oder direkte Query)
$selectors = DkimKey::where('domain_id', $domain->id)->pluck('selector')->all();
$selectors = $selectors ?: ['mwl1'];
foreach ($selectors as $sel) {
$cmd = ['sudo','-n','/usr/local/sbin/mailwolt-remove-dkim', $domain->domain, $sel];
$res = Process::timeout(30)->run($cmd);
Log::info('DKIM remove exit', [
'domain' => $domain->domain,
'selector' => $sel,
'exit' => $res->exitCode(),
'out' => $res->output(),
'err' => $res->errorOutput(),
]);
if ($res->failed()) {
throw new \RuntimeException('OpenDKIM-Remove fehlgeschlagen: '.$res->errorOutput());
}
}
// lokale Backups unter storage/… löschen (App-User, kein sudo nötig)
$path = storage_path("app/private/dkim/{$domain->domain}");
if (is_dir($path)) {
\Illuminate\Support\Facades\File::deleteDirectory($path);
}
// OpenDKIM neu laden (best effort)
Process::run(['sudo','-n','/bin/systemctl','reload','opendkim']);
} catch (\Throwable $e) {
Log::error('Domain deleting cleanup failed', [
'domain' => $domain->domain,
'error' => $e->getMessage(),
]);
// Optional: Exception werfen, um das Löschen vollständig abzubrechen
// throw $e;
}
}
/** Nur noch Info-Log NACH dem Löschen (kein Cleanup mehr hier) */
public function deleted(Domain $domain): void
{
Log::info('Domain deleted', ['domain' => $domain->domain]);
}
/** Für forceDelete bei SoftDeletes */
public function forceDeleted(Domain $domain): void
{
$this->deleted($domain);
}
// public function deleted(Domain $domain): void
// {
// try {
// $svc = app(\App\Services\DkimService::class);
//
// foreach ($domain->dkimKeys as $key) {
// $svc->removeForDomain($domain, $key->selector);
// }
//
// // Local storage wegräumen (kein Root nötig)
// $path = storage_path("app/private/dkim/{$domain->domain}");
// if (is_dir($path)) {
// \Illuminate\Support\Facades\File::deleteDirectory($path);
// }
//
// Log::info("Domain deleted + DKIM cleaned", ['domain' => $domain->domain]);
// } catch (\Throwable $e) {
// Log::error("Domain delete cleanup failed", ['domain'=>$domain->domain,'error'=>$e->getMessage()]);
// }
// }
//
// public function forceDeleted(Domain $domain): void
// {
// $this->deleted($domain);
// }
// public function created(Domain $domain): void
// {
// if ($domain->is_server) {
// return;
// }
//
// $selector = (string) config('mailpool.defaults.dkim_selector', 'mwl1');
// $bits = (int) config('mailpool.defaults.dkim_bits', 2048);
//
// $res = app(\App\Services\DkimService::class)
// ->generateForDomain($domain, $bits, $selector);
//
// // DNS-Records gleich anlegen/aktualisieren
// app(\App\Services\DnsRecordService::class)->provision(
// $domain,
// $dk->selector,
// "v=DKIM1; k=rsa; p={$dk->public_key_txt}",
// [
// 'spf_tail' => \App\Models\Setting::get('mailpool.spf_tail', '~all'),
// 'spf_extra' => \App\Models\Setting::get('mailpool.spf_extra', []),
// 'dmarc_policy' => \App\Models\Setting::get('mailpool.dmarc_policy', 'none'),
// 'rua' => \App\Models\Setting::get('mailpool.rua', null),
// ]
// );
// }
// public function deleted(Domain $domain): void
// {
// try {
// /** @var \App\Services\DkimService $svc */
// $svc = app(\App\Services\DkimService::class);
//
// // Entferne DKIM aus OpenDKIM Config
// $svc->removeForDomain($domain);
//
// // Optionale lokale Dateien löschen
// $path = storage_path("app/private/dkim/{$domain->domain}");
// if (is_dir($path)) {
// \Illuminate\Support\Facades\File::deleteDirectory($path);
// }
//
// // Reload OpenDKIM
// \Illuminate\Support\Facades\Process::run(['sudo','-n','/usr/bin/systemctl','reload','opendkim']);
//
// Log::info("Domain deleted + DKIM cleaned", ['domain' => $domain->domain]);
// } catch (\Throwable $e) {
// Log::error("Domain delete cleanup failed", [
// 'domain' => $domain->domain,
// 'error' => $e->getMessage(),
// ]);
// }
// }
}