implemented: generate captcha and captcha solution, returns only captcha which has only fake image names and captchaid, stores also translator fake image name to real. Implemented read images dataset, storing in categories (folders names). GetImage reads fake image name, and translates to real image name, and serves the image content as fake image name

This commit is contained in:
arnaucode
2017-08-08 21:23:28 +02:00
parent ab69ef235d
commit 22d77500bd
7 changed files with 189 additions and 5 deletions

67
captcha.go Normal file
View File

@@ -0,0 +1,67 @@
package main
import (
"math/rand"
"os/exec"
"strings"
)
type Captcha struct {
Id string `json:"id"`
Imgs []string `json:"imgs"`
Question string `json:"question"`
Date string `json:"date"`
}
type CaptchaSolution struct {
Id string `json:"id"`
Imgs []string `json:"imgs"`
ImgsSolution []string `json:"imgssolution"`
Question string `json:"question"`
Date string `json:"date"`
}
type ImgFakePath struct {
CaptchaId string `json:"captchaid"`
Real string `json:"real"`
Fake string `json:"fake"`
}
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 generateCaptcha(count int) Captcha {
var captcha Captcha
var captchaSol CaptchaSolution
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.Imgs = append(captchaSol.Imgs, dataset[categDataset[nCateg]][nImg])
captchaSol.ImgsSolution = append(captchaSol.ImgsSolution, categDataset[nCateg])
}
captcha.Question = "Select all leopards"
captchaSol.Question = "Select all leopards"
err := captchaCollection.Insert(captcha)
check(err)
err = captchaSolutionCollection.Insert(captchaSol)
check(err)
return captcha
}

View File

@@ -2,14 +2,27 @@ package main
import (
"bytes"
"fmt"
"image"
"image/jpeg"
"image/png"
)
func dataToPNG(data []byte, imageName string) (image.Image, error) {
func dataToImage(data []byte, imageExtension string) (image.Image, error) {
reader := bytes.NewReader(data)
img, err := png.Decode(reader)
//img, err := png.Decode(reader)
var img image.Image
var err error
switch imageExtension {
case "png":
img, err = png.Decode(reader)
case "jpg", "jpeg":
img, err = jpeg.Decode(reader)
default:
img = nil
}
if err != nil {
fmt.Println(err)
return img, err
}
return img, err

17
main.go
View File

@@ -2,7 +2,10 @@ package main
import (
"log"
"math/rand"
"net/http"
"strconv"
"time"
"github.com/gorilla/handlers"
)
@@ -10,11 +13,25 @@ import (
func main() {
savelog()
log.Println("goCaptcha started")
rand.Seed(time.Now().UTC().UnixNano())
//connect with mongodb
readMongodbConfig("./mongodbConfig.json")
session, err := getSession()
check(err)
captchaCollection = getCollection(session, "captchas")
captchaSolutionCollection = getCollection(session, "captchassolutions")
imgFakePathCollection = getCollection(session, "imgfakepath")
//start the server
//http server start
readServerConfig("./serverConfig.json")
//read the filenames of the dataset
readDataset(serverConfig.ImgsFolder)
log.Println("dataset read")
log.Println("num of dataset categories: " + strconv.Itoa(len(dataset)))
log.Println("server running")
log.Print("port: ")
log.Println(serverConfig.ServerPort)

51
mongoConfig.go Normal file
View File

@@ -0,0 +1,51 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
mgo "gopkg.in/mgo.v2"
)
//MongoConfig stores the configuration of mongodb to connect
type MongoConfig struct {
Ip string `json:"ip"`
Database string `json:"database"`
}
var mongoConfig MongoConfig
var captchaCollection *mgo.Collection
var captchaSolutionCollection *mgo.Collection
var imgFakePathCollection *mgo.Collection
func readMongodbConfig(path string) {
file, e := ioutil.ReadFile(path)
if e != nil {
fmt.Println("error:", e)
}
content := string(file)
json.Unmarshal([]byte(content), &mongoConfig)
}
func getSession() (*mgo.Session, error) {
session, err := mgo.Dial("mongodb://" + mongoConfig.Ip)
if err != nil {
panic(err)
}
//defer session.Close()
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
return session, err
}
func getCollection(session *mgo.Session, collection string) *mgo.Collection {
c := session.DB(mongoConfig.Database).C(collection)
return c
}

4
mongodbConfig.json Normal file
View File

@@ -0,0 +1,4 @@
{
"ip": "127.0.0.1",
"database": "goCaptcha"
}

21
readDataset.go Normal file
View File

@@ -0,0 +1,21 @@
package main
import (
"io/ioutil"
)
var dataset map[string][]string
var categDataset []string
func readDataset(path string) {
dataset = make(map[string][]string)
folders, _ := ioutil.ReadDir(path)
for _, folder := range folders {
categDataset = append(categDataset, folder.Name())
folderFiles, _ := ioutil.ReadDir(path + "/" + folder.Name())
for _, file := range folderFiles {
dataset[folder.Name()] = append(dataset[folder.Name()], file.Name())
}
}
}

View File

@@ -6,6 +6,9 @@ import (
"image/jpeg"
"io/ioutil"
"net/http"
"strings"
"gopkg.in/mgo.v2/bson"
"github.com/gorilla/mux"
)
@@ -43,12 +46,20 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
imageName := vars["imageName"]
file, err := ioutil.ReadFile(serverConfig.ImgsFolder + "/" + imageName)
imgFakePath := ImgFakePath{}
err := imgFakePathCollection.Find(bson.M{"fake": imageName}).One(&imgFakePath)
check(err)
fmt.Println(serverConfig.ImgsFolder + "/" + imgFakePath.Real)
file, err := ioutil.ReadFile(serverConfig.ImgsFolder + "/" + imgFakePath.Real)
if err != nil {
fmt.Fprintln(w, err)
}
img, err := dataToPNG(file, imageName)
pathSplited := strings.Split(imgFakePath.Real, ".")
imageExtension := pathSplited[len(pathSplited)-1]
img, err := dataToImage(file, imageExtension)
if err != nil {
fmt.Fprintln(w, "image "+imageName+" does not exist in server")
@@ -58,7 +69,7 @@ func GetImage(w http.ResponseWriter, r *http.Request) {
}
func GetCaptcha(w http.ResponseWriter, r *http.Request) {
resp := ""
resp := generateCaptcha(6)
jsonResp, err := json.Marshal(resp)
check(err)
fmt.Fprintln(w, string(jsonResp))