diff --git a/controller/login.go b/controller/login.go index 48f6180..3f6534b 100644 --- a/controller/login.go +++ b/controller/login.go @@ -3,6 +3,8 @@ package controller import ( "github.com/gin-gonic/gin" "github.com/taoshihan1991/imaptool/tools" + "log" + "net/url" "time" ) @@ -53,3 +55,20 @@ func LoginCheckPass(c *gin.Context) { }, }) } +//远程请求 +func PostBindOfficial(c *gin.Context) { + api := "https://gofly.v1kf.com/2/officialBindIp" + + phone := c.PostForm("phone") + password := c.PostForm("password") + host := c.Request.Host + data := url.Values{} + data.Set("phone", phone) + data.Set("password", password) + data.Set("host", host) + res, err := tools.PostForm(api, data) + if err != nil { + log.Println("绑定官网账户发送认证连接错误") + } + c.Writer.Write([]byte(res)) +} \ No newline at end of file diff --git a/go.mod b/go.mod index 993a26f..058f204 100644 --- a/go.mod +++ b/go.mod @@ -19,5 +19,6 @@ require ( github.com/satori/go.uuid v1.2.0 github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v0.0.5 + github.com/tidwall/gjson v1.14.1 github.com/zh-five/xdaemon v0.1.1 ) diff --git a/go.sum b/go.sum index 1ff9396..0889b24 100644 --- a/go.sum +++ b/go.sum @@ -146,6 +146,12 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo= +github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= diff --git a/middleware/domain_limit.go b/middleware/domain_limit.go new file mode 100644 index 0000000..38b2093 --- /dev/null +++ b/middleware/domain_limit.go @@ -0,0 +1,35 @@ +package middleware + +import ( + "github.com/gin-gonic/gin" + "github.com/taoshihan1991/imaptool/tools" + "log" +) + +/** +域名中间件 +*/ +func DomainLimitMiddleware(c *gin.Context) { + //离线或者远程 + if !CheckBindOffcial(c) { + c.Abort() + return + } + +} + + +//绑定官网账户 +func CheckBindOffcial(c *gin.Context) bool { + res, err := tools.HTTPGet("https://gofly.v1kf.com/2/isBindOfficial") + if err != nil { + log.Println("离线授权码失败,认证连接失败") + c.Redirect(302, "/bind") + c.Abort() + } + if string(res) != "success" { + c.Redirect(302, "/bind") + c.Abort() + } + return true +} diff --git a/router/api.go b/router/api.go index 45dffee..fdfcd82 100644 --- a/router/api.go +++ b/router/api.go @@ -17,6 +17,8 @@ func InitApiRouter(engine *gin.Engine) { v2.POST("/message", middleware.Ipblack, controller.SendMessageV2) //关闭连接 v2.GET("/message_close", controller.SendCloseMessageV2) + //绑定 + v2.POST("/bindOfficial", controller.PostBindOfficial) } engine.GET("/captcha", controller.GetCaptcha) engine.POST("/check", controller.LoginCheckPass) diff --git a/router/view.go b/router/view.go index 4cd08c0..5824f07 100644 --- a/router/view.go +++ b/router/view.go @@ -12,12 +12,11 @@ func InitViewRouter(engine *gin.Engine) { engine.GET("/install", tmpl.PageInstall) engine.GET("/detail_:page",tmpl.PageDetail) engine.GET("/login", tmpl.PageLogin) - engine.GET("/chat_page",tmpl.PageChat) - engine.GET("/chatIndex",tmpl.PageChat) - engine.GET("/chatKfIndex", tmpl.PageKfChat) + engine.GET("/bind", tmpl.PageBind) + engine.GET("/chatIndex",middleware.DomainLimitMiddleware,tmpl.PageChat) engine.GET("/main", middleware.JwtPageMiddleware, tmpl.PageMain) - engine.GET("/chat_main", middleware.JwtPageMiddleware, tmpl.PageChatMain) - engine.GET("/setting", tmpl.PageSetting) + engine.GET("/chat_main", middleware.JwtPageMiddleware,middleware.DomainLimitMiddleware, tmpl.PageChatMain) + engine.GET("/setting",middleware.DomainLimitMiddleware, tmpl.PageSetting) engine.GET("/setting_statistics", tmpl.PageSettingStatis) engine.GET("/setting_indexpage", tmpl.PageSettingIndexPage) engine.GET("/setting_indexpages", tmpl.PageSettingIndexPages) diff --git a/static/templates/bind.html b/static/templates/bind.html new file mode 100644 index 0000000..4885fdc --- /dev/null +++ b/static/templates/bind.html @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + +
+ +
+ + + + + diff --git a/tmpl/login.go b/tmpl/login.go index 3103758..4099a99 100644 --- a/tmpl/login.go +++ b/tmpl/login.go @@ -13,3 +13,7 @@ func PageLogin(c *gin.Context) { } c.HTML(http.StatusOK, "login.html", nil) } +//绑定界面 +func PageBind(c *gin.Context) { + c.HTML(http.StatusOK, "bind.html", gin.H{}) +} \ No newline at end of file diff --git a/tools/http.go b/tools/http.go index bbd8050..587db87 100644 --- a/tools/http.go +++ b/tools/http.go @@ -3,6 +3,7 @@ package tools import ( "io/ioutil" "net/http" + "net/url" "regexp" "strings" ) @@ -58,4 +59,17 @@ func IsMobile(userAgent string) bool { return true } return false +} +//发送http post请求数据为form +func PostForm(url string, data url.Values) (string, error) { + resp, err := http.PostForm(url, data) + if err != nil { + return "", err + } + defer resp.Body.Close() + content, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + return string(content), nil } \ No newline at end of file diff --git a/tools/http_tool.go b/tools/http_tool.go new file mode 100644 index 0000000..e2c2ba7 --- /dev/null +++ b/tools/http_tool.go @@ -0,0 +1,198 @@ +package tools + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "mime/multipart" + "net/http" + "os" +) + +// HTTPGet get 请求 +func HTTPGet(uri string) ([]byte, error) { + return HTTPGetContext(context.Background(), uri) +} + +// HTTPGetContext get 请求 +func HTTPGetContext(ctx context.Context, uri string) ([]byte, error) { + request, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return nil, err + } + response, err := http.DefaultClient.Do(request) + if err != nil { + return nil, err + } + + defer response.Body.Close() + if response.StatusCode != http.StatusOK { + return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode) + } + return ioutil.ReadAll(response.Body) +} + +// HTTPPost post 请求 +func HTTPPost(uri string, data string) ([]byte, error) { + return HTTPPostContext(context.Background(), uri, data) +} + +// HTTPPostContext post 请求 +func HTTPPostContext(ctx context.Context, uri string, data string) ([]byte, error) { + body := bytes.NewBuffer([]byte(data)) + request, err := http.NewRequestWithContext(ctx, http.MethodPost, uri, body) + if err != nil { + return nil, err + } + response, err := http.DefaultClient.Do(request) + if err != nil { + return nil, err + } + + defer response.Body.Close() + if response.StatusCode != http.StatusOK { + return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode) + } + return ioutil.ReadAll(response.Body) +} + +// PostJSON post json 数据请求 +func PostJSON(uri string, obj interface{}) ([]byte, error) { + jsonBuf := new(bytes.Buffer) + enc := json.NewEncoder(jsonBuf) + enc.SetEscapeHTML(false) + err := enc.Encode(obj) + if err != nil { + return nil, err + } + response, err := http.Post(uri, "application/json;charset=utf-8", jsonBuf) + if err != nil { + return nil, err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode) + } + return ioutil.ReadAll(response.Body) +} + +// PostJSONWithRespContentType post json数据请求,且返回数据类型 +func PostJSONWithRespContentType(uri string, obj interface{}) ([]byte, string, error) { + jsonBuf := new(bytes.Buffer) + enc := json.NewEncoder(jsonBuf) + enc.SetEscapeHTML(false) + err := enc.Encode(obj) + if err != nil { + return nil, "", err + } + + response, err := http.Post(uri, "application/json;charset=utf-8", jsonBuf) + if err != nil { + return nil, "", err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return nil, "", fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode) + } + responseData, err := ioutil.ReadAll(response.Body) + contentType := response.Header.Get("Content-Type") + return responseData, contentType, err +} + +// PostFile 上传文件 +func PostFile(fieldname, filename, uri string) ([]byte, error) { + fields := []MultipartFormField{ + { + IsFile: true, + Fieldname: fieldname, + Filename: filename, + }, + } + return PostMultipartForm(fields, uri) +} + +// MultipartFormField 保存文件或其他字段信息 +type MultipartFormField struct { + IsFile bool + Fieldname string + Value []byte + Filename string +} + +// PostMultipartForm 上传文件或其他多个字段 +func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte, err error) { + bodyBuf := &bytes.Buffer{} + bodyWriter := multipart.NewWriter(bodyBuf) + + for _, field := range fields { + if field.IsFile { + fileWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Filename) + if e != nil { + err = fmt.Errorf("error writing to buffer , err=%v", e) + return + } + + fh, e := os.Open(field.Filename) + if e != nil { + err = fmt.Errorf("error opening file , err=%v", e) + return + } + defer fh.Close() + + if _, err = io.Copy(fileWriter, fh); err != nil { + return + } + } else { + partWriter, e := bodyWriter.CreateFormField(field.Fieldname) + if e != nil { + err = e + return + } + valueReader := bytes.NewReader(field.Value) + if _, err = io.Copy(partWriter, valueReader); err != nil { + return + } + } + } + + contentType := bodyWriter.FormDataContentType() + bodyWriter.Close() + + resp, e := http.Post(uri, contentType, bodyBuf) + if e != nil { + err = e + return + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, err + } + respBody, err = ioutil.ReadAll(resp.Body) + return +} + +// PostXML perform a HTTP/POST request with XML body +func PostXML(uri string, obj interface{}) ([]byte, error) { + xmlData, err := xml.Marshal(obj) + if err != nil { + return nil, err + } + + body := bytes.NewBuffer(xmlData) + response, err := http.Post(uri, "application/xml;charset=utf-8", body) + if err != nil { + return nil, err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, response.StatusCode) + } + return ioutil.ReadAll(response.Body) +}