all repos — well-binge @ 55e48ab1355d3b02788c0881ffa8067493ecfb6b

Create positive, recurring habits.

src/app/handlers.go (view raw)

  1package app
  2
  3import (
  4	"net/http"
  5	"strconv"
  6	"time"
  7)
  8
  9func getIndexHandler(w http.ResponseWriter, r *http.Request) {
 10	xt.ExecuteTemplate(w, "index.tmpl", nil)
 11}
 12
 13func getHabitsHandler(w http.ResponseWriter, r *http.Request) {
 14	user, ok := getLoggedUser(r)
 15	if !ok {
 16		http.Error(w, "Could not find user in context.", http.StatusInternalServerError)
 17		return
 18	}
 19
 20	positive, negative, err := getAllHabits(user.ID)
 21	if err != nil {
 22		http.Error(w, "Could not get user habits.", http.StatusInternalServerError)
 23		return
 24	}
 25
 26	data := map[string]interface{}{
 27		"User":     user,
 28		"Positive": positive,
 29		"Negative": negative,
 30	}
 31
 32	xt.ExecuteTemplate(w, "habits.tmpl", data)
 33}
 34
 35func getNewPositiveHandler(w http.ResponseWriter, r *http.Request) {
 36	data := map[string]interface{}{"Negative": false}
 37	xt.ExecuteTemplate(w, "new.tmpl", data)
 38}
 39
 40func getNewNegativeHandler(w http.ResponseWriter, r *http.Request) {
 41	data := map[string]interface{}{"Negative": true}
 42	xt.ExecuteTemplate(w, "new.tmpl", data)
 43}
 44
 45func postNewHandler(w http.ResponseWriter, r *http.Request) {
 46	negative := r.FormValue("negative") == "on"
 47	name := r.FormValue("name")
 48
 49	if !checkHabitName(name) {
 50		http.Error(w, "Bad habit name.", http.StatusBadRequest)
 51	}
 52
 53	var days uint
 54	if !negative {
 55		res, err := strconv.ParseUint(r.FormValue("days"), 10, 64)
 56		if err != nil {
 57			http.Error(w, "Bad days value.", http.StatusBadRequest)
 58			return
 59		}
 60		days = uint(res)
 61	}
 62
 63	user, ok := getLoggedUser(r)
 64	if !ok {
 65		http.Error(w, "Could not get logged user", http.StatusInternalServerError)
 66	}
 67
 68	db.Create(&Habit{
 69		UserID:   user.ID,
 70		Name:     name,
 71		Days:     days,
 72		Negative: negative,
 73	})
 74
 75	http.Redirect(w, r, "/habits", http.StatusFound)
 76}
 77
 78func getRegisterHandler(w http.ResponseWriter, r *http.Request) {
 79	xt.ExecuteTemplate(w, "auth-register.tmpl", nil)
 80}
 81
 82func getLoginHandler(w http.ResponseWriter, r *http.Request) {
 83	_, err := readSessionCookie(r)
 84	if err != nil {
 85		xt.ExecuteTemplate(w, "auth-login.tmpl", nil)
 86		return
 87	}
 88
 89	http.Redirect(w, r, "/habits", http.StatusFound)
 90}
 91
 92func getResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
 93	xt.ExecuteTemplate(w, "auth-reset_password.tmpl", nil)
 94}
 95
 96func postRegisterHandler(w http.ResponseWriter, r *http.Request) {
 97	if !registrationEnabled {
 98		http.Error(w, "Registration is currently disabled.", http.StatusForbidden)
 99		return
100	}
101
102	username, err := sanitizeUsername(r.FormValue("username"))
103	if err != nil {
104		http.Error(w, "Invalid username.", http.StatusBadRequest)
105		return
106	}
107
108	email, err := sanitizeEmail(r.FormValue("email"))
109	if err != nil {
110		http.Error(w, "Invalid email.", http.StatusBadRequest)
111		return
112	}
113
114	_, err = getUserByName(username, 0)
115	if err == nil {
116		http.Error(w, "This username is already registered.", http.StatusConflict)
117		return
118	}
119
120	hashedPassword, salt, err := g.HashPassword(r.FormValue("password"))
121	if err != nil {
122		http.Error(w, "Invalid password.", http.StatusBadRequest)
123		return
124	}
125
126	user := User{
127		Username:     username,
128		Email:        email,
129		PasswordHash: hashedPassword,
130		Salt:         salt,
131	}
132
133	db.Create(&user)
134	if user.ID == 0 {
135		http.Error(w, "This email is already registered.", http.StatusConflict)
136		return
137	}
138
139	login(w, user.ID, false)
140	http.Redirect(w, r, "/login", http.StatusFound)
141}
142
143func postLoginHandler(w http.ResponseWriter, r *http.Request) {
144	username := r.FormValue("username")
145	password := r.FormValue("password")
146	remember := r.FormValue("remember")
147
148	user, err := getUserByName(username, 0)
149
150	if err != nil || !g.CheckPassword(password, user.Salt, user.PasswordHash) {
151		http.Error(w, "Invalid credentials", http.StatusUnauthorized)
152		return
153	}
154
155	login(w, user.ID, remember == "on")
156	http.Redirect(w, r, "/login", http.StatusFound)
157}
158
159func logoutHandler(w http.ResponseWriter, r *http.Request) {
160	http.SetCookie(w, g.GenerateEmptyCookie())
161	http.Redirect(w, r, "/login", http.StatusFound)
162}
163
164func postResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
165	emailInput := r.FormValue("email")
166
167	var user User
168	db.Where("email = ?", emailInput).First(&user)
169
170	if user.ID == 0 {
171		http.Redirect(w, r, "/login", http.StatusFound)
172		return
173	}
174
175	resetToken, err := g.GenerateRandomToken(32)
176	if err != nil {
177		http.Error(w, "Could not generate reset token.", http.StatusInternalServerError)
178		return
179	}
180
181	ks.Set("reset:"+resetToken, user.ID, time.Hour)
182	sendResetEmail(user.Email, resetToken)
183
184	http.Redirect(w, r, "/login", http.StatusFound)
185
186}
187
188func getResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
189	token := r.URL.Query().Get("token")
190	_, err := ks.Get("reset:" + token)
191	if err != nil {
192		http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)
193		return
194	}
195
196	xt.ExecuteTemplate(w, "auth-new_password.tmpl", nil)
197}
198
199func postResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
200	token := r.URL.Query().Get("token")
201	userID, err := ks.Get("reset:" + token)
202	if err != nil {
203		http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)
204		return
205	}
206
207	var user User
208	db.First(&user, *userID)
209
210	password := r.FormValue("password")
211
212	hashedPassword, salt, err := g.HashPassword(password)
213	if err != nil {
214		http.Error(w, "Invalid password.", http.StatusBadRequest)
215		return
216	}
217
218	user.PasswordHash = hashedPassword
219	user.Salt = salt
220	db.Save(&user)
221	ks.Delete(token)
222
223	http.Redirect(w, r, "/login", http.StatusFound)
224}