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}