Browse Source

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

master
arnaucode 6 years ago
parent
commit
22d77500bd
7 changed files with 189 additions and 5 deletions
  1. +67
    -0
      captcha.go
  2. +15
    -2
      imageOperations.go
  3. +17
    -0
      main.go
  4. +51
    -0
      mongoConfig.go
  5. +4
    -0
      mongodbConfig.json
  6. +21
    -0
      readDataset.go
  7. +14
    -3
      serverRoutes.go

+ 67
- 0
captcha.go

@ -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
}

+ 15
- 2
imageOperations.go

@ -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
- 0
main.go

@ -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
- 0
mongoConfig.go

@ -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
- 0
mongodbConfig.json

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

+ 21
- 0
readDataset.go

@ -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())
}
}
}

+ 14
- 3
serverRoutes.go

@ -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))

Loading…
Cancel
Save