From ad1b8cdf274756c834c55703a3d732adf4349ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=AD=D9=85=DB=8C=D8=AF=20=D8=B1=D8=B6=D8=A7=20=D8=AD?= =?UTF-8?q?=D8=B3=D9=86=DB=8C=20=DB=8C=D8=A7=D9=82=D9=88=D8=AA=DB=8C?= <09335556879@Aramooz.co> Date: Tue, 10 Nov 2020 16:44:56 +0330 Subject: [PATCH] WIP : MVP of handler class --- go.mod | 3 + main.go | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+) create mode 100644 go.mod create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d5fb481 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/IrisDev-net/irisCaptchaGo + +go 1.15 diff --git a/main.go b/main.go new file mode 100644 index 0000000..bea19bb --- /dev/null +++ b/main.go @@ -0,0 +1,232 @@ +package irisCaptchaGo + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/json" + "encoding/pem" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + "sync" + "time" + + "log" + + "github.com/dgrijalva/jwt-go" +) + +//validationUrl : is where the http request sent to +const validationUrl = `https://captcha.irisdev.net/check` + +var ( + // ErrHandlerTimeout = http.ErrHandlerTimeout + ErrSignatureInvalid = jwt.ErrSignatureInvalid + ErrMisMachIP = errors.New("the IPs are not matched") + ErrInvalidSecret = errors.New("Invalid Secret") +) + +// UserResponse : the standard defined for User Response +type UserResponse struct { + Success bool `json:"success"` + Hostname string `json:"hostname"` + IP string `json:"ip"` + jwt.StandardClaims +} + +// irisDev : the response Struct that resives from irisdev server +type irisServerResponse struct { + Code int `json:"Code"` // the Error Code 200 is OK / others shows Error - Note With Upper Case + Message string `json:"Message"` // error Message - Note with Upper Case + + Hostname string `json:"hostname"` // the hostname of the site where the Iris-Captcha was solved + Success bool `json:"success"` // true | false +} + +// The Global Handler +type IrisCaptchaHandler interface { + GetJs() string + Validate(string, string) (UserResponse, error) +} + +/** + * NewIrisCaptchaHandler + * Create a new Handle + * + * + */ +func NewIrisCaptchaHandler(secret string) (IrisCaptchaHandler, error) { + h := new(irisCaptchaHandler) + var err error + + h.provider = "https://captcha.irisdev.net" + err = h.init(secret) + return h, err +} + +/** + * NewIrisCaptchaHandlerRemote + * Create a new Handle that the server is not hosted on iris dev - Premium Service + * + * + */ +func NewIrisCaptchaHandlerRemote(provider string) (IrisCaptchaHandler, error) { + h := new(irisCaptchaHandler) + var err error + h.provider = provider + h.selfHosted = true + err = h.init("") + return h, err +} + +// irisCaptchaHandler the main Handler Object +type irisCaptchaHandler struct { + secret string + appUid string + + provider string + selfHosted bool + + js string + + publicKeyUpdateTime time.Time + publicKey *rsa.PublicKey + hasValidPublicKey bool + + sync.Mutex +} + +//init : +func (c *irisCaptchaHandler) init(secret string) error { + + if !c.selfHosted { + c.secret = secret + ss := strings.Split(secret, "0x") + if len(ss) < 2 { + return ErrInvalidSecret + } + c.appUid = "0x" + ss[len(ss)-1] + } + if err := c.loadPublicKey(); err != nil { + log.Printf("Couldn't Load Public-Key From %s , Using request mode\n", c.provider) + } + + c.js = fmt.Sprintf(`