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