61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package captcha
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"github.com/dchest/captcha"
|
|
"net/http"
|
|
"netoik.io/netoik-api/pkg/api"
|
|
"netoik.io/netoik-api/pkg/conf"
|
|
"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))
|
|
}
|