Author: Adam Evyčędo <git@apiote.xyz>
add recipient to lock and clear locks when checking sent
db.go | 9 +++++++-- main.go | 4 +--- tyr.go | 54 +++++++++++++++++++++++++++++++++++-------------------
diff --git a/db.go b/db.go index d75b934a9556cbae410a462c63f0d7796fc54799..86501e2c9342891df44e36c17477dee771c6e5e2 100644 --- a/db.go +++ b/db.go @@ -126,6 +126,11 @@ if err != nil && err.Error() != "table mimir_recipients already exists" { return nil, err } + _, err = db.Exec(`alter table tyr_locks add column recipient text`) + if err != nil && err.Error() != "duplicate column name: recipient" { + return nil, err + } + return db, nil } @@ -186,9 +191,9 @@ return locks, nil } func insertLock(db *sql.DB, lock Lock) error { - _, err := db.Exec(`insert into tyr_locks values(?, ?, ?) on + _, err := db.Exec(`insert into tyr_locks values(?, ?, ?, ?) on conflict(address) do nothing`, - lock.address, lock.token, lock.date) + lock.address, lock.token, lock.date, lock.recipient) return err } diff --git a/main.go b/main.go index 643c0fee8916484786061cf4e8e9b51274f30150..91dac23725739f9d64ac7be79ebe97f25e1dd8cb 100644 --- a/main.go +++ b/main.go @@ -179,9 +179,7 @@ if len(args) == 2 { log.Fatalln("missing token (and recipient)") } addressTo := "" - if len(args) == 3 { - addressTo = "*" - } else { + if len(args) != 3 { addressTo = args[3] } tyr_release(db, config, args[2], addressTo, config.Tyr.ImapFolderInbox) diff --git a/tyr.go b/tyr.go index 2b9671f07c380725130e5006edccfae8aff4b5dd..1bcc79b7b9e1e50ba77cdd947370278dd483259e 100644 --- a/tyr.go +++ b/tyr.go @@ -30,17 +30,19 @@ return a.addressFrom == "" && a.addressTo == "" } type Lock struct { - address string - token string - date time.Time + address string + token string + date time.Time + recipient string } -func NewLock(address string) Lock { +func NewLock(address, recipient string) Lock { token := strconv.FormatUint(rand.Uint64(), 16) lock := Lock{ - address: address, - token: token, - date: time.Now(), + address: address, + token: token, + date: time.Now(), + recipient: recipient, } return lock } @@ -52,7 +54,6 @@ /* ASGARD */ func addSentTo(db *sql.DB, c *client.Client, mbox *imap.MailboxStatus, config Config) error { - // todo also release from Quarantine from := uint32(1) to := mbox.Messages seqset := new(imap.SeqSet) @@ -66,10 +67,11 @@ }() for msg := range messages { recipients := append(msg.Envelope.To, msg.Envelope.Cc...) + sender := msg.Envelope.From[0].Address() for _, recipient := range recipients { knownAddress := KnownAddress{ addressFrom: recipient.Address(), - addressTo: "*", + addressTo: sender, ban: false, } err := insertKnownAddress(db, knownAddress) @@ -80,12 +82,26 @@ } } } + clearLocks(db, config) + if err := <-done; err != nil { return err } return nil } +func clearLocks(db *sql.DB, config Config) { + locks, _ := listLocks(db) + for _, lock := range locks { + knownAddresses, _ := getKnownAddress(db, lock.address) + for _, knownAddress := range knownAddresses { + if knownAddress.addressTo == lock.recipient { + releaseQuarantine(db, config, lock, config.Tyr.ImapFolderInbox) + } + } + } +} + func listInboxes(c *client.Client, config Config) ([]*imap.MailboxInfo, error) { mailboxes := make(chan *imap.MailboxInfo, 10) inboxes := []*imap.MailboxInfo{} @@ -180,7 +196,7 @@ if domainRecipient == config.Tyr.MainEmailAddress { sendQuarantine(sender) } - lock = NewLock(sender.Address()) + lock = NewLock(sender.Address(), domainRecipient) insertLock(db, lock) log.Printf("moving %v : %s from %s to %s to quarantine\n", msg.Envelope.Date, msg.Envelope.Subject, msg.Envelope.From[0].Address(), domainRecipient) moveSet.AddNum(msg.Uid) @@ -259,7 +275,10 @@ lock, err := getLock(db, token) if err != nil { log.Fatalln(err) } - err = releaseQuarantine(db, config, lock, addressTo, dest) + if addressTo != "" { + lock.recipient = addressTo + } + err = releaseQuarantine(db, config, lock, dest) if err != nil { log.Fatalln(err) } @@ -272,15 +291,12 @@ Captcha string Error string } -func releaseQuarantine(db *sql.DB, config Config, lock Lock, addressTo, dest string) error { +func releaseQuarantine(db *sql.DB, config Config, lock Lock, dest string) error { deleteLock(db, lock) knownAddress := KnownAddress{ addressFrom: lock.address, - addressTo: addressTo, - ban: false, - } - if dest == config.Tyr.ImapFolderJunk { - knownAddress.ban = true + addressTo: lock.recipient, + ban: dest == config.Tyr.ImapFolderJunk, } err := insertKnownAddress(db, knownAddress) if err != nil { @@ -338,7 +354,7 @@ return } if lock.token != "" && lock.token == formToken { lock.address = formAddress - err = releaseQuarantine(db, config, lock, "*", config.Tyr.ImapFolderInbox) + err = releaseQuarantine(db, config, lock, config.Tyr.ImapFolderInbox) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error())) @@ -365,7 +381,7 @@ w.Header().Add("Location", "?error=token&address="+formAddress) w.WriteHeader(303) return } - err = releaseQuarantine(db, config, lock, "*", config.Tyr.ImapFolderInbox) + err = releaseQuarantine(db, config, lock, config.Tyr.ImapFolderInbox) if err != nil { w.WriteHeader(500) w.Write([]byte(err.Error()))