all repos — postern @ fc287763b9ce6b6f9823e11c0b1173da0446ebc5

Modern mail management

internal/db/address.go (view raw)

 1package db
 2
 3import (
 4	"context"
 5	"database/sql"
 6	"errors"
 7	"time"
 8
 9	"postern/internal/model"
10)
11
12func (db *DB) InsertUserAddress(ctx context.Context, username, address string) error {
13	tx, err := db.write.BeginTx(ctx, nil)
14	if err != nil {
15		return err
16	}
17	defer txRollback(tx)
18
19	// Get userID
20	var userID int
21	row := tx.QueryRowContext(ctx, `SELECT id FROM users WHERE name = ?`, username)
22	if err = row.Scan(&userID); err != nil {
23		if errors.Is(err, sql.ErrNoRows) {
24			return errors.New("user not found")
25		}
26		return err
27	}
28
29	// Insert address
30	_, err = tx.ExecContext(ctx, `INSERT INTO addresses (user_id, name, created_at) VALUES (?, ?, ?)`, userID, address, time.Now().Unix())
31	if err != nil {
32		return err
33	}
34	return tx.Commit()
35}
36
37func (db *DB) GetUserForAddress(ctx context.Context, address string) (model.User, error) {
38	res := db.read.QueryRowContext(ctx, `SELECT users.id, users.name, users.password_hash FROM users INNER JOIN addresses ON users.id = addresses.user_id WHERE addresses.name = ?`, address)
39
40	var u model.User
41	var pw []byte
42	err := res.Scan(&u.ID, &u.Name, &pw)
43	u.SetPassword(pw)
44	return u, err
45}
46
47func (db *DB) GetGatekeepDecision(ctx context.Context, userID int, fromAddress string) (string, error) {
48	res := db.read.QueryRowContext(ctx, `SELECT destination FROM gatekeepers WHERE from_address = ? and user_id = ?`, fromAddress, userID)
49
50	var mailbox string
51	err := res.Scan(&mailbox)
52	if err != nil {
53		return "", err
54	}
55
56	return mailbox, nil
57}