netoik-api/pkg/captcha/captcha.go

61 lines
1.5 KiB
Go
Raw Normal View History

2023-01-19 15:49:23 +00:00
package captcha
import (
"errors"
"fmt"
"github.com/dchest/captcha"
"net/http"
2023-01-24 17:40:54 +00:00
"netoik.io/netoik-api/pkg/api"
"netoik.io/netoik-api/pkg/conf"
2023-01-19 15:49:23 +00:00
"os"
"path/filepath"
"time"
)
func writeImage(id string) bool {
path := filepath.Join(conf.Conf.CaptchaDirectory, id+".png")
file, err := os.Create(path)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: cannot write file %q: %s\n", path, err.Error())
return false
}
if err = captcha.WriteImage(file, id, conf.Conf.CaptchaWidth, conf.Conf.CaptchaHeight); err != nil {
fmt.Fprintf(os.Stderr, "ERROR: cannot write captcha into file %q: %s\n", path, err.Error())
return false
}
return true
}
func HandleNew(w http.ResponseWriter, r *http.Request) {
// Check method
if r.Method != "POST" {
api.Reply(w, 405, api.Answer{})
return
}
// Create new captcha
id := captcha.NewLen(conf.Conf.CaptchaLength)
// Write captcha image
if !writeImage(id) {
api.Reply(w, 500, api.Answer{})
return
}
// Remove captcha image after expiration time
go func(id string) {
time.Sleep(conf.Conf.CaptchaExpiration)
path := filepath.Join(conf.Conf.CaptchaDirectory, id+".png")
if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) {
fmt.Fprintf(os.Stderr, "ERROR: cannot remove captcha image after expiration %q: %s", path, err.Error())
}
}(id)
// Return captcha id
api.Reply(w, 200, api.Answer{Success: true, Id: id})
}
func Setup() {
captcha.SetCustomStore(captcha.NewMemoryStore(captcha.CollectNum, conf.Conf.CaptchaExpiration))
}