feat: MAILBOX_EXCLUDE hinzugefügt – Mailboxen per Env von der Synchronisation ausschließen
Build Test Docker Image / docker-test (pull_request) Successful in 1m39s
Run Tests / test (pull_request) Successful in 4m45s

This commit is contained in:
2026-03-29 21:53:02 +02:00
parent 1e51010f10
commit 05faa43541
3 changed files with 55 additions and 1 deletions
+45
View File
@@ -40,6 +40,7 @@ type Daemon struct {
notificationEnabled bool
notificationTrigger string
syncInterval time.Duration
excludeMailboxes map[string]bool
health *healthState
}
@@ -130,8 +131,17 @@ func run() error {
"NOTIFICATION_ENABLED", notificationEnabled,
"MAILCOW_RESOLVE_HOST", os.Getenv("MAILCOW_RESOLVE_HOST"),
"STATEFILE", os.Getenv("STATEFILE"),
"MAILBOX_EXCLUDE", os.Getenv("MAILBOX_EXCLUDE"),
)
excludeMailboxes := parseMailboxExclude()
if len(excludeMailboxes) > 0 {
slog.Info("mailbox exclusion configured", "count", len(excludeMailboxes))
for addr := range excludeMailboxes {
slog.Debug("excluding mailbox", "address", addr)
}
}
notificationTrigger := "PT8H"
if notificationEnabled {
notificationTime := os.Getenv("NOTIFICATION_TIME")
@@ -157,6 +167,7 @@ func run() error {
notificationEnabled: notificationEnabled,
notificationTrigger: notificationTrigger,
syncInterval: syncInterval,
excludeMailboxes: excludeMailboxes,
}
if len(d.stateFilepath) == 0 {
d.stateFilepath = "state.json"
@@ -242,11 +253,24 @@ func (d *Daemon) daemonRun() error {
return nil
}
// isMailboxExcluded prüft, ob eine Mailbox über MAILBOX_EXCLUDE
// von der Synchronisation ausgeschlossen ist.
func (d *Daemon) isMailboxExcluded(username string) bool {
if len(d.excludeMailboxes) == 0 {
return false
}
return d.excludeMailboxes[strings.ToLower(username)]
}
func (d *Daemon) processUser(ctx context.Context, m mailcow.Mailbox) error {
if !m.IsActive() {
slog.DebugContext(ctx, "skipping inactive mailbox", "user", m.Username)
return nil
}
if d.isMailboxExcluded(m.Username) {
slog.DebugContext(ctx, "skipping excluded mailbox", "user", m.Username)
return nil
}
slog.DebugContext(ctx, "processing user", "user", m.Username)
pass, err := d.getUserPass(ctx, m.Username)
if err != nil {
@@ -358,6 +382,27 @@ func runCleanup() error {
return nil
}
// parseMailboxExclude liest MAILBOX_EXCLUDE aus der Umgebung und gibt eine
// Map mit den ausgeschlossenen Mailadressen (lowercase) zurück.
// Mehrere Adressen werden durch Komma getrennt.
func parseMailboxExclude() map[string]bool {
raw := os.Getenv("MAILBOX_EXCLUDE")
if raw == "" {
return nil
}
exclude := make(map[string]bool)
for _, addr := range strings.Split(raw, ",") {
addr = strings.TrimSpace(addr)
if addr != "" {
exclude[strings.ToLower(addr)] = true
}
}
if len(exclude) == 0 {
return nil
}
return exclude
}
// parseSyncInterval liest SYNC_INTERVAL aus der Umgebung und gibt die
// geparste Dauer zurück. Standard: 15m.
func parseSyncInterval() (time.Duration, error) {