package handlers import ( "fmt" "net/http" "strings" "veola/internal/auth" "veola/internal/models" "veola/templates" ) func (a *App) renderSettingsWithUserMsg(w http.ResponseWriter, r *http.Request, msg, errMsg string) { d, err := a.settingsData(r) if err != nil { a.serverError(w, r, err) return } d.UserMsg = msg d.UserError = errMsg render(w, r, templates.Settings(d)) } func (a *App) PostCreateUser(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "bad form", http.StatusBadRequest) return } username := strings.TrimSpace(r.PostFormValue("username")) password := r.PostFormValue("password") role := strings.TrimSpace(r.PostFormValue("role")) if role != string(models.RoleAdmin) { role = string(models.RoleUser) } switch { case username == "": a.renderSettingsWithUserMsg(w, r, "", "Username is required") return case len(password) < auth.MinPasswordLen: a.renderSettingsWithUserMsg(w, r, "", fmt.Sprintf("Password must be at least %d characters", auth.MinPasswordLen)) return } existing, _ := a.Store.GetUserByUsername(r.Context(), username) if existing != nil { a.renderSettingsWithUserMsg(w, r, "", "User already exists") return } hash, err := auth.HashPassword(password) if err != nil { a.renderSettingsWithUserMsg(w, r, "", "hash error") return } if _, err := a.Store.CreateUser(r.Context(), username, hash, models.Role(role)); err != nil { a.renderSettingsWithUserMsg(w, r, "", err.Error()) return } a.renderSettingsWithUserMsg(w, r, "Created user "+username, "") } func (a *App) PostDeleteUser(w http.ResponseWriter, r *http.Request) { id := intParam(r, "id") cur := auth.CurrentUserFromRequest(r) if cur != nil && cur.ID == id { a.renderSettingsWithUserMsg(w, r, "", "You cannot delete your own account") return } if err := a.Store.DeleteUser(r.Context(), id); err != nil { a.renderSettingsWithUserMsg(w, r, "", err.Error()) return } a.renderSettingsWithUserMsg(w, r, "User removed", "") } func (a *App) PostResetPassword(w http.ResponseWriter, r *http.Request) { id := intParam(r, "id") if err := r.ParseForm(); err != nil { http.Error(w, "bad form", http.StatusBadRequest) return } next := r.PostFormValue("new_password") if len(next) < auth.MinPasswordLen { a.renderSettingsWithUserMsg(w, r, "", fmt.Sprintf("Password must be at least %d characters", auth.MinPasswordLen)) return } u, err := a.Store.GetUserByID(r.Context(), id) if err != nil || u == nil { a.renderSettingsWithUserMsg(w, r, "", "User not found") return } hash, err := auth.HashPassword(next) if err != nil { a.renderSettingsWithUserMsg(w, r, "", "hash error") return } if err := a.Store.UpdateUserPassword(r.Context(), id, hash); err != nil { a.renderSettingsWithUserMsg(w, r, "", err.Error()) return } a.renderSettingsWithUserMsg(w, r, "Password reset for "+u.Username, "") }