func RegisterPOST(w http.ResponseWriter, r *http.Request) { // Get session sess := session.Instance(r) // If user is authenticated if sess.Values["id"] != nil { http.Redirect(w, r, "/", http.StatusFound) return } // 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 } // 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 db, _ := mysql.Instance() defer db.Link.Close() result := database.User{} err := db.Link.Get(&result, "SELECT id FROM user WHERE email = ? LIMIT 1", email) if err == sql.ErrNoRows { // If success (no user exists with that email) _, ex := db.Link.Exec("INSERT INTO user (first_name, last_name, email, password) VALUES (?,?,?,?)", 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 { sess.AddFlash(view.Flash{"Account created successfully for: " + 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) // If user is authenticated if sess.Values["id"] != nil { http.Redirect(w, r, "/", http.StatusFound) return } // 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 } // Form values email := r.FormValue("email") password := r.FormValue("password") // Get database result db, _ := mysql.Instance() defer db.Link.Close() result := database.User{} err := db.Link.Get(&result, "SELECT id, password, status_id, first_name FROM user WHERE email = ? LIMIT 1", email) // Determine if password is correct if err == sql.ErrNoRows { // Log the attempt if sess.Values["login_attempt"] == nil { sess.Values["login_attempt"] = 1 } else { sess.Values["login_attempt"] = sess.Values["login_attempt"].(int) + 1 } 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 != 1 { // User inactive and display inactive message sess.AddFlash(view.Flash{"Account is inactive so login is disabled.", view.FlashNotice}) sess.Save(r, w) } else { // Login successfully // Clear out all stored values in the cookie for k := range sess.Values { delete(sess.Values, k) } sess.AddFlash(view.Flash{"Login successful!", view.FlashSuccess}) sess.Values["id"] = result.Id sess.Values["email"] = email sess.Values["first_name"] = result.First_name err := sess.Save(r, w) if err != nil { log.Println(err) } http.Redirect(w, r, "/", http.StatusFound) return } } else { // Log the attempt if sess.Values["login_attempt"] == nil { sess.Values["login_attempt"] = 1 } else { sess.Values["login_attempt"] = sess.Values["login_attempt"].(int) + 1 } 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) }