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