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 _, err = getUserByName(username, 0)
54 if err == nil {
55 http.Error(w, "This username is already registered.", http.StatusConflict)
56 return
57 }
58
59 hashedPassword, salt, err := g.HashPassword(r.FormValue("password"))
60 if err != nil {
61 http.Error(w, "Invalid password.", http.StatusBadRequest)
62 return
63 }
64
65 user := User{
66 Username: username,
67 Email: email,
68 PasswordHash: hashedPassword,
69 Salt: salt,
70 }
71
72 db.Create(&user)
73 if user.ID == 0 {
74 http.Error(w, "This email is already registered.", http.StatusConflict)
75 return
76 }
77
78 login(w, user.ID, false)
79 http.Redirect(w, r, "/login", http.StatusFound)
80}
81
82func postLoginHandler(w http.ResponseWriter, r *http.Request) {
83 username := r.FormValue("username")
84 password := r.FormValue("password")
85 remember := r.FormValue("remember")
86
87 user, err := getUserByName(username, 0)
88
89 if err != nil || !g.CheckPassword(password, user.Salt, user.PasswordHash) {
90 http.Error(w, "Invalid credentials", http.StatusUnauthorized)
91 return
92 }
93
94 login(w, user.ID, remember == "on")
95 http.Redirect(w, r, "/", http.StatusFound)
96}
97
98func logoutHandler(w http.ResponseWriter, r *http.Request) {
99 http.SetCookie(w, g.GenerateEmptyCookie())
100 http.Redirect(w, r, "/login", http.StatusFound)
101}
102
103func postResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
104 emailInput := r.FormValue("email")
105
106 var user User
107 db.Where("email = ?", emailInput).First(&user)
108
109 if user.ID == 0 {
110 http.Redirect(w, r, "/login", http.StatusFound)
111 return
112 }
113
114 resetToken, err := g.GenerateRandomToken(32)
115 if err != nil {
116 http.Error(w, "Could not generate reset token.", http.StatusInternalServerError)
117 return
118 }
119
120 ks.Set("reset:"+resetToken, user.ID, time.Hour)
121 sendResetEmail(user.Email, resetToken)
122
123 http.Redirect(w, r, "/login", http.StatusFound)
124
125}
126
127func getResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
128 token := r.URL.Query().Get("token")
129 _, err := ks.Get("reset:" + token)
130 if err != nil {
131 http.Error(w, "Token is invalid or expired.", http.StatusUnauthorized)
132 return
133 }
134
135 xt.ExecuteTemplate(w, "new_password.tmpl", nil)
136}
137
138func postResetPasswordConfirmHandler(w http.ResponseWriter, r *http.Request) {
139 token := r.URL.Query().Get("token")
140 userID, err := ks.Get("reset:" + 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, "Invalid password.", http.StatusBadRequest)
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}