Blame


1 925168e0 2022-04-14 o package mailmux
2 925168e0 2022-04-14 o
3 925168e0 2022-04-14 o import (
4 925168e0 2022-04-14 o "database/sql"
5 925168e0 2022-04-14 o "fmt"
6 925168e0 2022-04-14 o "time"
7 925168e0 2022-04-14 o )
8 925168e0 2022-04-14 o
9 925168e0 2022-04-14 o type Alias struct {
10 925168e0 2022-04-14 o Recipient string
11 925168e0 2022-04-14 o Destination string
12 925168e0 2022-04-14 o Expiry time.Time
13 925168e0 2022-04-14 o Note string
14 925168e0 2022-04-14 o }
15 925168e0 2022-04-14 o
16 925168e0 2022-04-14 o type AliasStore interface {
17 925168e0 2022-04-14 o Create(dest string) (Alias, error)
18 925168e0 2022-04-14 o Aliases(dest string) ([]Alias, error)
19 925168e0 2022-04-14 o Delete(rcpt string) error
20 925168e0 2022-04-14 o }
21 925168e0 2022-04-14 o
22 925168e0 2022-04-14 o type AliasDB struct {
23 925168e0 2022-04-14 o *sql.DB
24 925168e0 2022-04-14 o dictpath string
25 925168e0 2022-04-14 o }
26 925168e0 2022-04-14 o
27 925168e0 2022-04-14 o func OpenAliasDB(name, dictpath string) (*AliasDB, error) {
28 925168e0 2022-04-14 o db, err := sql.Open("sqlite3", name)
29 925168e0 2022-04-14 o if err != nil {
30 925168e0 2022-04-14 o return nil, err
31 925168e0 2022-04-14 o }
32 925168e0 2022-04-14 o stmt := `
33 925168e0 2022-04-14 o CREATE TABLE IF NOT EXISTS aliases (
34 925168e0 2022-04-14 o recipient TEXT PRIMARY KEY,
35 925168e0 2022-04-14 o destination TEXT NOT NULL,
36 925168e0 2022-04-14 o expiry INTEGER,
37 925168e0 2022-04-14 o note TEXT
38 925168e0 2022-04-14 o );`
39 925168e0 2022-04-14 o _, err = db.Exec(stmt)
40 925168e0 2022-04-14 o return &AliasDB{db, dictpath}, err
41 925168e0 2022-04-14 o }
42 925168e0 2022-04-14 o
43 925168e0 2022-04-14 o func (db *AliasDB) Create(dest string) (Alias, error) {
44 925168e0 2022-04-14 o rcpt, err := RandomUsername(db.dictpath)
45 925168e0 2022-04-14 o if err != nil {
46 925168e0 2022-04-14 o return Alias{}, fmt.Errorf("create alias: %w", err)
47 925168e0 2022-04-14 o }
48 925168e0 2022-04-14 o _, err = db.Exec("INSERT INTO aliases (recipient, destination) VALUES (?, ?)", rcpt, dest)
49 925168e0 2022-04-14 o if err != nil {
50 925168e0 2022-04-14 o return Alias{}, fmt.Errorf("create alias: %w", err)
51 925168e0 2022-04-14 o }
52 925168e0 2022-04-14 o return Alias{Recipient: rcpt, Destination: dest}, nil
53 925168e0 2022-04-14 o }
54 925168e0 2022-04-14 o
55 925168e0 2022-04-14 o func (db *AliasDB) Aliases(dest string) ([]Alias, error) {
56 925168e0 2022-04-14 o rows, err := db.Query("SELECT recipient, destination, expiry, note FROM aliases WHERE destination = ?", dest)
57 925168e0 2022-04-14 o if err != nil {
58 925168e0 2022-04-14 o return nil, fmt.Errorf("aliases for %s: %w", dest, err)
59 925168e0 2022-04-14 o }
60 925168e0 2022-04-14 o defer rows.Close()
61 925168e0 2022-04-14 o var aliases []Alias
62 925168e0 2022-04-14 o for rows.Next() {
63 925168e0 2022-04-14 o var a Alias
64 925168e0 2022-04-14 o var t sql.NullTime
65 925168e0 2022-04-14 o var note sql.NullString
66 925168e0 2022-04-14 o err := rows.Scan(&a.Recipient, &a.Destination, &t, &note)
67 925168e0 2022-04-14 o if err != nil {
68 925168e0 2022-04-14 o return aliases, err
69 925168e0 2022-04-14 o }
70 925168e0 2022-04-14 o if t.Valid {
71 925168e0 2022-04-14 o a.Expiry = t.Time
72 925168e0 2022-04-14 o }
73 925168e0 2022-04-14 o if note.Valid {
74 925168e0 2022-04-14 o a.Note = note.String
75 925168e0 2022-04-14 o }
76 925168e0 2022-04-14 o aliases = append(aliases, a)
77 925168e0 2022-04-14 o }
78 925168e0 2022-04-14 o return aliases, rows.Err()
79 925168e0 2022-04-14 o }
80 925168e0 2022-04-14 o
81 925168e0 2022-04-14 o func (db *AliasDB) Delete(rcpt string) error {
82 925168e0 2022-04-14 o _, err := db.Exec("DELETE FROM aliases WHERE recipient = ?", rcpt)
83 925168e0 2022-04-14 o if err != nil {
84 925168e0 2022-04-14 o return fmt.Errorf("delete %s: %w", rcpt, err)
85 925168e0 2022-04-14 o }
86 925168e0 2022-04-14 o return nil
87 925168e0 2022-04-14 o }