goCaptcha/serverRoutes.go
serverRoutes.goRaw
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "image/jpeg"
7 "io/ioutil"
8 "log"
9 "net/http"
10 "strings"
11 "time"
12
13 "gopkg.in/mgo.v2/bson"
14
15 "github.com/gorilla/mux"
16)
17
18type Routes []Route
19
20var routes = Routes{
21 Route{
22 "Index",
23 "GET",
24 "/",
25 Index,
26 },
27 Route{
28 "GetImage",
29 "GET",
30 "/image/{imageName}",
31 GetImage,
32 },
33 Route{
34 "GetCaptcha",
35 "GET",
36 "/captcha",
37 GetCaptcha,
38 },
39 Route{
40 "AnswerCaptcha",
41 "POST",
42 "/answer",
43 AnswerCaptcha,
44 },
45}
46
47//ROUTES
48
49func Index(w http.ResponseWriter, r *http.Request) {
50 fmt.Fprintln(w, "ask for images in /r")
51}
52
53func GetImage(w http.ResponseWriter, r *http.Request) {
54 vars := mux.Vars(r)
55 imageName := vars["imageName"]
56
57 imgFakePath := ImgFakePath{}
58 err := imgFakePathCollection.Find(bson.M{"fake": imageName}).One(&imgFakePath)
59 check(err)
60
61 file, err := ioutil.ReadFile(serverConfig.ImgsFolder + "/" + imgFakePath.Real)
62 if err != nil {
63 fmt.Fprintln(w, err)
64 }
65
66 pathSplited := strings.Split(imgFakePath.Real, ".")
67 imageExtension := pathSplited[len(pathSplited)-1]
68 img, err := dataToImage(file, imageExtension)
69
70 if err != nil {
71 fmt.Fprintln(w, "image "+imageName+" does not exist in server")
72 } else {
73 jpeg.Encode(w, img, nil) // Write to the ResponseWriter
74 }
75}
76func GetCaptcha(w http.ResponseWriter, r *http.Request) {
77
78 ip := strings.Split(r.RemoteAddr, ":")[0]
79 resp := generateCaptcha(serverConfig.NumImgsCaptcha, ip)
80 jsonResp, err := json.Marshal(resp)
81 check(err)
82 fmt.Fprintln(w, string(jsonResp))
83}
84
85func AnswerCaptcha(w http.ResponseWriter, r *http.Request) {
86 decoder := json.NewDecoder(r.Body)
87 var captchaAnswer CaptchaAnswer
88 err := decoder.Decode(&captchaAnswer)
89 check(err)
90 defer r.Body.Close()
91
92 ip := strings.Split(r.RemoteAddr, ":")[0]
93 resp := validateCaptcha(captchaAnswer, ip)
94 //if resp==false add ip to blacklist
95 if resp == false {
96 //get SuspiciousIP
97 suspiciousIP := SuspiciousIP{}
98 err := suspiciousIPCollection.Find(bson.M{"ip": ip}).One(&suspiciousIP)
99 if err != nil {
100 //if not exist, add
101 suspiciousIP.Date = time.Now().Unix()
102 suspiciousIP.IP = ip
103 suspiciousIP.Count = 0
104 //store suspiciousIP in MongoDB
105 err := suspiciousIPCollection.Insert(suspiciousIP)
106 check(err)
107 } else {
108 //if exist
109 suspiciousIP.Date = time.Now().Unix()
110 suspiciousIP.Count++
111 err := suspiciousIPCollection.Update(bson.M{"ip": ip}, suspiciousIP)
112 check(err)
113 }
114 }
115 //if count > limit, resp=false
116 suspiciousIP := SuspiciousIP{}
117 err = suspiciousIPCollection.Find(bson.M{"ip": ip}).One(&suspiciousIP)
118 if err == nil {
119 //if exist, and time.Since(suspiciousIP.Date) < serverConfig.TimeBan, increase counter
120 if time.Since(time.Unix(suspiciousIP.Date, 0)).Seconds() < serverConfig.TimeBan {
121 if suspiciousIP.Count > serverConfig.SuspiciousIPCountLimit {
122 if resp == false {
123 log.Println("IP: " + ip + ", has reached limit count of SuspiciousIP")
124 }
125 resp = false
126 }
127 } else {
128 //timeBan is completed, delete counter
129 err := suspiciousIPCollection.Remove(bson.M{"ip": ip})
130 check(err)
131 }
132 if resp == true {
133 //answered correct, delete counter
134 err := suspiciousIPCollection.Remove(bson.M{"ip": ip})
135 check(err)
136 }
137 }
138
139 jsonResp, err := json.Marshal(resp)
140 check(err)
141 fmt.Fprintln(w, string(jsonResp))
142}