Newer
Older
func (h Handler) userCreate(w http.ResponseWriter, r *http.Request) (string, error) {
name := r.PostForm.Get("new-user")
if name == "" {
return "", errors.New("name can't be empty")
}
if len(name) > 80 {
return "", fmt.Errorf("user name too long %q", name)
}
generatedPassword, err := h.up.CreateUser(r.Context(), name)
if err != nil {
return "", err
}
return generatedPassword, nil
}
type pageName string
const (
pageYou pageName = "you"
pageAllUsers pageName = "all-users"
pageSessions pageName = "sessions"
)
func (h Handler) user(page pageName) http.Handler {
var (
once sync.Once
tpl *template.Template
)
type templateData struct {
FormErrors map[string]error
Success bool
ShowResult bool
GeneratedPassword string // For new users
CreatedUser string // Name for new users
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
once.Do(func() {
tpl = template.Must(template.ParseFS(templateFS, "templates/base.tpl", "templates/user.tpl"))
})
User: user,
FormErrors: make(map[string]error),
}
// If set to true, we don't render the template at function exit
var skipRender bool
data.AllUsers, err = h.up.ListUsers(r.Context())
httpError(w, r, "can't get list of all users", nil, http.StatusInternalServerError)
data.AllSessions, err = h.sp.ListSessions(r.Context())
httpError(w, r, "can't get list of sessions", err, http.StatusInternalServerError)
Log("error", err,
"msg", "can't execute details template")
if r.Method == "GET" {
// No need to do anything here, users and sessions will be loaded by deferred func.
// That will also take care of rendering things.
httpError(w, r, "bad method", errors.New(r.Method), http.StatusMethodNotAllowed)
return
}
err := r.ParseForm()
if err != nil {
httpError(w, r, "can't parse POST form", err, http.StatusInternalServerError)
switch r.PostForm.Get("action") {
case "update":
data.ShowResult = true
case "create":
generatedPw, err := h.userCreate(w, r)
if err != nil {
data.FormErrors["NewUser"] = err
}
data.GeneratedPassword = generatedPw
data.CreatedUser = r.PostForm.Get("new-user")
return
case "delete":
err := h.up.DeleteUser(r.Context(), r.PostForm.Get("username"))
if err != nil {
data.FormErrors["DeleteUser"] = err
}
return
case "logout":
cookie, err := r.Cookie("session")
if err != nil {
// We shouldn't end up here: if we do, someone managed to bypass the authentication
// middleware.
Log("error", err,
"msg", "can't get session token: possible auth bypass")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
err = h.sp.DeleteSession(r.Context(), cookie.Value)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/", http.StatusFound)
httpError(w, r, "unknown action", nil, http.StatusBadRequest)
if r.PostForm.Get("new-pw") != r.PostForm.Get("new-pw-repeat") {
data.FormErrors["NewPW"] = errors.New("new passwords don't match")
return
if len(r.PostForm.Get("new-pw")) == 0 {
data.FormErrors["NewPW"] = errors.New("new password can't be empty")
return
}
err = h.up.UpdatePassword(r.Context(), user.Name, r.PostForm.Get("old-pw"), r.PostForm.Get("new-pw"))
data.FormErrors["OldPW"] = err
return