all repos — postern @ fc287763b9ce6b6f9823e11c0b1173da0446ebc5

Modern mail management

internal/db/smtpauth.go (view raw)

 1package db
 2
 3import (
 4	"context"
 5	"database/sql"
 6	"errors"
 7	"fmt"
 8	"time"
 9
10	"postern/internal/model"
11
12	"modernc.org/sqlite"
13	sqlite3 "modernc.org/sqlite/lib"
14)
15
16func (db *DB) SMTPAuthNameExists(ctx context.Context, name string) (bool, error) {
17	var count int
18	err := db.read.QueryRowContext(ctx,
19		`SELECT COUNT(*) FROM smtp_auth WHERE name = ?`,
20		name,
21	).Scan(&count)
22	if err != nil {
23		return false, fmt.Errorf("checking name existence: %w", err)
24	}
25	return count > 0, nil
26}
27
28func (db *DB) InsertSMTPAuthUser(ctx context.Context, name string, hash []byte) error {
29	_, err := db.write.ExecContext(ctx,
30		`INSERT INTO smtp_auth (name, password_hash, created_at) VALUES (?, ?, ?)`,
31		name, hash, time.Now().Unix(),
32	)
33	if err != nil {
34		if insertErr, ok := errors.AsType[*sqlite.Error](err); ok {
35			if insertErr.Code() == sqlite3.SQLITE_CONSTRAINT_UNIQUE {
36				return fmt.Errorf("name %s already exists", name)
37			}
38			return fmt.Errorf("inserting smtp auth: %w", err)
39		}
40	}
41
42	return err
43}
44
45func (db *DB) GetSMTPAuthUser(ctx context.Context, name string) (model.SMTPAuth, error) {
46	res := db.read.QueryRowContext(
47		ctx, `SELECT id, name, password_hash FROM smtp_auth WHERE name = ?`, name)
48
49	var u model.SMTPAuth
50	var pw []byte
51	err := res.Scan(&u.ID, &u.Name, &pw)
52	if err != nil {
53		return model.SMTPAuth{}, err
54	}
55	u.SetPassword(pw)
56
57	return u, nil
58}
59
60func (db *DB) RemoveSMTPAuthUser(ctx context.Context, name string) error {
61	_, err := db.write.ExecContext(ctx, `DELETE FROM smtp_auth WHERE name = ?`, name)
62	return err
63}
64
65func (db *DB) ListSMTPAuthUsers(ctx context.Context) ([]model.SMTPAuth, error) {
66	rows, err := db.read.QueryContext(ctx, `SELECT id, name, password_hash FROM smtp_auth ORDER BY name`)
67	if err != nil {
68		return nil, err
69	}
70	defer func(rows *sql.Rows) {
71		_ = rows.Close()
72	}(rows)
73
74	var auths []model.SMTPAuth
75	for rows.Next() {
76		var u model.SMTPAuth
77		var pw []byte
78		if err := rows.Scan(&u.ID, &u.Name, &pw); err != nil {
79			return nil, err
80		}
81		u.SetPassword(pw)
82		auths = append(auths, u)
83	}
84
85	if err := rows.Err(); err != nil {
86		return nil, err
87	}
88
89	return auths, nil
90}