From 2a966bf842fb05700387d663161300f488014bc0 Mon Sep 17 00:00:00 2001 From: vilmibm Date: Tue, 24 Oct 2023 05:15:04 +0000 Subject: [PATCH] ask db about users --- cmd/help/main.go | 54 +++++++++++++++++++++++++++++++++++++++++------- towndb/towndb.go | 23 +++++++++++++++++++++ 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/cmd/help/main.go b/cmd/help/main.go index dd47e24..05c4b1d 100644 --- a/cmd/help/main.go +++ b/cmd/help/main.go @@ -1,11 +1,15 @@ package main import ( + "database/sql" "fmt" "os" "strconv" + "strings" + "git.tilde.town/tildetown/town/towndb" "github.com/charmbracelet/lipgloss" + _ "github.com/mattn/go-sqlite3" "github.com/mattn/go-tty" ) @@ -83,6 +87,11 @@ func numberPrompt(cs colorScheme, tty *tty.TTY, prompt string, opts []string) (i } func _main() error { + db, err := towndb.ConnectDB() + if err != nil { + return fmt.Errorf("could not connect to database. please let root@tilde.town know about this.") + } + cs := newColorScheme() fmt.Println(cs.Header("Hi, you have reached the tilde town help desk.")) fmt.Println() @@ -101,29 +110,60 @@ func _main() error { } c, err := numberPrompt(cs, tty, "What do you need help with?", options) + defer func() { + fmt.Println() + fmt.Println(cs.Header("bye~")) + }() + switch c { case 0: - return collectEmail(cs, tty) + return collectEmail(db, cs, tty) case 1: return redeemCode(tty) case 2: - fmt.Println() - fmt.Println(cs.Header("bye~")) return nil } return nil } -func collectEmail(cs colorScheme, tty *tty.TTY) error { - fmt.Println(cs.Header("We can send a reset code to an email associated with your town account.")) +func collectEmail(db *sql.DB, cs colorScheme, tty *tty.TTY) error { + fmt.Println(cs.Header("We can send a authorization code to an email associated with your town account.")) email, err := stringPrompt(cs, tty, "email to send reset code to?") if err != nil { return err } - fmt.Println(email) - // TODO confirm email + fmt.Println() + fmt.Println(cs.Header("thanks!")) + fmt.Println() + fmt.Printf("If %s is associated with a town account we'll email an authorization code.\n", cs.Email(email)) + + mustHave := []string{"@", "."} + found := 0 + for _, s := range mustHave { + if strings.Contains(email, s) { + found++ + } + } + if found != len(mustHave) { + // TODO log + return nil + } + + user, err := towndb.UserForEmail(db, email) + if err != nil { + // TODO log + return err + } + + if user == nil { + // TODO log + return nil + } + + fmt.Println("found a user so gonna email") + // TODO generate reset code // TODO send email // TODO report success diff --git a/towndb/towndb.go b/towndb/towndb.go index 52d073a..2524303 100644 --- a/towndb/towndb.go +++ b/towndb/towndb.go @@ -2,6 +2,7 @@ package towndb import ( "database/sql" + "errors" "time" _ "github.com/mattn/go-sqlite3" @@ -142,6 +143,28 @@ func (u *TownUser) Insert(db *sql.DB) (err error) { return tx.Commit() } +// UserForEmail returns the user associated with an email or nil if no matching user is found +func UserForEmail(db *sql.DB, address string) (*TownUser, error) { + stmt, err := db.Prepare(` + SELECT u.id, u.username FROM users u + JOIN emails e ON e.userid = u.id + WHERE e.address = ? + `) + if err != nil { + return nil, err + } + row := stmt.QueryRow(address) + u := &TownUser{} + if err = row.Scan(u.ID, u.Username); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return nil, err + } + + return u, nil +} + func ConnectDB() (*sql.DB, error) { db, err := sql.Open("sqlite3", dsn) if err != nil {