8 5e70998a 2022-04-12 o _ "github.com/mattn/go-sqlite3"
11 5e70998a 2022-04-12 o // UserDB is an implementation of UserStore backed by a SQLite3 database.
12 5e70998a 2022-04-12 o // Users are fully authenticated after confirming ownership of their
13 5e70998a 2022-04-12 o // email address by supplying a matching ticket to a generated ticket file.
14 5e70998a 2022-04-12 o type UserDB struct {
16 5e70998a 2022-04-12 o TicketDir string
19 5e70998a 2022-04-12 o // OpenUserDB opens the named user database file and ticket directory.
20 5e70998a 2022-04-12 o func OpenUserDB(name, dir string) (*UserDB, error) {
21 5e70998a 2022-04-12 o db, err := sql.Open("sqlite3", name)
22 5e70998a 2022-04-12 o if err != nil {
23 5e70998a 2022-04-12 o return nil, err
25 5e70998a 2022-04-12 o return &UserDB{db, dir}, db.Ping()
28 5e70998a 2022-04-12 o func (db *UserDB) Lookup(name string) (User, error) {
30 5e70998a 2022-04-12 o row := db.QueryRow("SELECT username, password FROM users WHERE username = ?", name)
31 5e70998a 2022-04-12 o if err := row.Scan(&u.name, &u.password); err != nil {
32 5e70998a 2022-04-12 o if errors.Is(err, sql.ErrNoRows) {
33 5e70998a 2022-04-12 o return User{}, fmt.Errorf("lookup %s: %w", name, ErrUnknownUser)
35 5e70998a 2022-04-12 o return User{}, fmt.Errorf("lookup %s: %w", name, err)
40 5e70998a 2022-04-12 o func (db *UserDB) add(username string, pw Password) error {
41 5e70998a 2022-04-12 o _, err := db.Exec("INSERT INTO users (username, password) VALUES (?, ?)", username, pw)
42 5e70998a 2022-04-12 o if err != nil {
43 5e70998a 2022-04-12 o return fmt.Errorf("add %s: %w", username, err)
45 5e70998a 2022-04-12 o if err := createTicket(db.TicketDir, username, pw); err != nil {
46 5e70998a 2022-04-12 o return fmt.Errorf("add %s: create ticket: %w", username, err)
51 5e70998a 2022-04-12 o func (db *UserDB) Change(name string, new Password) error {
52 5e70998a 2022-04-12 o _, err := db.Lookup(name)
53 5e70998a 2022-04-12 o if errors.Is(err, ErrUnknownUser) {
54 5e70998a 2022-04-12 o return db.add(name, new)
56 5e70998a 2022-04-12 o if err != nil {
57 5e70998a 2022-04-12 o return fmt.Errorf("change %s: %w", name, err)
60 5e70998a 2022-04-12 o _, err = db.Exec("UPDATE users SET password = ? WHERE username = ?", new, name)
61 5e70998a 2022-04-12 o if err != nil {
62 5e70998a 2022-04-12 o return fmt.Errorf("change %s: %w", name, err)
67 5e70998a 2022-04-12 o func (db *UserDB) Delete(name string) error {
68 5e70998a 2022-04-12 o _, err := db.Lookup(name)
69 5e70998a 2022-04-12 o if err != nil {
70 5e70998a 2022-04-12 o return fmt.Errorf("delete %s: %w", name, err)
72 5e70998a 2022-04-12 o _, err = db.Exec("DELETE FROM users WHERE username = ?", name)
73 5e70998a 2022-04-12 o if err != nil {
74 5e70998a 2022-04-12 o return fmt.Errorf("delete %s: %w", name, err)