canape/users/handlers.go

101 lines
2.3 KiB
Go

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")
}