Example #1
0
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 := "Guest"

	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: "+user+"\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
}
Example #2
0
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
	}
}
Example #3
0
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)
}
Example #4
0
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)
}
Example #5
0
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)
}
Example #6
0
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)
}