diff --git a/config/config.go b/config/config.go index 6fb7a9d..acb09b7 100644 --- a/config/config.go +++ b/config/config.go @@ -9,48 +9,48 @@ import ( ) const Dir = "config/" -const AccountConf = Dir +"account.json" +const AccountConf = Dir + "account.json" -func GetAccount()map[string]string{ +func GetAccount() map[string]string { var account map[string]string - isExist,_:=tools.IsFileExist(AccountConf) - if !isExist{ + isExist, _ := tools.IsFileExist(AccountConf) + if !isExist { return account } - info,err:=ioutil.ReadFile(AccountConf) - if err!=nil{ + info, err := ioutil.ReadFile(AccountConf) + if err != nil { return account } - err=json.Unmarshal(info,&account) + err = json.Unmarshal(info, &account) return account } -func GetUserInfo(uid string)map[string]string{ +func GetUserInfo(uid string) map[string]string { var userInfo map[string]string - userFile:=Dir+"sess_"+uid+".json" - isExist,_:=tools.IsFileExist(userFile) - if !isExist{ + userFile := Dir + "sess_" + uid + ".json" + isExist, _ := tools.IsFileExist(userFile) + if !isExist { return userInfo } - info,err:=ioutil.ReadFile(userFile) - if err!=nil{ + info, err := ioutil.ReadFile(userFile) + if err != nil { return userInfo } - err=json.Unmarshal(info,&userInfo) + err = json.Unmarshal(info, &userInfo) return userInfo } -func SetUserInfo(uid string,info map[string]string){ - userFile:=Dir+"sess_"+uid+".json" - isExist,_:=tools.IsFileExist(Dir) - if !isExist{ - os.Mkdir(Dir,os.ModePerm) +func SetUserInfo(uid string, info map[string]string) { + userFile := Dir + "sess_" + uid + ".json" + isExist, _ := tools.IsFileExist(Dir) + if !isExist { + os.Mkdir(Dir, os.ModePerm) } file, _ := os.OpenFile(userFile, os.O_RDWR|os.O_CREATE, os.ModePerm) - str:="{\r\n" - for k,v:=range info{ - str+=fmt.Sprintf(`"%s":"%s",`,k,v) + str := "{\r\n" + for k, v := range info { + str += fmt.Sprintf(`"%s":"%s",`, k, v) } - str+=fmt.Sprintf(`"session_id":"%s"%s}`,uid,"\r\n") + str += fmt.Sprintf(`"session_id":"%s"%s}`, uid, "\r\n") file.WriteString(str) -} \ No newline at end of file +} diff --git a/controller/auth.go b/controller/auth.go index d3c931c..9265074 100644 --- a/controller/auth.go +++ b/controller/auth.go @@ -3,30 +3,59 @@ package controller import ( "github.com/taoshihan1991/imaptool/config" "github.com/taoshihan1991/imaptool/tools" + "log" ) -func AuthLocal(username string,password string)string{ - account:=config.GetAccount() - if account==nil{ - account=make(map[string]string) + +func CheckPass(username string, password string) string { + account := config.GetAccount() + if account == nil { + account = make(map[string]string) + } + if account["Username"] == "" && account["Password"] == "" { + account["Username"] = "admin" + account["Password"] = "admin123" + } + if username == account["Username"] && password == account["Password"] { + + sessionId := tools.Md5(username) + info := make(map[string]string) + info["username"] = username + config.SetUserInfo(sessionId, info) + return sessionId + } + return "" +} +func CheckAuth(token string) bool { + userinfo := tools.ParseToken(token) + log.Println(userinfo) + if userinfo == nil { + return false + } + return true +} +func AuthLocal(username string, password string) string { + account := config.GetAccount() + if account == nil { + account = make(map[string]string) } - if account["Username"]=="" && account["Password"]==""{ - account["Username"]="admin" - account["Password"]="admin123" + if account["Username"] == "" && account["Password"] == "" { + account["Username"] = "admin" + account["Password"] = "admin123" } - if username==account["Username"] && password==account["Password"]{ + if username == account["Username"] && password == account["Password"] { - sessionId:=tools.Md5(username) - info:=make(map[string]string) - info["username"]=username - config.SetUserInfo(sessionId,info) + sessionId := tools.Md5(username) + info := make(map[string]string) + info["username"] = username + config.SetUserInfo(sessionId, info) return sessionId } return "" } + //验证是否已经登录 -func AuthCheck(uid string)map[string]string{ - info:=config.GetUserInfo(uid) +func AuthCheck(uid string) map[string]string { + info := config.GetUserInfo(uid) return info } - diff --git a/controller/chat.go b/controller/chat.go index 2fea12f..1aa2749 100644 --- a/controller/chat.go +++ b/controller/chat.go @@ -16,17 +16,20 @@ func ActionChatMain(w http.ResponseWriter, r *http.Request) { render := tmpl.NewRender(w) render.Display("chat_main", nil) } + //聊天客户端界面 -func ActionChatPage(w http.ResponseWriter, r *http.Request){ +func ActionChatPage(w http.ResponseWriter, r *http.Request) { render := tmpl.NewRender(w) render.Display("chat_page", nil) } + //咨询界面 -func PageChat(c *gin.Context){ +func PageChat(c *gin.Context) { html := tools.FileGetContent("html/chat_page.html") c.Header("Content-Type", "text/html; charset=utf-8") c.String(200, html) } + //获取在线用户 func ChatUsers(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "text/json;charset=utf-8;") @@ -34,7 +37,7 @@ func ChatUsers(w http.ResponseWriter, r *http.Request) { for uid, _ := range clientList { userInfo := make(map[string]string) userInfo["uid"] = uid - userInfo["username"]=clientNameList[uid] + userInfo["username"] = clientNameList[uid] result = append(result, userInfo) } msg, _ := json.Marshal(tools.JsonListResult{ @@ -43,6 +46,7 @@ func ChatUsers(w http.ResponseWriter, r *http.Request) { }) w.Write(msg) } + type NoticeMessage struct { Type interface{} `json:"type"` Data interface{} `json:"data"` @@ -52,13 +56,13 @@ type TypeMessage struct { Data interface{} `json:"data"` } type KfMessage struct { - Kf_name string `json:"kf_name"` - Avatar string `json:"avatar"` - Kf_id string `json:"kf_id"` + Kf_name string `json:"kf_name"` + Avatar string `json:"avatar"` + Kf_id string `json:"kf_id"` Kf_group string `json:"kf_group"` - Time string `json:"time"` + Time string `json:"time"` Guest_id string `json:"guest_id"` - Content string `json:"content"` + Content string `json:"content"` } type UserMessage struct { From_avatar string `json:"from_avatar"` @@ -66,9 +70,10 @@ type UserMessage struct { From_name string `json:"from_name"` To_id string `json:"to_id"` To_name string `json:"to_name"` - Time string `json:"time"` + Time string `json:"time"` Content string `json:"content"` } + //定时检测客户端是否在线 func init() { sendPingToClient() @@ -91,11 +96,11 @@ func ChatServer(w *websocket.Conn) { var kfMsg KfMessage var userMsg UserMessage json.Unmarshal([]byte(receive), &typeMsg) - if typeMsg.Type==nil||typeMsg.Data==nil{ + if typeMsg.Type == nil || typeMsg.Data == nil { break } - msgType:=typeMsg.Type.(string) - msgData, _ :=json.Marshal(typeMsg.Data) + msgType := typeMsg.Type.(string) + msgData, _ := json.Marshal(typeMsg.Data) switch msgType { //获取当前在线的所有用户 @@ -103,39 +108,39 @@ func ChatServer(w *websocket.Conn) { getOnlineUser(w) //用户上线 case "userInit": - json.Unmarshal(msgData,&userMsg) + json.Unmarshal(msgData, &userMsg) //用户id对应的连接 clientList[userMsg.From_id] = w - clientNameList[userMsg.From_id]=userMsg.From_name + clientNameList[userMsg.From_id] = userMsg.From_name SendUserAllNotice() //客服上线 case "kfOnline": - json.Unmarshal(msgData,&kfMsg) + json.Unmarshal(msgData, &kfMsg) //客服id对应的连接 kefuList[kfMsg.Kf_id] = w //发送给客户 - if len(clientList)==0{ + if len(clientList) == 0 { break } for _, conn := range clientList { - SendKefuOnline(kfMsg,conn) + SendKefuOnline(kfMsg, conn) } //发送给客服通知 //SendOnekfuAllNotice(w) //客服接手 case "kfConnect": - json.Unmarshal(msgData,&kfMsg) + json.Unmarshal(msgData, &kfMsg) kefuList[kfMsg.Kf_id] = w - SendKefuOnline(kfMsg,clientList[kfMsg.Guest_id]) + SendKefuOnline(kfMsg, clientList[kfMsg.Guest_id]) case "kfChatMessage": - json.Unmarshal(msgData,&kfMsg) - conn:=clientList[kfMsg.Guest_id] - if kfMsg.Guest_id=="" ||conn==nil{ + json.Unmarshal(msgData, &kfMsg) + conn := clientList[kfMsg.Guest_id] + if kfMsg.Guest_id == "" || conn == nil { return } - msg:=NoticeMessage{ + msg := NoticeMessage{ Type: "kfChatMessage", - Data:KfMessage{ + Data: KfMessage{ Kf_name: kfMsg.Kf_name, Avatar: kfMsg.Avatar, Kf_id: kfMsg.Kf_id, @@ -144,110 +149,122 @@ func ChatServer(w *websocket.Conn) { Content: kfMsg.Content, }, } - str,_:=json.Marshal(msg);sendStr:=string(str) - websocket.Message.Send(conn,sendStr) + str, _ := json.Marshal(msg) + sendStr := string(str) + websocket.Message.Send(conn, sendStr) case "chatMessage": - json.Unmarshal(msgData,&userMsg) - conn:=kefuList[userMsg.To_id] - msg:=NoticeMessage{ + json.Unmarshal(msgData, &userMsg) + conn := kefuList[userMsg.To_id] + msg := NoticeMessage{ Type: "chatMessage", - Data:UserMessage{ + Data: UserMessage{ From_avatar: userMsg.From_avatar, From_id: userMsg.From_id, From_name: userMsg.From_name, To_id: userMsg.To_id, To_name: userMsg.To_name, Content: userMsg.Content, - Time: time.Now().Format("2006-01-02 15:04:05"), + Time: time.Now().Format("2006-01-02 15:04:05"), }, } - str,_:=json.Marshal(msg);sendStr:=string(str) - websocket.Message.Send(conn,sendStr) + str, _ := json.Marshal(msg) + sendStr := string(str) + websocket.Message.Send(conn, sendStr) } } } + //发送给所有客服客户上线 -func SendUserAllNotice(){ - if len(kefuList)!=0{ +func SendUserAllNotice() { + if len(kefuList) != 0 { //发送给客服通知 for _, conn := range kefuList { - msg:=NoticeMessage{ + msg := NoticeMessage{ Type: "notice", } - str,_:=json.Marshal(msg);sendStr:=string(str) - websocket.Message.Send(conn,sendStr) + str, _ := json.Marshal(msg) + sendStr := string(str) + websocket.Message.Send(conn, sendStr) } } } + //发送给客户客服上线 -func SendKefuOnline(kfMsg KfMessage,conn *websocket.Conn){ +func SendKefuOnline(kfMsg KfMessage, conn *websocket.Conn) { sendMsg := TypeMessage{ Type: "kfOnline", Data: KfMessage{ - Kf_name: kfMsg.Kf_name, - Avatar: kfMsg.Avatar, - Kf_id: kfMsg.Kf_id, + Kf_name: kfMsg.Kf_name, + Avatar: kfMsg.Avatar, + Kf_id: kfMsg.Kf_id, Kf_group: kfMsg.Kf_group, - Time: time.Now().Format("2006-01-02 15:04:05"), - Content: "客服上线", + Time: time.Now().Format("2006-01-02 15:04:05"), + Content: "客服上线", }, } jsonStrByte, _ := json.Marshal(sendMsg) websocket.Message.Send(conn, string(jsonStrByte)) } + //发送给所有客服客户上线 -func SendOnekfuAllNotice(conn *websocket.Conn){ +func SendOnekfuAllNotice(conn *websocket.Conn) { result := make([]map[string]string, 0) for uid, _ := range clientList { userInfo := make(map[string]string) userInfo["uid"] = uid - userInfo["username"]=clientNameList[uid] + userInfo["username"] = clientNameList[uid] result = append(result, userInfo) } - msg:=NoticeMessage{ + msg := NoticeMessage{ Type: "notice", - Data:result, + Data: result, } - str,_:=json.Marshal(msg);sendStr:=string(str) - websocket.Message.Send(conn,sendStr) + str, _ := json.Marshal(msg) + sendStr := string(str) + websocket.Message.Send(conn, sendStr) } + //获取当前的在线用户 -func getOnlineUser(w *websocket.Conn){ +func getOnlineUser(w *websocket.Conn) { result := make([]map[string]string, 0) for uid, _ := range clientList { userInfo := make(map[string]string) userInfo["uid"] = uid - userInfo["username"]=clientNameList[uid] + userInfo["username"] = clientNameList[uid] result = append(result, userInfo) } - msg:=NoticeMessage{ + msg := NoticeMessage{ Type: "getOnlineUsers", - Data:result, + Data: result, } - str,_:=json.Marshal(msg);sendStr:=string(str) - websocket.Message.Send(w,sendStr) + str, _ := json.Marshal(msg) + sendStr := string(str) + websocket.Message.Send(w, sendStr) } + //定时给客户端发送消息判断客户端是否在线 -func sendPingToClient(){ - msg:=NoticeMessage{ +func sendPingToClient() { + msg := NoticeMessage{ Type: "ping", } go func() { - for{ + for { log.Println("check online users...") - str,_:=json.Marshal(msg);sendStr:=string(str) + str, _ := json.Marshal(msg) + sendStr := string(str) for uid, conn := range clientList { - err:=websocket.Message.Send(conn,sendStr) - if err!=nil{ - delete(clientList,uid) + err := websocket.Message.Send(conn, sendStr) + if err != nil { + delete(clientList, uid) SendUserAllNotice() } } - time.Sleep(10*time.Second) + time.Sleep(10 * time.Second) } }() } + var clientList = make(map[string]*websocket.Conn) var clientNameList = make(map[string]string) -var kefuList = make(map[string]*websocket.Conn) \ No newline at end of file +var kefuList = make(map[string]*websocket.Conn) diff --git a/controller/folder.go b/controller/folder.go index bfe77ab..39b5837 100644 --- a/controller/folder.go +++ b/controller/folder.go @@ -9,11 +9,13 @@ import ( "strconv" "sync" ) + const PageSize = 20 + //输出列表 -func ActionFolder(w http.ResponseWriter, r *http.Request){ - fid:=tools.GetUrlArg(r,"fid") - currentPage, _ :=strconv.Atoi(tools.GetUrlArg(r,"page")) +func ActionFolder(w http.ResponseWriter, r *http.Request) { + fid := tools.GetUrlArg(r, "fid") + currentPage, _ := strconv.Atoi(tools.GetUrlArg(r, "page")) if fid == "" { fid = "INBOX" } @@ -23,28 +25,31 @@ func ActionFolder(w http.ResponseWriter, r *http.Request){ render := tmpl.NewFolderHtml(w) render.CurrentPage = currentPage render.Fid = fid - render.Display("list",render) + render.Display("list", render) } + //写信界面 -func ActionWrite(w http.ResponseWriter, r *http.Request){ - render:=tmpl.NewRender(w) +func ActionWrite(w http.ResponseWriter, r *http.Request) { + render := tmpl.NewRender(w) render.SetLeft("mail_left") - render.Display("write",nil) + render.Display("write", nil) } + //读信界面 -func ActionDetail(w http.ResponseWriter, r *http.Request){ - fid:=tools.GetUrlArg(r,"fid") - id, _ :=strconv.Atoi(tools.GetUrlArg(r,"id")) +func ActionDetail(w http.ResponseWriter, r *http.Request) { + fid := tools.GetUrlArg(r, "fid") + id, _ := strconv.Atoi(tools.GetUrlArg(r, "id")) - render:=tmpl.NewDetailHtml(w) + render := tmpl.NewDetailHtml(w) render.SetLeft("mail_left") - render.Fid=fid - render.Id=uint32(id) - render.Display("mail_detail",render) + render.Fid = fid + render.Id = uint32(id) + render.Display("mail_detail", render) } + //获取邮件夹接口 -func FolderDir(w http.ResponseWriter, r *http.Request){ - fid:=tools.GetUrlArg(r,"fid") +func FolderDir(w http.ResponseWriter, r *http.Request) { + fid := tools.GetUrlArg(r, "fid") if fid == "" { fid = "INBOX" @@ -69,10 +74,11 @@ func FolderDir(w http.ResponseWriter, r *http.Request){ }) w.Write(msg) } + //邮件夹接口 func FoldersList(w http.ResponseWriter, r *http.Request) { - fid:=tools.GetUrlArg(r,"fid") - currentPage, _ :=strconv.Atoi(tools.GetUrlArg(r,"page")) + fid := tools.GetUrlArg(r, "fid") + currentPage, _ := strconv.Atoi(tools.GetUrlArg(r, "page")) if fid == "" { fid = "INBOX" @@ -90,7 +96,6 @@ func FoldersList(w http.ResponseWriter, r *http.Request) { return } - var wg sync.WaitGroup wg.Add(2) result := make(map[string]interface{}) @@ -115,10 +120,11 @@ func FoldersList(w http.ResponseWriter, r *http.Request) { }) w.Write(msg) } + //邮件接口 func FolderMail(w http.ResponseWriter, r *http.Request) { - fid:=tools.GetUrlArg(r,"fid") - id, _ :=strconv.Atoi(tools.GetUrlArg(r,"id")) + fid := tools.GetUrlArg(r, "fid") + id, _ := strconv.Atoi(tools.GetUrlArg(r, "id")) mailServer := tools.GetMailServerFromCookie(r) w.Header().Set("content-type", "text/json;charset=utf-8;") @@ -154,8 +160,9 @@ func FolderMail(w http.ResponseWriter, r *http.Request) { }) w.Write(msg) } + //发送邮件接口 -func FolderSend(w http.ResponseWriter, r *http.Request){ +func FolderSend(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "text/json;charset=utf-8;") mailServer := tools.GetMailServerFromCookie(r) @@ -165,28 +172,28 @@ func FolderSend(w http.ResponseWriter, r *http.Request){ return } - bodyBytes,err:=ioutil.ReadAll(r.Body) - if err!=nil{ - msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "操作失败,"+err.Error()}) + bodyBytes, err := ioutil.ReadAll(r.Body) + if err != nil { + msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "操作失败," + err.Error()}) w.Write(msg) return } var sendData tools.SmtpBody err = json.Unmarshal(bodyBytes, &sendData) - if err!=nil{ - msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "操作失败,"+err.Error()}) + if err != nil { + msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: "操作失败," + err.Error()}) w.Write(msg) return } - smtpServer:=sendData.Smtp - smtpFrom:=mailServer.Email - smtpTo:=sendData.To - smtpBody:=sendData.Body - smtpPass:=mailServer.Password - smtpSubject:=sendData.Subject - err=tools.Send(smtpServer,smtpFrom,smtpPass,smtpTo,smtpSubject,smtpBody) - if err!=nil{ + smtpServer := sendData.Smtp + smtpFrom := mailServer.Email + smtpTo := sendData.To + smtpBody := sendData.Body + smtpPass := mailServer.Password + smtpSubject := sendData.Subject + err = tools.Send(smtpServer, smtpFrom, smtpPass, smtpTo, smtpSubject, smtpBody) + if err != nil { msg, _ := json.Marshal(tools.JsonResult{Code: 400, Msg: err.Error()}) w.Write(msg) return diff --git a/controller/index.go b/controller/index.go index 84b4655..b0ac9f4 100644 --- a/controller/index.go +++ b/controller/index.go @@ -4,8 +4,9 @@ import ( "github.com/taoshihan1991/imaptool/tools" "net/http" ) + //首页跳转 -func ActionIndex(w http.ResponseWriter, r *http.Request){ +func ActionIndex(w http.ResponseWriter, r *http.Request) { if r.URL.RequestURI() == "/favicon.ico" { return } diff --git a/controller/login.go b/controller/login.go index d4f6a4b..0cc55ff 100644 --- a/controller/login.go +++ b/controller/login.go @@ -6,16 +6,44 @@ import ( "github.com/gin-gonic/gin" "github.com/taoshihan1991/imaptool/tools" "html/template" + "log" "net/http" ) + //验证接口 func LoginCheckPass(c *gin.Context) { + authType := c.PostForm("type") + password := c.PostForm("password") + username := c.PostForm("username") + switch authType { + case "local": + sessionId := CheckPass(username, password) + userinfo := make(map[string]interface{}) + userinfo["name"] = username + token, err := tools.MakeToken(userinfo) + log.Println(err) + if sessionId != "" { + c.JSON(200, gin.H{ + "code": 200, + "msg": "验证成功,正在跳转", + "result": gin.H{ + "token": token, + }, + }) + return + } + c.JSON(200, gin.H{ + "code": 400, + "msg": "验证失败", + }) + } } -func ActionLogin(w http.ResponseWriter, r *http.Request){ +func ActionLogin(w http.ResponseWriter, r *http.Request) { html := tools.FileGetContent("html/login.html") t, _ := template.New("login").Parse(html) t.Execute(w, nil) } + //验证接口 func LoginCheck(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "text/json;charset=utf-8;") @@ -25,8 +53,8 @@ func LoginCheck(w http.ResponseWriter, r *http.Request) { switch authType { case "local": username := r.PostFormValue("username") - sessionId:=AuthLocal(username,password) - if sessionId!=""{ + sessionId := AuthLocal(username, password) + if sessionId != "" { tools.SetCookie("session_id", sessionId, &w) msg, _ = json.Marshal(tools.JsonResult{Code: 200, Msg: "验证成功,正在跳转..."}) w.Write(msg) diff --git a/controller/main.go b/controller/main.go index e6203df..cf6f35c 100644 --- a/controller/main.go +++ b/controller/main.go @@ -1,17 +1,34 @@ package controller import ( + "github.com/gin-gonic/gin" "github.com/taoshihan1991/imaptool/tmpl" "github.com/taoshihan1991/imaptool/tools" "net/http" ) -func ActionMain(w http.ResponseWriter, r *http.Request){ - sessionId:=tools.GetCookie(r,"session_id") - info:=AuthCheck(sessionId) - if len(info)==0{ + +func ActionMain(w http.ResponseWriter, r *http.Request) { + sessionId := tools.GetCookie(r, "session_id") + info := AuthCheck(sessionId) + if len(info) == 0 { http.Redirect(w, r, "/login", 302) return } - render:=tmpl.NewRender(w) - render.Display("main",render) + render := tmpl.NewRender(w) + render.Display("main", render) +} +func MainCheckAuth(c *gin.Context) { + token := c.Query("token") + r := CheckAuth(token) + if !r { + c.JSON(200, gin.H{ + "code": 400, + "msg": "验证失败", + }) + } else { + c.JSON(200, gin.H{ + "code": 200, + "msg": "验证成功", + }) + } } diff --git a/controller/mysql.go b/controller/mysql.go index 02682be..e6b7353 100644 --- a/controller/mysql.go +++ b/controller/mysql.go @@ -5,9 +5,9 @@ import ( "net/http" ) -func ActionMysqlSet(w http.ResponseWriter, r *http.Request){ - render:=tmpl.NewSettingHtml(w) +func ActionMysqlSet(w http.ResponseWriter, r *http.Request) { + render := tmpl.NewSettingHtml(w) render.SetLeft("setting_left") render.SetBottom("setting_bottom") - render.Display("mysql_setting",render) + render.Display("mysql_setting", render) } diff --git a/controller/notice.go b/controller/notice.go index 627f99b..2c9ac86 100644 --- a/controller/notice.go +++ b/controller/notice.go @@ -7,10 +7,12 @@ import ( "log" "net/http" ) + var upgrader = websocket.Upgrader{} var oldFolders map[string]int + //推送新邮件到达 -func PushMailServer(w http.ResponseWriter, r *http.Request){ +func PushMailServer(w http.ResponseWriter, r *http.Request) { c, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Print("upgrade:", err) @@ -28,26 +30,26 @@ func PushMailServer(w http.ResponseWriter, r *http.Request){ var msg []byte if mailServer == nil { msg, _ = json.Marshal(tools.JsonResult{Code: 400, Msg: "验证失败"}) - err = c.WriteMessage(mt,msg) + err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } - }else{ - folders:=tools.GetMailNum(mailServer.Server, mailServer.Email, mailServer.Password) - for name,num:=range folders{ - if oldFolders[name]!=num{ + } else { + folders := tools.GetMailNum(mailServer.Server, mailServer.Email, mailServer.Password) + for name, num := range folders { + if oldFolders[name] != num { result := make(map[string]interface{}) result["folder_name"] = name - result["new_num"] = num-oldFolders[name] + result["new_num"] = num - oldFolders[name] msg, _ := json.Marshal(tools.JsonListResult{ JsonResult: tools.JsonResult{Code: 200, Msg: "获取成功"}, Result: result, }) - c.WriteMessage(mt,msg) + c.WriteMessage(mt, msg) } } - oldFolders=folders + oldFolders = folders } } } diff --git a/controller/setting.go b/controller/setting.go index 8c25dc2..1ed7068 100644 --- a/controller/setting.go +++ b/controller/setting.go @@ -10,41 +10,40 @@ import ( "os" ) - -func ActionSetting(w http.ResponseWriter, r *http.Request){ - render:=tmpl.NewSettingHtml(w) +func ActionSetting(w http.ResponseWriter, r *http.Request) { + render := tmpl.NewSettingHtml(w) render.SetLeft("setting_left") render.SetBottom("setting_bottom") - account:=config.GetAccount() - render.Username=account["Username"] - render.Password=account["Password"] - render.Display("setting",render) + account := config.GetAccount() + render.Username = account["Username"] + render.Password = account["Password"] + render.Display("setting", render) } -func SettingAccount(w http.ResponseWriter, r *http.Request){ +func SettingAccount(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "text/json;charset=utf-8;") - username:=r.PostFormValue("username") - password:=r.PostFormValue("password") + username := r.PostFormValue("username") + password := r.PostFormValue("password") - isExist,_:=tools.IsFileExist(config.Dir) - if !isExist{ - os.Mkdir(config.Dir,os.ModePerm) + isExist, _ := tools.IsFileExist(config.Dir) + if !isExist { + os.Mkdir(config.Dir, os.ModePerm) } - fileConfig:=config.AccountConf + fileConfig := config.AccountConf file, _ := os.OpenFile(fileConfig, os.O_RDWR|os.O_CREATE, os.ModePerm) - format:=`{ + format := `{ "Username":"%s", "Password":"%s" } ` - data := fmt.Sprintf(format,username,password) + data := fmt.Sprintf(format, username, password) file.WriteString(data) msg, _ := json.Marshal(tools.JsonResult{Code: 200, Msg: "操作成功!"}) w.Write(msg) } -func SettingGetAccount(w http.ResponseWriter, r *http.Request){ +func SettingGetAccount(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "text/json;charset=utf-8;") mailServer := tools.GetMailServerFromCookie(r) @@ -53,7 +52,7 @@ func SettingGetAccount(w http.ResponseWriter, r *http.Request){ w.Write(msg) return } - result:=config.GetAccount() + result := config.GetAccount() msg, _ := json.Marshal(tools.JsonListResult{ JsonResult: tools.JsonResult{Code: 200, Msg: "获取成功"}, Result: result, diff --git a/controller/timer.go b/controller/timer.go index 92cbd4a..d2ed187 100644 --- a/controller/timer.go +++ b/controller/timer.go @@ -10,25 +10,28 @@ import ( "syscall" "time" ) + var osType = runtime.GOOS -const expireTime=30*60 + +const expireTime = 30 * 60 + //检测权限文件是否过期,超过30分钟删除掉 -func TimerSessFile(){ +func TimerSessFile() { go func() { for { - time.Sleep(time.Second*10) - files,_:=filepath.Glob(config.Dir+"sess_*") - for _,file:=range files{ + time.Sleep(time.Second * 10) + files, _ := filepath.Glob(config.Dir + "sess_*") + for _, file := range files { fileInfo, _ := os.Stat(file) var createTime int64 - now:=time.Now().Unix() + now := time.Now().Unix() if osType == "windows" { wFileSys := fileInfo.Sys().(*syscall.Win32FileAttributeData) - tNanSeconds := wFileSys.CreationTime.Nanoseconds() /// 返回的是纳秒 - createTime = tNanSeconds/1e9 ///秒 + tNanSeconds := wFileSys.CreationTime.Nanoseconds() /// 返回的是纳秒 + createTime = tNanSeconds / 1e9 ///秒 } - diffTime:=now-createTime - if diffTime>expireTime{ + diffTime := now - createTime + if diffTime > expireTime { os.Remove(file) } } diff --git a/controller/timer_linux.go b/controller/timer_linux.go index ca7a86e..f7aab88 100644 --- a/controller/timer_linux.go +++ b/controller/timer_linux.go @@ -8,24 +8,27 @@ import ( "runtime" "time" ) + var osType = runtime.GOOS -const expireTime=30*60 + +const expireTime = 30 * 60 + //检测权限文件是否过期,超过30分钟删除掉 -func TimerSessFile(){ +func TimerSessFile() { go func() { for { - time.Sleep(time.Second*10) - files,_:=filepath.Glob(config.Dir+"sess_*") - for _,file:=range files{ + time.Sleep(time.Second * 10) + files, _ := filepath.Glob(config.Dir + "sess_*") + for _, file := range files { fileInfo, _ := os.Stat(file) var createTime int64 - now:=time.Now().Unix() + now := time.Now().Unix() if osType == "linux" { stat_t := fileInfo.Sys().(*syscall.Stat_t) createTime = int64(stat_t.Ctim.Sec) } - diffTime:=now-createTime - if diffTime>expireTime{ + diffTime := now - createTime + if diffTime > expireTime { os.Remove(file) } } diff --git a/go.mod b/go.mod index f9751c0..6d0d81d 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require github.com/emersion/go-imap v1.0.4 require ( github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 + github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/emersion/go-message v0.11.2 github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 github.com/emersion/go-smtp v0.13.0 diff --git a/go.sum b/go.sum index 592f948..ebc9e01 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/emersion/go-imap v1.0.4 h1:uiCAIHM6Z5Jwkma1zdNDWWXxSCqb+/xHBkHflD7XBro= github.com/emersion/go-imap v1.0.4/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU= github.com/emersion/go-message v0.11.1/go.mod h1:C4jnca5HOTo4bGN9YdqNQM9sITuT3Y0K6bSUw9RklvY= diff --git a/server.go b/server.go index f262115..5932ffd 100644 --- a/server.go +++ b/server.go @@ -1,27 +1,34 @@ package main import ( - "github.com/taoshihan1991/imaptool/controller" "github.com/gin-gonic/gin" + "github.com/taoshihan1991/imaptool/controller" "github.com/taoshihan1991/imaptool/tmpl" "golang.org/x/net/websocket" "log" "net/http" "time" ) + func main() { - baseServer:="127.0.0.1:8080" - log.Println("start server...\r\ngo:http://"+baseServer) + baseServer := "127.0.0.1:8080" + log.Println("start server...\r\ngo:http://" + baseServer) engine := gin.Default() + engine.LoadHTMLGlob("static/html/*") //登陆界面 - engine.GET("/login",tmpl.PageLogin) + engine.GET("/login", tmpl.PageLogin) //咨询界面 - engine.GET("/chat_page",tmpl.PageChat) + engine.GET("/chat_page", tmpl.PageChat) //登陆验证 - engine.POST("/check",controller.LoginCheckPass) - + engine.POST("/check", controller.LoginCheckPass) + //框架界面 + engine.GET("/main", tmpl.PageMain) + //框架界面 + engine.GET("/chat_main", tmpl.PageChatMain) + //验证权限 + engine.GET("/check_auth", controller.MainCheckAuth) //------------------old code----------------------------- - mux:=&http.ServeMux{} + mux := &http.ServeMux{} //根路径 mux.HandleFunc("/", controller.ActionIndex) //邮件夹 @@ -53,13 +60,13 @@ func main() { //新邮件提醒服务 mux.HandleFunc("/push_mail", controller.PushMailServer) //聊天界面 - mux.HandleFunc("/chat_page",controller.ActionChatPage) + mux.HandleFunc("/chat_page", controller.ActionChatPage) //聊天服务 - mux.Handle("/chat_server",websocket.Handler(controller.ChatServer)) + mux.Handle("/chat_server", websocket.Handler(controller.ChatServer)) //获取在线用户 mux.HandleFunc("/chat_users", controller.ChatUsers) //设置mysql - mux.HandleFunc("/setting_mysql",controller.ActionMysqlSet) + mux.HandleFunc("/setting_mysql", controller.ActionMysqlSet) //后台任务 controller.TimerSessFile() //监听端口 diff --git a/static/html/login.html b/static/html/login.html index 18cae34..06fe433 100644 --- a/static/html/login.html +++ b/static/html/login.html @@ -160,7 +160,7 @@ message: data.msg, type: 'success' }); - window.location.href="/"; + //window.location.href="/"; }else{ _this.$message({ message: data.msg, @@ -195,7 +195,7 @@ message: data.msg, type: 'success' }); - window.location.href="/main"; + //window.location.href="/main"; }else{ _this.$message({ message: data.msg, diff --git a/tmpl/common.go b/tmpl/common.go index 1d2342b..b150d27 100644 --- a/tmpl/common.go +++ b/tmpl/common.go @@ -1,40 +1,55 @@ package tmpl import ( + "github.com/gin-gonic/gin" "github.com/taoshihan1991/imaptool/tools" "html/template" "net/http" ) -type CommonHtml struct{ - Header template.HTML - Nav template.HTML - Left template.HTML - Bottom template.HTML - Rw http.ResponseWriter +type CommonHtml struct { + Header template.HTML + Nav template.HTML + Left template.HTML + Bottom template.HTML + Rw http.ResponseWriter } -func NewRender(rw http.ResponseWriter)*CommonHtml{ - obj:=new(CommonHtml) - obj.Rw=rw + +func NewRender(rw http.ResponseWriter) *CommonHtml { + obj := new(CommonHtml) + obj.Rw = rw header := tools.FileGetContent("html/header.html") nav := tools.FileGetContent("html/nav.html") - obj.Header=template.HTML(header) - obj.Nav=template.HTML(nav) + obj.Header = template.HTML(header) + obj.Nav = template.HTML(nav) return obj } -func (obj *CommonHtml)SetLeft(file string){ - leftStr := tools.FileGetContent("html/"+file+".html") - obj.Left=template.HTML(leftStr) +func (obj *CommonHtml) SetLeft(file string) { + leftStr := tools.FileGetContent("html/" + file + ".html") + obj.Left = template.HTML(leftStr) } -func (obj *CommonHtml)SetBottom(file string){ - str := tools.FileGetContent("html/"+file+".html") - obj.Bottom=template.HTML(str) +func (obj *CommonHtml) SetBottom(file string) { + str := tools.FileGetContent("html/" + file + ".html") + obj.Bottom = template.HTML(str) } -func (obj *CommonHtml)Display(file string,data interface{}){ - if data==nil{ - data=obj +func (obj *CommonHtml) Display(file string, data interface{}) { + if data == nil { + data = obj } - main := tools.FileGetContent("html/"+file+".html") + main := tools.FileGetContent("html/" + file + ".html") t, _ := template.New(file).Parse(main) t.Execute(obj.Rw, data) -} \ No newline at end of file +} + +//登陆界面 +func PageMain(c *gin.Context) { + nav := tools.FileGetContent("html/nav.html") + c.HTML(http.StatusOK, "main.html", gin.H{ + "Nav": template.HTML(nav), + }) +} + +//客服界面 +func PageChatMain(c *gin.Context) { + c.HTML(http.StatusOK, "chat_main.html", nil) +} diff --git a/tmpl/detail.go b/tmpl/detail.go index 91f322f..f3e9114 100644 --- a/tmpl/detail.go +++ b/tmpl/detail.go @@ -5,11 +5,12 @@ import "net/http" type DetailHtml struct { *CommonHtml Fid string - Id uint32 + Id uint32 } -func NewDetailHtml(w http.ResponseWriter)*DetailHtml{ - obj:=new(DetailHtml) - parent:=NewRender(w) - obj.CommonHtml=parent + +func NewDetailHtml(w http.ResponseWriter) *DetailHtml { + obj := new(DetailHtml) + parent := NewRender(w) + obj.CommonHtml = parent return obj } diff --git a/tmpl/folder.go b/tmpl/folder.go index 0085e7d..d9fb677 100644 --- a/tmpl/folder.go +++ b/tmpl/folder.go @@ -1,15 +1,16 @@ package tmpl + import "net/http" type FolderHtml struct { *CommonHtml - CurrentPage int - Fid string + CurrentPage int + Fid string } -func NewFolderHtml(w http.ResponseWriter)*FolderHtml{ - obj:=new(FolderHtml) - parent:=NewRender(w) - obj.CommonHtml=parent + +func NewFolderHtml(w http.ResponseWriter) *FolderHtml { + obj := new(FolderHtml) + parent := NewRender(w) + obj.CommonHtml = parent return obj } - diff --git a/tmpl/login.go b/tmpl/login.go index 9c014b1..c58065d 100644 --- a/tmpl/login.go +++ b/tmpl/login.go @@ -6,17 +6,15 @@ import ( "html/template" "net/http" ) + //登陆界面 -func PageLogin(c *gin.Context){ - html := tools.FileGetContent("html/login.html") - c.Header("Content-Type", "text/html; charset=utf-8") - c.String(200, html) +func PageLogin(c *gin.Context) { + c.HTML(http.StatusOK, "login.html", nil) } + //咨询界面 -func PageChat(c *gin.Context){ - html := tools.FileGetContent("html/chat_page.html") - c.Header("Content-Type", "text/html; charset=utf-8") - c.String(200, html) +func PageChat(c *gin.Context) { + c.HTML(http.StatusOK, "chat_page.html", nil) } func RenderLogin(w http.ResponseWriter, render interface{}) { html := tools.FileGetContent("html/login.html") diff --git a/tmpl/setting.go b/tmpl/setting.go index 158dea6..3bb90e9 100644 --- a/tmpl/setting.go +++ b/tmpl/setting.go @@ -4,11 +4,12 @@ import "net/http" type SettingHtml struct { *CommonHtml - Username,Password string + Username, Password string } -func NewSettingHtml(w http.ResponseWriter)*SettingHtml{ - obj:=new(SettingHtml) - parent:=NewRender(w) - obj.CommonHtml=parent + +func NewSettingHtml(w http.ResponseWriter) *SettingHtml { + obj := new(SettingHtml) + parent := NewRender(w) + obj.CommonHtml = parent return obj } diff --git a/tools/imap.go b/tools/imap.go index b7f1231..deb03e7 100644 --- a/tools/imap.go +++ b/tools/imap.go @@ -63,6 +63,7 @@ func connect(server string, email string, password string) *client.Client { } return c } + //获取邮件总数 func GetMailNum(server string, email string, password string) map[string]int { var c *client.Client @@ -90,6 +91,7 @@ func GetMailNum(server string, email string, password string) map[string]int { } return folders } + //获取邮件夹 func GetFolders(server string, email string, password string, folder string) map[string]int { var c *client.Client @@ -143,9 +145,9 @@ func GetFolderMail(server string, email string, password string, folder string, messages := make(chan *imap.Message, pagesize) done := make(chan error, 1) - fetchItem:=imap.FetchItem(imap.FetchEnvelope) - items := make([]imap.FetchItem,0) - items=append(items,fetchItem) + fetchItem := imap.FetchItem(imap.FetchEnvelope) + items := make([]imap.FetchItem, 0) + items = append(items, fetchItem) go func() { done <- c.Fetch(seqset, items, messages) }() @@ -196,7 +198,7 @@ func GetMessage(server string, email string, password string, folder string, id seqSet.AddNum(id) // Get the whole message body - section:= &imap.BodySectionName{} + section := &imap.BodySectionName{} items := []imap.FetchItem{section.FetchItem()} messages := make(chan *imap.Message, 1) @@ -221,7 +223,6 @@ func GetMessage(server string, email string, password string, folder string, id // Create a new mail reader mr, _ := mail.CreateReader(r) - // Print some info about the message header := mr.Header date, _ := header.Date() diff --git a/tools/jwt.go b/tools/jwt.go new file mode 100644 index 0000000..df1d7cf --- /dev/null +++ b/tools/jwt.go @@ -0,0 +1,25 @@ +package tools + +import ( + "github.com/dgrijalva/jwt-go" + "time" +) + +const SECRET = "taoshihan" + +func MakeToken(obj map[string]interface{}) (string, error) { + obj["time"] = time.Now().Unix() + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims(obj)) + tokenString, err := token.SignedString([]byte(SECRET)) + return tokenString, err +} +func ParseToken(tokenStr string) map[string]interface{} { + token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (i interface{}, e error) { + return []byte(SECRET), nil + }) + if err != nil { + return nil + } + finToken := token.Claims.(jwt.MapClaims) + return finToken +} diff --git a/tools/session/session.go b/tools/session/session.go index 641fc8b..d4df28d 100644 --- a/tools/session/session.go +++ b/tools/session/session.go @@ -1,8 +1,8 @@ package session -func Set(name string,value string){ +func Set(name string, value string) { } -func Get(name string){ +func Get(name string) { -} \ No newline at end of file +} diff --git a/tools/smtp.go b/tools/smtp.go index bdcac90..301a990 100644 --- a/tools/smtp.go +++ b/tools/smtp.go @@ -6,17 +6,17 @@ import ( "strings" ) -func Send(server string,from string,password string,to []string,subject string,body string)error{ +func Send(server string, from string, password string, to []string, subject string, body string) error { auth := sasl.NewPlainClient("", from, password) msg := strings.NewReader( - "From: "+from+"\r\n"+ - "To: "+strings.Join(to,",")+"\r\n"+ - "Subject: "+subject+"\r\n" + - "\r\n" + - body+"\r\n") + "From: " + from + "\r\n" + + "To: " + strings.Join(to, ",") + "\r\n" + + "Subject: " + subject + "\r\n" + + "\r\n" + + body + "\r\n") err := smtp.SendMail(server, auth, from, to, msg) if err != nil { return err } return nil -} \ No newline at end of file +} diff --git a/tools/stringutil.go b/tools/stringutil.go index 57eb898..45a32f7 100644 --- a/tools/stringutil.go +++ b/tools/stringutil.go @@ -13,13 +13,15 @@ import ( "net/http" "strings" ) + //获取URL的GET参数 -func GetUrlArg(r *http.Request,name string)string{ +func GetUrlArg(r *http.Request, name string) string { var arg string values := r.URL.Query() - arg=values.Get(name) + arg = values.Get(name) return arg } + // Reverse 将其实参字符串以符文为单位左右反转。 func Reverse(s string) string { r := []rune(s) @@ -47,20 +49,22 @@ func DetermineEncoding(html string) (encoding.Encoding, string) { e, name, _ := charset.DetermineEncoding([]byte(html), "") return e, name } + //获取文件内容,可以打包到二进制 func FileGetContent(file string) string { str := "" - box := packr.New("tmpl","../static") + box := packr.New("tmpl", "../static") content, err := box.FindString(file) if err != nil { return str } return content } + //md5加密 -func Md5(src string)string{ - m:=md5.New() +func Md5(src string) string { + m := md5.New() m.Write([]byte(src)) - res:=hex.EncodeToString(m.Sum(nil)) + res := hex.EncodeToString(m.Sum(nil)) return res } diff --git a/tools/types.go b/tools/types.go index aa312f0..29a5fa6 100644 --- a/tools/types.go +++ b/tools/types.go @@ -5,9 +5,9 @@ import "html/template" type MailServer struct { Server, Email, Password string } -type ViewHtml struct{ - Header template.HTML - Nav template.HTML +type ViewHtml struct { + Header template.HTML + Nav template.HTML } type IndexData struct { ViewHtml @@ -44,11 +44,11 @@ type JsonListResult struct { JsonResult Result interface{} `json:"result"` } -type SmtpBody struct{ - Smtp string - From string - To []string +type SmtpBody struct { + Smtp string + From string + To []string Password string - Subject string - Body string + Subject string + Body string }