-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
captcha.go
95 lines (83 loc) · 2.82 KB
/
captcha.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package main
import (
"github.com/dchest/captcha"
"github.com/gorilla/csrf"
"log"
"net/http"
)
func beginCaptcha(rw http.ResponseWriter, req *http.Request, body string, replyTo string) {
sessionManager.Put(req.Context(), bodyKey, body)
sessionManager.Put(req.Context(), replyToKey, replyTo)
rw.Header().Add("Location", "captcha")
rw.WriteHeader(http.StatusSeeOther)
}
func showCaptcha(rw http.ResponseWriter, req *http.Request) {
if !sessionManager.Exists(req.Context(), bodyKey) || !sessionManager.Exists(req.Context(), replyToKey) {
rw.Header().Add("Location", "failure")
rw.WriteHeader(http.StatusSeeOther)
return
}
captchaId := sessionManager.GetString(req.Context(), captchaKey)
if captchaId == "" || !captcha.Reload(captchaId) {
captchaId = captcha.New()
sessionManager.Put(req.Context(), captchaKey, captchaId)
}
_ = captchaTemplate.ExecuteTemplate(rw, "captcha.html", map[string]interface{}{
csrf.TemplateTag: csrf.TemplateField(req),
})
}
func writeCaptchaImage(rw http.ResponseWriter, req *http.Request) {
captchaId := sessionManager.GetString(req.Context(), captchaKey)
if captchaId == "" {
rw.WriteHeader(http.StatusForbidden)
return
}
rw.Header().Set("Cache-Control", "no-cache")
rw.Header().Set("Content-Type", "image/png")
if err := captcha.WriteImage(rw, captchaId, captcha.StdWidth, captcha.StdHeight); err != nil {
hc.recordCaptchaError(err)
log.Printf("Unable to generate image captcha: %s", err.Error())
rw.WriteHeader(http.StatusInternalServerError)
return
}
hc.recordCaptchaSuccess()
}
func writeCaptchaAudio(rw http.ResponseWriter, req *http.Request) {
captchaId := sessionManager.GetString(req.Context(), captchaKey)
if captchaId == "" {
rw.WriteHeader(http.StatusForbidden)
return
}
rw.Header().Set("Cache-Control", "no-cache")
rw.Header().Set("Content-Type", "audio/wav")
rw.Header().Set("Content-Disposition", "attachment")
if err := captcha.WriteAudio(rw, captchaId, "en"); err != nil {
hc.recordCaptchaError(err)
log.Printf("Unable to generate audio captcha: %s", err.Error())
rw.WriteHeader(http.StatusInternalServerError)
return
}
hc.recordCaptchaSuccess()
}
func handleSolve(rw http.ResponseWriter, req *http.Request) {
captchaId := sessionManager.GetString(req.Context(), captchaKey)
if captchaId == "" {
rw.WriteHeader(http.StatusForbidden)
return
}
digits := req.Form.Get("captcha")
if !captcha.VerifyString(captchaId, digits) {
hc.recordCaptchaSuccess()
rw.Header().Add("Location", "failure")
rw.WriteHeader(http.StatusSeeOther)
return
}
hc.recordCaptchaSuccess()
if sendMail(sessionManager.PopString(req.Context(), replyToKey), sessionManager.PopString(req.Context(), bodyKey)) {
rw.Header().Add("Location", "success")
rw.WriteHeader(http.StatusSeeOther)
} else {
rw.Header().Add("Location", "failure")
rw.WriteHeader(http.StatusSeeOther)
}
}