func ContactPOST(w http.ResponseWriter, r *http.Request) { // Get session sess := session.Instance(r) // Validate with required fields if validate, missingField := view.Validate(r, []string{"email", "fullname", "message"}); !validate { sess.AddFlash(view.Flash{"Field missing: " + missingField, view.FlashError}) sess.Save(r, w) ContactGET(w, r) return } // Validate with Google reCAPTCHA if !recaptcha.Verified(r) { sess.AddFlash(view.Flash{"reCAPTCHA invalid!", view.FlashError}) sess.Save(r, w) ContactGET(w, r) return } // Form values email := r.FormValue("email") name := r.FormValue("fullname") message := r.FormValue("message") ip, err := model.GetRemoteIP(r) if err != nil { log.Println(err) } user := "******" if sess.Values["id"] != nil { user = fmt.Sprintf("Registered (%v)", sess.Values["id"]) } // Email the hash to the user err = emailer.SendEmail(emailer.ReadConfig().From, "Contact Submission for Verified.ninja", "From: "+ name+" <"+email+">\nUser: "******"\nIP: "+ip+"\nMessage: "+message) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) ContactGET(w, r) return } // Post successful sess.AddFlash(view.Flash{"Thanks for the message! We'll get back to you in a bit.", view.FlashSuccess}) sess.Save(r, w) http.Redirect(w, r, "/", http.StatusFound) return }
func UserPasswordPOST(w http.ResponseWriter, r *http.Request) { // Get session sess := session.Instance(r) // Validate with required fields if validate, missingField := view.Validate(r, []string{"passwordold", "passwordnew"}); !validate { sess.AddFlash(view.Flash{"Field missing: " + missingField, view.FlashError}) sess.Save(r, w) UserPasswordGET(w, r) return } user_id := int64(sess.Values["id"].(uint32)) // Form values passwordOld := r.FormValue("passwordold") passwordNew, errp := passhash.HashString(r.FormValue("passwordnew")) if passwordOld == r.FormValue("passwordnew") { sess.AddFlash(view.Flash{"New password cannot be the same as the old password.", view.FlashError}) sess.Save(r, w) UserPasswordGET(w, r) return } // If password hashing failed if errp != nil { log.Println(errp) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserPasswordGET(w, r) return } // Get database result result, err := model.UserByEmail(fmt.Sprintf("%v", sess.Values["email"])) // Determine if user exists if err == sql.ErrNoRows { sess.AddFlash(view.Flash{"Password is incorrect.", view.FlashWarning}) sess.Save(r, w) UserPasswordGET(w, r) return } else if err != nil { // Display error message log.Println(err) sess.AddFlash(view.Flash{"There was an error. Please try again later.", view.FlashError}) sess.Save(r, w) UserPasswordGET(w, r) return } else if passhash.MatchString(result.Password, passwordOld) { err = model.UserPasswordUpdate(user_id, passwordNew) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"There was an error. Please try again later.", view.FlashError}) sess.Save(r, w) UserPasswordGET(w, r) return } // Password matches sess.AddFlash(view.Flash{"Password changed!", view.FlashSuccess}) sess.Save(r, w) http.Redirect(w, r, "/", http.StatusFound) return } else { sess.AddFlash(view.Flash{"Password is incorrect.", view.FlashWarning}) sess.Save(r, w) UserPasswordGET(w, r) return } }
func UserEmailPOST(w http.ResponseWriter, r *http.Request) { // Get session sess := session.Instance(r) user_id := int64(sess.Values["id"].(uint32)) if !isVerifiedEmail(r, user_id) { sess.AddFlash(view.Flash{"You can't change you email again until you verify your current email.", view.FlashError}) sess.Save(r, w) http.Redirect(w, r, "/", http.StatusFound) } // Validate with required fields if validate, missingField := view.Validate(r, []string{"email"}); !validate { sess.AddFlash(view.Flash{"Field missing: " + missingField, view.FlashError}) sess.Save(r, w) UserEmailGET(w, r) return } // Validate with Google reCAPTCHA if !recaptcha.Verified(r) { sess.AddFlash(view.Flash{"reCAPTCHA invalid!", view.FlashError}) sess.Save(r, w) UserEmailGET(w, r) return } // Form values email := r.FormValue("email") emailOld := sess.Values["email"] if email == emailOld { sess.AddFlash(view.Flash{"New email cannot be the same as the old email.", view.FlashError}) sess.Save(r, w) UserEmailGET(w, r) return } // Get database result err := model.UserEmailUpdate(user_id, email) if err != nil { if strings.Contains(err.Error(), "Duplicate entry") { sess.AddFlash(view.Flash{"That email already exists in the database. Please use a different one.", view.FlashError}) } else { // Display error message log.Println(err) sess.AddFlash(view.Flash{"There was an error. Please try again later.", view.FlashError}) } sess.Save(r, w) UserEmailGET(w, r) return } first_name := fmt.Sprintf("%v", sess.Values["first_name"]) // Create the email verification string md := random.Generate(32) // Add the hash to the database err = model.UserEmailVerificationCreate(user_id, md) if err != nil { log.Println(err) } err = model.UserReverify(user_id) if err != nil { log.Println(err) } c := view.ReadConfig() // Email the hash to the user err = emailer.SendEmail(email, "Email Verification for Verified.ninja", "Hi "+first_name+",\n\nTo verify your email address ("+email+"), please click here: "+c.BaseURI+"emailverification/"+md) if err != nil { log.Println(err) } // Login successfully sess.AddFlash(view.Flash{"Email updated! You must verify your email before you can login again.", view.FlashSuccess}) sess.Values["email"] = email sess.Save(r, w) http.Redirect(w, r, "/", http.StatusFound) }
func UserInformationPOST(w http.ResponseWriter, r *http.Request) { // Get session sess := session.Instance(r) // Validate with required fields if validate, missingField := view.Validate(r, []string{"birth_month", "birth_day", "birth_year", "gender", "height_feet", "height_inches", "ethnicity"}); !validate { sess.AddFlash(view.Flash{"Field missing: " + missingField, view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } user_id := uint64(sess.Values["id"].(uint32)) d := model.Demographic{} // Get form values bm, err := strconv.Atoi(r.FormValue("birth_month")) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } bd, _ := strconv.Atoi(r.FormValue("birth_day")) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } by, _ := strconv.Atoi(r.FormValue("birth_year")) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } d.Birth_month = uint8(bm) d.Birth_day = uint8(bd) d.Birth_year = uint16(by) d.Gender = r.FormValue("gender") hf, _ := strconv.Atoi(r.FormValue("height_feet")) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } d.Height_feet = uint8(hf) hi, _ := strconv.Atoi(r.FormValue("height_inches")) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } d.Height_inches = uint8(hi) we, _ := strconv.Atoi(r.FormValue("weight")) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } d.Weight = uint16(we) err = model.DemographicAdd(user_id, d) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } err = model.EthnicityAdd(user_id, r.Form["ethnicity"]) if err != nil { log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) UserInformationGET(w, r) return } sess.AddFlash(view.Flash{"Settings saved.", view.FlashSuccess}) sess.Save(r, w) http.Redirect(w, r, "/", http.StatusFound) }
func RegisterPOST(w http.ResponseWriter, r *http.Request) { // Get session sess := session.Instance(r) // Prevent brute force login attempts by not hitting MySQL and pretending like it was invalid :-) if sess.Values["register_attempt"] != nil && sess.Values["register_attempt"].(int) >= 5 { log.Println("Brute force register prevented") http.Redirect(w, r, "/register", http.StatusFound) return } // Validate with required fields if validate, missingField := view.Validate(r, []string{"first_name", "last_name", "email", "password"}); !validate { sess.AddFlash(view.Flash{"Field missing: " + missingField, view.FlashError}) sess.Save(r, w) RegisterGET(w, r) return } // Validate with Google reCAPTCHA if !recaptcha.Verified(r) { sess.AddFlash(view.Flash{"reCAPTCHA invalid!", view.FlashError}) sess.Save(r, w) RegisterGET(w, r) return } // Get form values first_name := r.FormValue("first_name") last_name := r.FormValue("last_name") email := r.FormValue("email") password, errp := passhash.HashString(r.FormValue("password")) // If password hashing failed if errp != nil { log.Println(errp) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) http.Redirect(w, r, "/register", http.StatusFound) return } // Get database result _, err := model.UserIdByEmail(email) if err == sql.ErrNoRows { // If success (no user exists with that email) result, ex := model.UserCreate(first_name, last_name, email, password) // Will only error if there is a problem with the query if ex != nil { log.Println(ex) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) } else { // Create the email verification string md := random.Generate(32) // Get the user ID user_id, _ := result.LastInsertId() // Add the user role model.RoleCreate(user_id, model.Role_level_User) // Add the hash to the database model.UserEmailVerificationCreate(user_id, md) c := view.ReadConfig() // Email the hash to the user err := emailer.SendEmail(email, "Email Verification for Verified.ninja", "Hi "+first_name+",\n\nTo verify your email address, please click here: "+c.BaseURI+"emailverification/"+md) if err != nil { log.Println(err) } // TODO This is just temporary for testing log.Println("Email Verification Link:", c.BaseURI+"emailverification/"+md) po, err := pushover.New() if err == pushover.ErrPushoverDisabled { // Nothing } else if err != nil { log.Println(err) } else { err = po.Message(first_name + " " + last_name + "(" + fmt.Sprintf("%v", user_id) + ") created an account. You can view the account here:\nhttps://verified.ninja/admin/user/" + fmt.Sprintf("%v", user_id)) if err != nil { log.Println(err) } } sess.AddFlash(view.Flash{"Account created successfully for: " + email + ". Please click the verification link in your email.", view.FlashSuccess}) sess.Save(r, w) http.Redirect(w, r, "/login", http.StatusFound) return } } else if err != nil { // Catch all other errors log.Println(err) sess.AddFlash(view.Flash{"An error occurred on the server. Please try again later.", view.FlashError}) sess.Save(r, w) } else { // Else the user already exists sess.AddFlash(view.Flash{"Account already exists for: " + email, view.FlashError}) sess.Save(r, w) } // Display the page RegisterGET(w, r) }
func LoginPOST(w http.ResponseWriter, r *http.Request) { // Get session sess := session.Instance(r) // Prevent brute force login attempts by not hitting MySQL and pretending like it was invalid :-) if sess.Values["login_attempt"] != nil && sess.Values["login_attempt"].(int) >= 5 { log.Println("Brute force login prevented") sess.AddFlash(view.Flash{"Sorry, no brute force :-)", view.FlashNotice}) sess.Save(r, w) LoginGET(w, r) return } // Validate with required fields if validate, missingField := view.Validate(r, []string{"email", "password"}); !validate { sess.AddFlash(view.Flash{"Field missing: " + missingField, view.FlashError}) sess.Save(r, w) LoginGET(w, r) return } // Validate with Google reCAPTCHA if !recaptcha.Verified(r) { sess.AddFlash(view.Flash{"reCAPTCHA invalid!", view.FlashError}) sess.Save(r, w) LoginGET(w, r) return } // Form values email := r.FormValue("email") password := r.FormValue("password") // Get database result result, err := model.UserByEmail(email) // Determine if user exists if err == sql.ErrNoRows { loginAttempt(sess) sess.AddFlash(view.Flash{"Password is incorrect - Attempt: " + fmt.Sprintf("%v", sess.Values["login_attempt"]), view.FlashWarning}) sess.Save(r, w) } else if err != nil { // Display error message log.Println(err) sess.AddFlash(view.Flash{"There was an error. Please try again later.", view.FlashError}) sess.Save(r, w) } else if passhash.MatchString(result.Password, password) { if result.Status_id == 2 { // User inactive and display inactive message sess.AddFlash(view.Flash{"Account is inactive so login is disabled.", view.FlashNotice}) sess.Save(r, w) } else if result.Status_id == 3 { // User email not verified sess.AddFlash(view.Flash{"You must confirm your email before login is allowed.", view.FlashWarning}) sess.Save(r, w) } else if result.Status_id == 4 { // User email not re-verified sess.AddFlash(view.Flash{"You must re-confirm your email before login is allowed.", view.FlashWarning}) sess.Save(r, w) } else if result.Status_id == 1 { // Log the login err = model.UserLoginCreate(int64(result.Id), r) if err != nil { log.Println(err) } // Login successfully clearSessionVariables(sess) sess.AddFlash(view.Flash{"Login successful!", view.FlashSuccess}) sess.Values["id"] = result.Id sess.Values["email"] = email sess.Values["first_name"] = result.First_name sess.Values["last_name"] = result.Last_name sess.Save(r, w) http.Redirect(w, r, "/", http.StatusFound) return } else { // User status unknown sess.AddFlash(view.Flash{"Account status is unknown so login is disabled.", view.FlashNotice}) sess.Save(r, w) } } else { loginAttempt(sess) sess.AddFlash(view.Flash{"Password is incorrect - Attempt: " + fmt.Sprintf("%v", sess.Values["login_attempt"]), view.FlashWarning}) sess.Save(r, w) } // Show the login page again LoginGET(w, r) }