func ResetPasswordHandler(app *Application) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { tk, ok := model.VerifyToken(RESET_SALT, mux.Vars(r)["token"]) if !ok { w.WriteHeader(http.StatusNotFound) renderTemplate(w, app.templates["404.html"], nil) return } token, err := model.FetchToken(app.db, tk, viper.GetInt("reset_max_age")) if err != nil { logrus.WithFields(logrus.Fields{ "error": err.Error(), }).Error("Failed to fetch token from database") w.WriteHeader(http.StatusNotFound) renderTemplate(w, app.templates["404.html"], nil) return } if token.Attempts > viper.GetInt("max_attempts") { logrus.WithFields(logrus.Fields{ "token": token.Token, "uid": token.UserName, }).Error("Too many attempts for token.") w.WriteHeader(http.StatusNotFound) renderTemplate(w, app.templates["404.html"], nil) return } answer, err := model.FetchAnswer(app.db, token.UserName) if err != nil { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err, }).Error("Failed to fetch security answer") w.WriteHeader(http.StatusNotFound) renderTemplate(w, app.templates["404.html"], nil) return } message := "" completed := false if r.Method == "POST" { err := resetPassword(app, answer, token, r) if err != nil { message = err.Error() completed = false err := model.IncrementToken(app.db, token.Token) if err != nil { logrus.WithFields(logrus.Fields{ "error": err.Error(), }).Error("Failed to increment token attempts") } } else { completed = true err = app.SendEmail(token.Email, fmt.Sprintf("[%s] Your password change confirmation", viper.GetString("email_prefix")), "reset-password-confirm.txt", nil) if err != nil { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err, }).Error("failed to send reset confirmation email to user") } } } vars := map[string]interface{}{ "token": nosurf.Token(r), "uid": token.UserName, "completed": completed, "question": answer.Question, "message": message} renderTemplate(w, app.templates["reset-password.html"], vars) }) }
func SetupAccountHandler(app *Application) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { tk, ok := model.VerifyToken(ACCOUNT_SETUP_SALT, mux.Vars(r)["token"]) if !ok { w.WriteHeader(http.StatusNotFound) renderTemplate(w, app.templates["404.html"], nil) return } token, err := model.FetchToken(app.db, tk, viper.GetInt("setup_max_age")) if err != nil { logrus.WithFields(logrus.Fields{ "error": err.Error(), }).Error("Failed to fetch token from database") w.WriteHeader(http.StatusNotFound) renderTemplate(w, app.templates["404.html"], nil) return } if token.Attempts > viper.GetInt("max_attempts") { logrus.WithFields(logrus.Fields{ "token": token.Token, "uid": token.UserName, }).Error("Too many attempts for token.") w.WriteHeader(http.StatusNotFound) renderTemplate(w, app.templates["404.html"], nil) return } questions, err := model.FetchQuestions(app.db) if err != nil { logrus.WithFields(logrus.Fields{ "error": err.Error(), }).Error("Failed to fetch questions from database") errorHandler(app, w, http.StatusInternalServerError) return } message := "" completed := false if r.Method == "POST" { err := setupAccount(app, questions, token, r) if err != nil { message = err.Error() completed = false err := model.IncrementToken(app.db, token.Token) if err != nil { logrus.WithFields(logrus.Fields{ "error": err.Error(), }).Error("Failed to increment token attempts") } } else { completed = true err = app.SendEmail(token.Email, fmt.Sprintf("[%s] Your account confirmation", viper.GetString("email_prefix")), "setup-account-confirm.txt", nil) if err != nil { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err, }).Error("failed to send setup confirmation email to user") } } } vars := map[string]interface{}{ "token": nosurf.Token(r), "uid": token.UserName, "completed": completed, "questions": questions, "message": message} renderTemplate(w, app.templates["setup-account.html"], vars) }) }