package db import "strings" func (d *DB) ListAllowBlock(mailboxID int64) ([]MailboxAllowBlockEntry, error) { rows, err := d.Query(`SELECT id, mailbox_id, list_type, pattern, created_at FROM esrv_mailbox_allowblock WHERE mailbox_id = ? ORDER BY list_type, pattern`, mailboxID) if err != nil { return nil, err } defer rows.Close() var out []MailboxAllowBlockEntry for rows.Next() { var e MailboxAllowBlockEntry var createdAt string if err := rows.Scan(&e.ID, &e.MailboxID, &e.ListType, &e.Pattern, &createdAt); err != nil { return nil, err } e.CreatedAt, _ = parseTime(createdAt) out = append(out, e) } return out, rows.Err() } func (d *DB) AddAllowBlockEntry(mailboxID int64, listType, pattern string) (int64, error) { res, err := d.Exec(`INSERT OR IGNORE INTO esrv_mailbox_allowblock (mailbox_id, list_type, pattern) VALUES (?, ?, ?)`, mailboxID, listType, strings.ToLower(pattern)) if err != nil { return 0, err } return res.LastInsertId() } // RemoveAllowBlockEntry deletes an entry, scoped to mailboxID (mirrors RemoveAppPassword/RemoveAlias). func (d *DB) RemoveAllowBlockEntry(id, mailboxID int64) error { _, err := d.Exec(`DELETE FROM esrv_mailbox_allowblock WHERE id = ? AND mailbox_id = ?`, id, mailboxID) return err } func (d *DB) IsBlocked(mailboxID int64, senderAddr string) (bool, error) { return matchesAllowBlock(d, mailboxID, "block", senderAddr) } func (d *DB) IsAllowed(mailboxID int64, senderAddr string) (bool, error) { return matchesAllowBlock(d, mailboxID, "allow", senderAddr) } // matchesAllowBlock checks senderAddr against every pattern of listType for mailboxID // — an exact address match, or a "@domain.com" wildcard matching senderAddr's domain. func matchesAllowBlock(d *DB, mailboxID int64, listType, senderAddr string) (bool, error) { senderAddr = strings.ToLower(senderAddr) domain := domainPart(senderAddr) rows, err := d.Query(`SELECT pattern FROM esrv_mailbox_allowblock WHERE mailbox_id = ? AND list_type = ?`, mailboxID, listType) if err != nil { return false, err } defer rows.Close() for rows.Next() { var pattern string if err := rows.Scan(&pattern); err != nil { return false, err } if strings.HasPrefix(pattern, "@") { if pattern[1:] == domain { return true, nil } } else if pattern == senderAddr { return true, nil } } return false, rows.Err() }