Exemplo n.º 1
0
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)
	})
}
Exemplo n.º 2
0
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)
	})
}