all repos — auth-boilerplate @ e32a2dfeddcff5b2677fdffb65af0a78b614f797

A simple Go web-app boilerplate.

handlers.go (view raw)

  1package main
  2
  3import (
  4	"fmt"
  5	"log"
  6	"net/http"
  7	"time"
  8
  9	"github.com/birabittoh/auth-boilerplate/email"
 10)
 11
 12func examplePage(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	templates.ExecuteTemplate(w, "example.html", map[string]interface{}{"User": user})
 20}
 21
 22func getRegisterHandler(w http.ResponseWriter, r *http.Request) {
 23	templates.ExecuteTemplate(w, "register.html", nil)
 24}
 25
 26func getLoginHandler(w http.ResponseWriter, r *http.Request) {
 27	templates.ExecuteTemplate(w, "login.html", nil)
 28}
 29
 30func getResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
 31	templates.ExecuteTemplate(w, "reset_password.html", nil)
 32}
 33
 34func postRegisterHandler(w http.ResponseWriter, r *http.Request) {
 35	username := r.FormValue("username")
 36	email := r.FormValue("email")
 37	password := r.FormValue("password")
 38
 39	hashedPassword, salt, err := g.HashPassword(password)
 40	if err != nil {
 41		http.Error(w, "Could not hash your password.", http.StatusInternalServerError)
 42		return
 43	}
 44
 45	user := User{
 46		Username:     username,
 47		Email:        email,
 48		PasswordHash: hashedPassword,
 49		Salt:         salt,
 50	}
 51	db.Create(&user)
 52	http.Redirect(w, r, "/login", http.StatusFound)
 53	return
 54}
 55
 56func postLoginHandler(w http.ResponseWriter, r *http.Request) {
 57	username := r.FormValue("username")
 58	password := r.FormValue("password")
 59	remember := r.FormValue("remember")
 60
 61	var user User
 62	db.Where("username = ?", username).First(&user)
 63
 64	if user.ID == 0 || !g.CheckPassword(password, user.Salt, user.PasswordHash) {
 65		http.Error(w, "Invalid credentials", http.StatusUnauthorized)
 66		return
 67	}
 68
 69	var duration time.Duration
 70	if remember == "on" {
 71		duration = durationWeek
 72	} else {
 73		duration = durationDay
 74	}
 75
 76	cookie, err := g.GenerateCookie(duration)
 77	if err != nil {
 78		http.Error(w, "Could not generate session cookie.", http.StatusInternalServerError)
 79	}
 80
 81	ks.Set(cookie.Value, user.ID, duration)
 82	http.SetCookie(w, cookie)
 83	http.Redirect(w, r, "/", http.StatusFound)
 84	return
 85}
 86
 87func logoutHandler(w http.ResponseWriter, r *http.Request) {
 88	http.SetCookie(w, g.GenerateEmptyCookie())
 89	http.Redirect(w, r, "/login", http.StatusFound)
 90}
 91
 92func postResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
 93	emailInput := r.FormValue("email")
 94
 95	var user User
 96	db.Where("email = ?", emailInput).First(&user)
 97
 98	if user.ID == 0 {
 99		http.Redirect(w, r, "/login", http.StatusFound)
100		return
101	}
102
103	resetToken, err := g.GenerateRandomToken(32)
104	if err != nil {
105		http.Error(w, "Could not generate reset token.", http.StatusInternalServerError)
106		return
107	}
108
109	ks.Set(resetToken, user.ID, time.Hour)
110	resetURL := fmt.Sprintf("http://localhost:8080/reset-password-confirm?token=%s", resetToken)
111
112	err = sendEmail(email.Email{
113		To:      []string{user.Email},
114		Subject: "Reset password",
115		Body:    fmt.Sprintf("Use this link to reset your password: %s", resetURL),
116	})
117
118	if err != nil {
119		log.Printf("Could not send reset email for %s. Link: %s", user.Email, resetURL)
120	}
121
122	http.Redirect(w, r, "/login", http.StatusFound)
123	return
124
125}
126
127func getResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
128	token := r.URL.Query().Get("token")
129	_, err := ks.Get(token)
130	if err != nil {
131		http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)
132		return
133	}
134
135	templates.ExecuteTemplate(w, "new_password.html", nil)
136}
137
138func postResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
139	token := r.URL.Query().Get("token")
140	userID, err := ks.Get(token)
141	if err != nil {
142		http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)
143		return
144	}
145
146	var user User
147	db.First(&user, *userID)
148
149	password := r.FormValue("password")
150
151	hashedPassword, salt, err := g.HashPassword(password)
152	if err != nil {
153		http.Error(w, "Could not edit your password.", http.StatusInternalServerError)
154		return
155	}
156
157	user.PasswordHash = hashedPassword
158	user.Salt = salt
159	db.Save(&user)
160	ks.Delete(token)
161
162	http.Redirect(w, r, "/login", http.StatusFound)
163	return
164}