justcaptcha/internal/handlers/handlers.go

77 lines
1.6 KiB
Go

package handlers
import (
"fmt"
"image/png"
"justcaptcha/internal/captcha"
"justcaptcha/pkg/server"
"net/http"
"time"
)
type CaptchaHandlers struct {
ExpireIn time.Duration
}
func New(expiration time.Duration) *CaptchaHandlers {
return &CaptchaHandlers{
ExpireIn: expiration}
}
func (h *CaptchaHandlers) New(w http.ResponseWriter, r *http.Request) {
dc := captcha.NewDwellingCaptcha(h.ExpireIn)
_, id := captcha.New(r.RemoteAddr, dc)
fmt.Fprint(w, id)
}
func (h *CaptchaHandlers) Image(w http.ResponseWriter, r *http.Request) {
captchaID := captcha.ID(server.GetURLParam(r, "captcha"))
captchaImage, err := captcha.Image(captchaID)
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)+"\"")
png.Encode(w, *captchaImage)
}
func (h *CaptchaHandlers) Solve(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
captchaID := captcha.ID(server.GetURLParam(r, "captcha"))
answer := captcha.Answer(r.FormValue("answer"))
ok, err := captcha.Solve(captcha.ID(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 := captcha.ID(server.GetURLParam(r, "captcha"))
solved, err := captcha.IsSolved(captchaID)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
if !solved {
w.WriteHeader(http.StatusForbidden)
}
}