diff options
Diffstat (limited to '')
-rw-r--r-- | main.go | 53 |
1 files changed, 48 insertions, 5 deletions
@@ -2,7 +2,9 @@ package main import ( "database/sql" + "errors" "flag" + "fmt" "log" "net" "net/http" @@ -11,6 +13,7 @@ import ( "github.com/gorilla/handlers" "github.com/gorilla/schema" + "golang.org/x/crypto/bcrypt" "gosten/model" "gosten/templ" @@ -56,8 +59,22 @@ func main() { } type User struct { - Name string `form:"options=required"` - Password string `form:"type=password;options=required"` + Name string `form:"options=required"` + Password string `form:"type=password;options=required"` + Errors []error `form:"-"` +} + +type fieldError struct { + Field string + Issue string +} + +func (fe fieldError) Error() string { + return fmt.Sprintf("%s: %v", fe.Field, fe.Issue) +} + +func (fe fieldError) FieldError() (field, err string) { + return fe.Field, fe.Issue } func showTemplate(tpl string, data any) http.HandlerFunc { @@ -68,14 +85,40 @@ func showTemplate(tpl string, data any) http.HandlerFunc { } } -func handleLogin(w http.ResponseWriter, r *http.Request) { - u := User{} +func parseForm[T any](r *http.Request, data *T) { if err := r.ParseForm(); err != nil { log.Panic("Parsing form: ", err) } - if err := s.Decode(&u, r.PostForm); err != nil { + if err := s.Decode(data, r.PostForm); err != nil { log.Panic("Decoding form: ", err) } +} + +func handleLogin(w http.ResponseWriter, r *http.Request) { + u := User{} + parseForm(r, &u) + + invalid := false + + dbUser, err := Q.GetUserByName(r.Context(), u.Name) + if err == nil { + hash := []byte(dbUser.Pwd) + pwd := []byte(u.Password) + + if bcrypt.CompareHashAndPassword(hash, pwd) != nil { + invalid = true + } + } else if errors.Is(err, sql.ErrNoRows) { + invalid = true + } else { + log.Panicf("Could not load user '%s': %v", u.Name, err) + } + + if invalid { + u.Errors = []error{fieldError{"Password", "Invalid"}} + showTemplate("login", u).ServeHTTP(w, r) + return + } showTemplate("login2", u).ServeHTTP(w, r) } |