all repos — auth-boilerplate @ main

A simple Go web-app boilerplate.

src/app/handlers.go (view raw)

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