Example #1
0
func ResetPasswordEmail(uid string) {
	db, err := NewDb()
	if err != nil {
		logrus.Fatal(err.Error())
	}

	_, err = model.FetchAnswer(db, uid)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"uid":   uid,
			"error": err,
		}).Error("Failed to fetch security answer. Please run newacct to setup user account.")
		return
	}

	token, err := createToken(uid)
	if err != nil {
		logrus.Fatal(err.Error())
	}

	app, err := NewApplication()
	if err != nil {
		logrus.Fatal(err.Error())
	}

	vars := map[string]interface{}{
		"link": fmt.Sprintf("%s/auth/resetpw/%s", viper.GetString("email_link_base"), model.SignToken(RESET_SALT, token.Token))}

	err = app.SendEmail(token.Email, fmt.Sprintf("[%s] Please reset your password", viper.GetString("email_prefix")), "reset-password.txt", vars)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"uid":   uid,
			"error": err,
		}).Error("failed send email to user")
	}
}
Example #2
0
func forgotPassword(app *Application, r *http.Request) error {
	uid := r.FormValue("uid")
	if len(uid) == 0 {
		return errors.New("Please provide a user name.")
	}

	_, err := model.FetchTokenByUser(app.db, uid, viper.GetInt("setup_max_age"))
	if err == nil {
		logrus.WithFields(logrus.Fields{
			"uid": uid,
		}).Error("Forgotpw: user already has active token")
		return nil
	}

	client := NewIpaClient(true)
	userRec, err := client.UserShow(uid)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"uid":   uid,
			"error": err,
		}).Error("Forgotpw: invalid uid")
		return nil
	}

	if len(userRec.Email) == 0 {
		logrus.WithFields(logrus.Fields{
			"uid": uid,
		}).Error("Forgotpw: missing email address")
		return nil
	}

	_, err = model.FetchAnswer(app.db, uid)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"uid":   uid,
			"error": err,
		}).Error("Forgotpw: Failed to fetch security answer")
		return nil
	}

	token, err := model.NewToken(app.db, uid, string(userRec.Email))
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"uid":   uid,
			"error": err,
		}).Error("Forgotpw: Failed to create token")
		return nil
	}

	vars := map[string]interface{}{
		"link": fmt.Sprintf("%s/auth/resetpw/%s", viper.GetString("email_link_base"), model.SignToken(RESET_SALT, token.Token))}

	err = app.SendEmail(token.Email, fmt.Sprintf("[%s] Please reset your password", viper.GetString("email_prefix")), "reset-password.txt", vars)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"uid":   uid,
			"error": err,
		}).Error("Forgotpw: failed send email to user")
	}

	return nil
}
Example #3
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)
	})
}