From 5cef17441a94167aedc729628f0e7122ec3edccb Mon Sep 17 00:00:00 2001 From: René 'Necoro' Neumann Date: Tue, 13 Feb 2024 20:44:56 +0100 Subject: login handling --- main.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'main.go') diff --git a/main.go b/main.go index f97c639..863e1ff 100644 --- a/main.go +++ b/main.go @@ -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) } -- cgit v1.2.3-70-g09d2