justcaptcha/internal/handlers/handlers.go

83 lines
1.7 KiB
Go

package handlers
import (
"fmt"
"image/jpeg"
"justcaptcha/internal/captcha"
pcaptcha "justcaptcha/pkg/captcha"
"justcaptcha/pkg/server"
"net/http"
)
type CaptchaHandlers struct{}
func New() *CaptchaHandlers {
return &CaptchaHandlers{}
}
func (h *CaptchaHandlers) New(w http.ResponseWriter, r *http.Request) {
_, id := captcha.New(r.RemoteAddr)
fmt.Fprint(w, id)
}
func (h *CaptchaHandlers) Image(w http.ResponseWriter, r *http.Request) {
captchaID := pcaptcha.ID(server.GetURLParam(r, "captcha"))
captchaStyle := r.URL.Query().Get("style")
captchaImage, err := captcha.Image(captchaID, captchaStyle)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
if captchaImage == nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Add("Content-Disposition", "inline; filename=\""+string(captchaID)+"\"")
jpeg.Encode(w, *captchaImage, &jpeg.Options{Quality: 20})
}
func (h *CaptchaHandlers) Solve(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
captchaID := pcaptcha.ID(server.GetURLParam(r, "captcha"))
answer := pcaptcha.Answer(r.FormValue("answer"))
ok, err := captcha.Solve(captchaID, answer)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
if !ok {
w.WriteHeader(http.StatusForbidden)
}
}
func (h *CaptchaHandlers) IsSolved(w http.ResponseWriter, r *http.Request) {
captchaID := pcaptcha.ID(server.GetURLParam(r, "captcha"))
isJustRemove := r.URL.Query().Has("remove")
if isJustRemove {
err := captcha.Remove(captchaID)
if err != nil {
w.WriteHeader(http.StatusNotFound)
}
return
}
solved, err := captcha.IsSolved(captchaID)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
if !solved {
w.WriteHeader(http.StatusForbidden)
}
}