arnaucube
arnaucube/goCaptchaPublic Self-hosted repository
goCaptcha/captcha.go
captcha.goRaw
  1package main
  2
  3import (
  4	"fmt"
  5	"math/rand"
  6	"os/exec"
  7	"strings"
  8	"time"
  9
 10	"gopkg.in/mgo.v2/bson"
 11)
 12
 13type Captcha struct {
 14	Id       string   `json:"id"`
 15	Imgs     []string `json:"imgs"`
 16	Question string   `json:"question"`
 17	Date     string   `json:"date"`
 18}
 19type CaptchaSol struct {
 20	Id           string   `json:"id"`
 21	ImgsSolution []string `json:"imgssolution"`
 22	Question     string   `json:"question"` //select all X
 23	Date         int64    `json:"date"`
 24}
 25type CaptchaAnswer struct {
 26	CaptchaId string `json:"captchaid"`
 27	Selection []int  `json:"selection"`
 28}
 29type ImgFakePath struct {
 30	CaptchaId string `json:"captchaid"`
 31	Real      string `json:"real"`
 32	Fake      string `json:"fake"`
 33}
 34
 35func generateUUID() string {
 36	out, err := exec.Command("uuidgen").Output()
 37	check(err)
 38	uuid := string(out)
 39	uuid = strings.Replace(uuid, "\n", "", -1)
 40	return uuid
 41}
 42func generateRandInt(min int, max int) int {
 43	//rand.Seed(time.Now().UTC().UnixNano())
 44	return rand.Intn(max-min) + min
 45}
 46func generateQuestionFromCategoriesArray(imgs []string) string {
 47	n := generateRandInt(0, len(imgs))
 48	return imgs[n]
 49}
 50func generateCaptcha(count int) Captcha {
 51	var captcha Captcha
 52	var captchaSol CaptchaSol
 53
 54	captcha.Id = generateUUID()
 55	captchaSol.Id = captcha.Id
 56
 57	for i := 0; i < count; i++ {
 58		nCateg := generateRandInt(0, len(categDataset))
 59		nImg := generateRandInt(0, len(dataset[categDataset[nCateg]]))
 60		//imgFakePath
 61		var imgFakePath ImgFakePath
 62		imgFakePath.CaptchaId = captcha.Id
 63		imgFakePath.Real = categDataset[nCateg] + "/" + dataset[categDataset[nCateg]][nImg]
 64		imgFakePath.Fake = generateUUID() + ".png"
 65		err := imgFakePathCollection.Insert(imgFakePath)
 66		check(err)
 67		captcha.Imgs = append(captcha.Imgs, imgFakePath.Fake)
 68		captchaSol.ImgsSolution = append(captchaSol.ImgsSolution, categDataset[nCateg])
 69	}
 70	question := generateQuestionFromCategoriesArray(captchaSol.ImgsSolution)
 71	captcha.Question = question
 72	captchaSol.Question = question
 73	captchaSol.Date = time.Now().Unix()
 74	err := captchaSolCollection.Insert(captchaSol)
 75	check(err)
 76	return captcha
 77}
 78func validateCaptcha(captchaAnswer CaptchaAnswer) bool {
 79	var solved bool
 80	solved = true
 81	captchaSol := CaptchaSol{}
 82	err := captchaSolCollection.Find(bson.M{"id": captchaAnswer.CaptchaId}).One(&captchaSol)
 83	check(err)
 84	for k, imgSol := range captchaSol.ImgsSolution {
 85		if imgSol == captchaSol.Question {
 86			if captchaAnswer.Selection[k] == 1 {
 87				//correct
 88			} else {
 89				solved = false
 90			}
 91		}
 92		if imgSol != captchaSol.Question {
 93			if captchaAnswer.Selection[k] == 0 {
 94				//correct
 95			} else {
 96				solved = false
 97			}
 98		}
 99	}
100
101	//time elapsed from captcha generation comprovation
102	date := time.Unix(captchaSol.Date, 0)
103	elapsed := time.Since(date)
104	fmt.Println(elapsed.Seconds())
105	if elapsed.Seconds() < 1 {
106		solved = false
107	}
108	if elapsed.Seconds() > 60 {
109		solved = false
110	}
111	return solved
112}