package users import ( "fmt" "net/http" "github.com/gorilla/mux" "github.com/mholt/binding" "gitlab.quimbo.fr/odwrtw/canape-sql/auth" "gitlab.quimbo.fr/odwrtw/canape-sql/web" ) // FormErrors map[field name]message type FormErrors map[string]string // HandleFormErrors translate binding.Erros to FormErrors func HandleFormErrors(errs binding.Errors) FormErrors { ferrs := FormErrors{} for _, err := range errs { for _, field := range err.FieldNames { if ferrs[field] == "" { ferrs[field] = err.Message } } } return ferrs } type loginForm struct { Username string Password string } func (f *loginForm) FieldMap(r *http.Request) binding.FieldMap { return binding.FieldMap{ &f.Username: "username", &f.Password: "password", } } func (f *loginForm) Validate(r *http.Request, errs binding.Errors) binding.Errors { if f.Username == "" { errs = append(errs, binding.Error{ FieldNames: []string{"username"}, Classification: "InvalidValues", Message: "Specify a username", }) } if f.Password == "" { errs = append(errs, binding.Error{ FieldNames: []string{"password"}, Classification: "InvalidValues", Message: "Specify a password", }) } return errs } func loginSubmitHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { form := new(loginForm) errs := binding.Bind(r, form) if errs != nil { formErrs := HandleFormErrors(errs) web.SetData(r, "FormErrors", formErrs) return e.Rends(w, r, "users/login") } err := e.Auth.Login(w, r, form.Username, form.Password) if err != nil { if err == auth.ErrInvalidPassword || err == ErrUnknownUser { web.SetData(r, "FormErrors", FormErrors{"password": "Invalid username or password"}) return e.Rends(w, r, "users/login") } return web.InternalError(err) } return nil } func userDetailsHandler(e *web.Env, w http.ResponseWriter, r *http.Request) error { u, err := e.Auth.CurrentUser(w, r) if err != nil { return err } if u == nil { return nil } _, ok := u.(*User) if !ok { return fmt.Errorf("Invalid user type") } return nil } // SetRoutes adds users routes to the router func SetRoutes(r *mux.Router, e *web.Env) { r.Handle("/login", e.Handler(loginSubmitHandler)).Methods("POST").Name("loginPost") r.Handle("/", e.Handler(userDetailsHandler)).Methods("GET").Name("UserDetails") }