You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

121 lines
3.0 KiB

package main
import (
"math/rand"
"os/exec"
"strings"
"time"
"gopkg.in/mgo.v2/bson"
)
type Captcha struct {
Id string `json:"id"`
Imgs []string `json:"imgs"`
Question string `json:"question"`
Date string `json:"date"`
}
type CaptchaSol struct {
Id string `json:"id"`
ImgsSolution []string `json:"imgssolution"`
Question string `json:"question"` //select all X
Date int64 `json:"date"`
IP string `json:"ip"`
}
type CaptchaAnswer struct {
CaptchaId string `json:"captchaid"`
Selection []int `json:"selection"`
}
type ImgFakePath struct {
CaptchaId string `json:"captchaid"`
Real string `json:"real"`
Fake string `json:"fake"`
}
type SuspiciousIP struct {
Date int64 `json:"date"`
IP string `json:"ip"`
Count int `json:"count"`
}
func generateUUID() string {
out, err := exec.Command("uuidgen").Output()
check(err)
uuid := string(out)
uuid = strings.Replace(uuid, "\n", "", -1)
return uuid
}
func generateRandInt(min int, max int) int {
//rand.Seed(time.Now().UTC().UnixNano())
return rand.Intn(max-min) + min
}
func generateQuestionFromCategoriesArray(imgs []string) string {
n := generateRandInt(0, len(imgs))
return imgs[n]
}
func generateCaptcha(count int, ip string) Captcha {
var captcha Captcha
var captchaSol CaptchaSol
captcha.Id = generateUUID()
captchaSol.Id = captcha.Id
for i := 0; i < count; i++ {
nCateg := generateRandInt(0, len(categDataset))
nImg := generateRandInt(0, len(dataset[categDataset[nCateg]]))
//imgFakePath
var imgFakePath ImgFakePath
imgFakePath.CaptchaId = captcha.Id
imgFakePath.Real = categDataset[nCateg] + "/" + dataset[categDataset[nCateg]][nImg]
imgFakePath.Fake = generateUUID() + ".png"
err := imgFakePathCollection.Insert(imgFakePath)
check(err)
captcha.Imgs = append(captcha.Imgs, imgFakePath.Fake)
captchaSol.ImgsSolution = append(captchaSol.ImgsSolution, categDataset[nCateg])
}
question := generateQuestionFromCategoriesArray(captchaSol.ImgsSolution)
captcha.Question = question
captchaSol.Question = question
captchaSol.Date = time.Now().Unix()
captchaSol.IP = ip
err := captchaSolCollection.Insert(captchaSol)
check(err)
return captcha
}
func validateCaptcha(captchaAnswer CaptchaAnswer, ip string) bool {
var solved bool
solved = true
captchaSol := CaptchaSol{}
err := captchaSolCollection.Find(bson.M{"id": captchaAnswer.CaptchaId}).One(&captchaSol)
check(err)
for k, imgSol := range captchaSol.ImgsSolution {
if imgSol == captchaSol.Question {
if captchaAnswer.Selection[k] == 1 {
//correct
} else {
solved = false
}
}
if imgSol != captchaSol.Question {
if captchaAnswer.Selection[k] == 0 {
//correct
} else {
solved = false
}
}
}
//time elapsed from captcha generation comprovation
date := time.Unix(captchaSol.Date, 0)
elapsed := time.Since(date)
if elapsed.Seconds() < 1 {
solved = false
}
if elapsed.Seconds() > 60 {
solved = false
}
//ip comprovation
if captchaSol.IP != ip {
solved = false
}
return solved
}