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	Ip           string   `json:"ip"`
 25}
 26type CaptchaAnswer struct {
 27	CaptchaId string `json:"captchaid"`
 28	Selection []int  `json:"selection"`
 29}
 30type ImgFakePath struct {
 31	CaptchaId string `json:"captchaid"`
 32	Real      string `json:"real"`
 33	Fake      string `json:"fake"`
 34}
 35
 36func generateUUID() string {
 37	out, err := exec.Command("uuidgen").Output()
 38	check(err)
 39	uuid := string(out)
 40	uuid = strings.Replace(uuid, "\n", "", -1)
 41	return uuid
 42}
 43func generateRandInt(min int, max int) int {
 44	//rand.Seed(time.Now().UTC().UnixNano())
 45	return rand.Intn(max-min) + min
 46}
 47func generateQuestionFromCategoriesArray(imgs []string) string {
 48	n := generateRandInt(0, len(imgs))
 49	return imgs[n]
 50}
 51func generateCaptcha(count int, ip string) Captcha {
 52	var captcha Captcha
 53	var captchaSol CaptchaSol
 54
 55	captcha.Id = generateUUID()
 56	captchaSol.Id = captcha.Id
 57
 58	for i := 0; i < count; i++ {
 59		nCateg := generateRandInt(0, len(categDataset))
 60		nImg := generateRandInt(0, len(dataset[categDataset[nCateg]]))
 61		//imgFakePath
 62		var imgFakePath ImgFakePath
 63		imgFakePath.CaptchaId = captcha.Id
 64		imgFakePath.Real = categDataset[nCateg] + "/" + dataset[categDataset[nCateg]][nImg]
 65		imgFakePath.Fake = generateUUID() + ".png"
 66		err := imgFakePathCollection.Insert(imgFakePath)
 67		check(err)
 68		captcha.Imgs = append(captcha.Imgs, imgFakePath.Fake)
 69		captchaSol.ImgsSolution = append(captchaSol.ImgsSolution, categDataset[nCateg])
 70	}
 71	question := generateQuestionFromCategoriesArray(captchaSol.ImgsSolution)
 72	captcha.Question = question
 73	captchaSol.Question = question
 74	captchaSol.Date = time.Now().Unix()
 75	captchaSol.Ip = ip
 76	err := captchaSolCollection.Insert(captchaSol)
 77	check(err)
 78	return captcha
 79}
 80func validateCaptcha(captchaAnswer CaptchaAnswer, ip string) bool {
 81	var solved bool
 82	solved = true
 83	captchaSol := CaptchaSol{}
 84	err := captchaSolCollection.Find(bson.M{"id": captchaAnswer.CaptchaId}).One(&captchaSol)
 85	check(err)
 86	for k, imgSol := range captchaSol.ImgsSolution {
 87		if imgSol == captchaSol.Question {
 88			if captchaAnswer.Selection[k] == 1 {
 89				//correct
 90			} else {
 91				solved = false
 92			}
 93		}
 94		if imgSol != captchaSol.Question {
 95			if captchaAnswer.Selection[k] == 0 {
 96				//correct
 97			} else {
 98				solved = false
 99			}
100		}
101	}
102
103	//time elapsed from captcha generation comprovation
104	date := time.Unix(captchaSol.Date, 0)
105	elapsed := time.Since(date)
106	fmt.Println(elapsed.Seconds())
107	if elapsed.Seconds() < 1 {
108		solved = false
109	}
110	if elapsed.Seconds() > 60 {
111		solved = false
112	}
113	//ip comprovation
114	if captchaSol.Ip != ip {
115		solved = false
116	}
117	return solved
118}