func resetPassword(app *Application, answer *model.SecurityAnswer, token *model.Token, r *http.Request) error { ans := r.FormValue("answer") pass := r.FormValue("password") pass2 := r.FormValue("password2") if len(pass) < viper.GetInt("min_passwd_len") || len(pass2) < viper.GetInt("min_passwd_len") { return errors.New(fmt.Sprintf("Please set a password at least %d characters in length.", viper.GetInt("min_passwd_len"))) } if pass != pass2 { return errors.New("Password do not match. Please confirm your password.") } if utf8.RuneCountInString(ans) < 2 || utf8.RuneCountInString(ans) > 100 { return errors.New("Invalid answer. Must be between 2 and 100 characters long.") } err := bcrypt.CompareHashAndPassword([]byte(answer.Answer), []byte(ans)) if err != nil { return errors.New("The security answer you provided does not match. Please check that you are entering the correct answer.") } // Setup password in FreeIPA err = setPassword(token.UserName, "", pass) if err != nil { if ierr, ok := err.(*ipa.ErrPasswordPolicy); ok { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": ierr.Error(), }).Error("password does not conform to policy") return errors.New("Your password is too weak. Please ensure your password includes a number and lower/upper case character") } if ierr, ok := err.(*ipa.ErrInvalidPassword); ok { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": ierr.Error(), }).Error("invalid password from FreeIPA") return errors.New("Invalid password.") } logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err.Error(), }).Error("failed to set user password in FreeIPA") return errors.New("Fatal system error") } // Destroy token err = model.DestroyToken(app.db, token.Token) if err != nil { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err.Error(), }).Error("failed to remove token from database") return errors.New("Fatal system error") } return nil }
func setupAccount(app *Application, questions []*model.SecurityQuestion, token *model.Token, r *http.Request) error { qid := r.FormValue("qid") answer := r.FormValue("answer") pass := r.FormValue("password") pass2 := r.FormValue("password2") if len(pass) < viper.GetInt("min_passwd_len") || len(pass2) < viper.GetInt("min_passwd_len") { return errors.New(fmt.Sprintf("Please set a password at least %d characters in length.", viper.GetInt("min_passwd_len"))) } if pass != pass2 { return errors.New("Password do not match. Please confirm your password.") } if len(qid) == 0 || len(answer) == 0 { return errors.New("Please choose a security question and answer.") } if utf8.RuneCountInString(answer) < 2 || utf8.RuneCountInString(answer) > 100 { return errors.New("Invalid answer. Must be between 2 and 100 characters long.") } q, err := strconv.Atoi(qid) if err != nil { return errors.New("Invalid security question") } found := false for _, sq := range questions { if sq.Id == q { found = true break } } if found == false { return errors.New("Invalid security question") } hash, err := bcrypt.GenerateFromPassword([]byte(answer), bcrypt.DefaultCost) if err != nil { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err.Error(), }).Error("failed to generate bcrypt hash of answer") return errors.New("Fatal system error") } // Setup password in FreeIPA err = setPassword(token.UserName, "", pass) if err != nil { if ierr, ok := err.(*ipa.ErrPasswordPolicy); ok { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": ierr.Error(), }).Error("password does not conform to policy") return errors.New("Your password is too weak. Please ensure your password includes a number and lower/upper case character") } if ierr, ok := err.(*ipa.ErrInvalidPassword); ok { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": ierr.Error(), }).Error("invalid password from FreeIPA") return errors.New("Invalid password.") } logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err.Error(), }).Error("failed to set user password in FreeIPA") return errors.New("Fatal system error") } // Save security answer a := &model.SecurityAnswer{ UserName: token.UserName, QuestionId: q, Answer: string(hash)} err = model.StoreAnswer(app.db, a) if err != nil { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err.Error(), }).Error("failed to save answer to the database") return errors.New("Fatal system error") } // Destroy token err = model.DestroyToken(app.db, token.Token) if err != nil { logrus.WithFields(logrus.Fields{ "uid": token.UserName, "error": err.Error(), }).Error("failed to remove token from database") return errors.New("Fatal system error") } return nil }