all repos — auth-boilerplate @ d865cd0aaa53991ee5b84ad5f87d22305f3bafc2

A simple Go web-app boilerplate.

src/app/handlers.go (view raw)

  1package app
  2
  3import (
  4	"net/http"
  5	"time"
  6)
  7
  8func examplePage(w http.ResponseWriter, r *http.Request) {
  9	user, ok := getLoggedUser(r)
 10	if !ok {
 11		http.Error(w, "Could not find user in context.", http.StatusInternalServerError)
 12		return
 13	}
 14
 15	xt.ExecuteTemplate(w, "example.tmpl", map[string]interface{}{"User": user})
 16}
 17
 18func getRegisterHandler(w http.ResponseWriter, r *http.Request) {
 19	xt.ExecuteTemplate(w, "register.tmpl", nil)
 20}
 21
 22func getLoginHandler(w http.ResponseWriter, r *http.Request) {
 23	_, err := readSessionCookie(r)
 24	if err != nil {
 25		xt.ExecuteTemplate(w, "login.tmpl", nil)
 26		return
 27	}
 28	http.Redirect(w, r, "/", http.StatusFound)
 29}
 30
 31func getResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
 32	xt.ExecuteTemplate(w, "reset_password.tmpl", nil)
 33}
 34
 35func postRegisterHandler(w http.ResponseWriter, r *http.Request) {
 36	if !registrationEnabled {
 37		http.Error(w, "Registration is currently disabled.", http.StatusForbidden)
 38		return
 39	}
 40
 41	username, err := sanitizeUsername(r.FormValue("username"))
 42	if err != nil {
 43		http.Error(w, "Invalid username.", http.StatusBadRequest)
 44		return
 45	}
 46
 47	email, err := sanitizeEmail(r.FormValue("email"))
 48	if err != nil {
 49		http.Error(w, "Invalid email.", http.StatusBadRequest)
 50		return
 51	}
 52
 53	hashedPassword, salt, err := g.HashPassword(r.FormValue("password"))
 54	if err != nil {
 55		http.Error(w, "Invalid password.", http.StatusBadRequest)
 56		return
 57	}
 58
 59	user := User{
 60		Username:     username,
 61		Email:        email,
 62		PasswordHash: hashedPassword,
 63		Salt:         salt,
 64	}
 65
 66	db.Create(&user)
 67	if user.ID == 0 {
 68		http.Error(w, "Username or email already exists.", http.StatusConflict)
 69		return
 70	}
 71
 72	login(w, user.ID, false)
 73	http.Redirect(w, r, "/login", http.StatusFound)
 74}
 75
 76func postLoginHandler(w http.ResponseWriter, r *http.Request) {
 77	username := r.FormValue("username")
 78	password := r.FormValue("password")
 79	remember := r.FormValue("remember")
 80
 81	var user User
 82	db.Where("username = ?", username).First(&user)
 83
 84	if user.ID == 0 || !g.CheckPassword(password, user.Salt, user.PasswordHash) {
 85		http.Error(w, "Invalid credentials", http.StatusUnauthorized)
 86		return
 87	}
 88
 89	login(w, user.ID, remember == "on")
 90	http.Redirect(w, r, "/", http.StatusFound)
 91}
 92
 93func logoutHandler(w http.ResponseWriter, r *http.Request) {
 94	http.SetCookie(w, g.GenerateEmptyCookie())
 95	http.Redirect(w, r, "/login", http.StatusFound)
 96}
 97
 98func postResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
 99	emailInput := r.FormValue("email")
100
101	var user User
102	db.Where("email = ?", emailInput).First(&user)
103
104	if user.ID == 0 {
105		http.Redirect(w, r, "/login", http.StatusFound)
106		return
107	}
108
109	resetToken, err := g.GenerateRandomToken(32)
110	if err != nil {
111		http.Error(w, "Could not generate reset token.", http.StatusInternalServerError)
112		return
113	}
114
115	ks.Set(resetToken, user.ID, time.Hour)
116	sendResetEmail(user.Email, resetToken)
117
118	http.Redirect(w, r, "/login", http.StatusFound)
119
120}
121
122func getResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
123	token := r.URL.Query().Get("token")
124	_, err := ks.Get(token)
125	if err != nil {
126		http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)
127		return
128	}
129
130	xt.ExecuteTemplate(w, "new_password.tmpl", nil)
131}
132
133func postResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
134	token := r.URL.Query().Get("token")
135	userID, err := ks.Get(token)
136	if err != nil {
137		http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)
138		return
139	}
140
141	var user User
142	db.First(&user, *userID)
143
144	password := r.FormValue("password")
145
146	hashedPassword, salt, err := g.HashPassword(password)
147	if err != nil {
148		http.Error(w, "Invalid password.", http.StatusBadRequest)
149		return
150	}
151
152	user.PasswordHash = hashedPassword
153	user.Salt = salt
154	db.Save(&user)
155	ks.Delete(token)
156
157	http.Redirect(w, r, "/login", http.StatusFound)
158}