diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ed5bfa..43f881a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -## [0.3.3-pre] - 2022-07-01(UTC) +## [0.3.4-alpha] + +### Added + +### Changed + + +### Removed + +- Removed connect + +### Security + +### Fixed + +## [0.3.3-alpha] - 2022-07-01(UTC) ### Added diff --git a/conf/conf.conf.sample b/conf/conf.conf.sample index 5dfe5a6..682717f 100644 --- a/conf/conf.conf.sample +++ b/conf/conf.conf.sample @@ -15,7 +15,6 @@ TempPath = /var/lib/casaos/temp [server] HttpPort = 80 -UDPPort = RunMode = release ServerApi = https://api.casaos.io/casaos-api Handshake = socket.casaos.io diff --git a/main.go b/main.go index ccf2d9e..e230ff4 100644 --- a/main.go +++ b/main.go @@ -42,10 +42,6 @@ func init() { service.Cache = cache.Init() service.GetToken() - service.UDPAddressMap = make(map[string]string) - //go service.SocketConnect() - service.CancelList = make(map[string]string) - service.InternalInspection = make(map[string][]string) service.NewVersionApp = make(map[string]string) route.InitFunction() @@ -93,17 +89,7 @@ func main() { fmt.Println("Password:" + password) return } - go func() { - service.UDPService() - service.SendIPToServer() - }() go route.SocketInit(service.NotifyMsg) - go func() { - for i := 0; i < 1000; i++ { - time.Sleep(2 * time.Second) - //service.NotifyMsg <- strconv.Itoa(i) - } - }() //model.Setup() //gredis.Setup() @@ -111,20 +97,8 @@ func main() { //service.SyncTask(sqliteDB) cron2 := cron.New() //every day execution - err := cron2.AddFunc("0 0/5 * * * *", func() { - //service.PushIpInfo(*&config.ServerInfo.Token) - //service.UpdataDDNSList(mysqldb) - //service.SyncTask(sqliteDB) - service.SendIPToServer() - - service.LoopFriend() - //service.MyService.App().CheckNewImage() - }) - if err != nil { - fmt.Println(err) - } - err = cron2.AddFunc("0/5 * * * * *", func() { + err := cron2.AddFunc("0/5 * * * * *", func() { if service.ClientCount > 0 { //route.SendNetINfoBySocket() //route.SendCPUBySocket() diff --git a/model/sys_common.go b/model/sys_common.go index 68d9786..ce36035 100644 --- a/model/sys_common.go +++ b/model/sys_common.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 17:50:56 + * @LastEditTime: 2022-07-04 14:39:23 * @FilePath: /CasaOS/model/sys_common.go * @Description: * @Website: https://www.casaos.io @@ -39,7 +39,6 @@ type ServerModel struct { LockAccount bool Handshake string Token string - UDPPort string USBAutoMount string SocketPort string } diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go index b395b0e..e2f778a 100644 --- a/pkg/sqlite/db.go +++ b/pkg/sqlite/db.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-22 18:50:44 + * @LastEditTime: 2022-07-04 14:26:07 * @FilePath: /CasaOS/pkg/sqlite/db.go * @Description: * @Website: https://www.casaos.io @@ -42,8 +42,11 @@ func GetDb(dbPath string) *gorm.DB { return nil } gdb = db - err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersonDownloadDBModel{}, model2.FriendModel{}, model2.PersonDownRecordDBModel{}, model2.UserDBModel{}) + err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.UserDBModel{}) db.Exec("DROP TABLE IF EXISTS o_application") + db.Exec("DROP TABLE IF EXISTS o_friend") + db.Exec("DROP TABLE IF EXISTS o_person_download") + db.Exec("DROP TABLE IF EXISTS o_person_down_record") if err != nil { loger.Error("check or create db error", zap.Any("error", err)) } diff --git a/route/route.go b/route/route.go index 5d5c032..db65d98 100644 --- a/route/route.go +++ b/route/route.go @@ -43,8 +43,6 @@ func InitRouter() *gin.Engine { r.GET("/v1/user/avatar/:id", v1.GetUserAvatar) r.GET("/v1/user/image", v1.GetUserImage) - //get user info - r.GET("/v1/person/shareid", v1.GetPersonShareId) r.GET("/v1/sys/socket/port", v1.GetSystemSocketPort) //r.POST("/v1/user/refresh/token", v1.PostUserRefreshToken) v1Group := r.Group("/v1") @@ -196,32 +194,6 @@ func InitRouter() *gin.Engine { v1DiskGroup.DELETE("/delpart", v1.RemovePartition) v1DiskGroup.GET("/usb", v1.GetUSBList) - } - v1PersonGroup := v1Group.Group("/person") - v1PersonGroup.Use() - { - v1PersonGroup.GET("/detection", v1.GetPersonDetection) - v1PersonGroup.GET("/users", v1.GetPersonFriend) - v1PersonGroup.POST("/user/:shareids", v1.PostAddPersonFriend) - v1PersonGroup.DELETE("/user/:shareid", v1.DeletePersonFriend) - v1PersonGroup.GET("/directory", v1.GetPersonDirectory) - v1PersonGroup.GET("/file", v1.GetPersonFile) - v1PersonGroup.GET("/refile/:uuid", v1.GetPersonReFile) - v1PersonGroup.PUT("/remarks/:shareid", v1.PutPersonRemarks) - v1PersonGroup.GET("/list", v1.GetPersonDownloadList) - v1PersonGroup.DELETE("/file/:uuid", v1.DeletePersonDownloadFile) - - v1PersonGroup.POST("/share", v1.PostPersonShare) - v1PersonGroup.POST("/file/:shareid", v1.PostPersonFile) - v1PersonGroup.GET("/share", v1.GetPersonShare) - v1PersonGroup.POST("/down/dir", v1.PostPersonDownDir) - v1PersonGroup.GET("/down/dir", v1.GetPersonDownDir) - v1PersonGroup.PUT("/block/:shareid", v1.PutPersonBlock) - v1PersonGroup.GET("/public", v1.GetPersonPublic) - v1PersonGroup.PUT("/friend/:shareid", v1.PutPersonAgreeFriend) - v1PersonGroup.PUT("/write/:shareid", v1.PutPersonWrite) - v1PersonGroup.GET("/image/thumbnail/:shareid", v1.GetPersonImageThumbnail) - } v1Group.GET("/sync/config", v1.GetSyncConfig) } diff --git a/route/v1/person.go b/route/v1/person.go deleted file mode 100644 index 3385b2d..0000000 --- a/route/v1/person.go +++ /dev/null @@ -1,804 +0,0 @@ -package v1 - -import ( - "bytes" - "encoding/base64" - "encoding/gob" - "encoding/json" - "io/ioutil" - "net" - "net/http" - "os" - "reflect" - "strconv" - "strings" - "time" - - natType "github.com/Curtis-Milo/nat-type-identifier-go" - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - - "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/gin-gonic/gin" - uuid "github.com/satori/go.uuid" -) - -// @Summary Retry the file that failed to download -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param uui path string true "download uuid" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/refile/{uuid} [get] -func GetPersonReFile(c *gin.Context) { - - uid := c.Param("uuid") - _, err := uuid.FromString(uid) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - task := service.MyService.Download().GetDownloadById(uid) - if reflect.DeepEqual(task, model2.PersonDownloadDBModel{}) { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - token := task.From - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - - m := model.MessageModel{} - m.Data = task.Path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONDOWNLOAD - m.UUId = uid - go service.Dial(m, false) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary download file -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param share_id query string true "opponent share_id" -// @Param path query string true "file path" -// @Param file_name query string true "file name" -// @Param local_path query string true "local_path" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/file [get] -func GetPersonFile(c *gin.Context) { - - path := c.Query("path") - localPath := c.Query("local_path") - token := c.Query("share_id") - fileName := c.Query("file_name") - _, err := uuid.FromString(token) - if len(path) == 0 || err != nil || len(localPath) == 0 || len(fileName) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if file.CheckNotExist(localPath) { - c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) - return - } - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - - // task id - uuid := uuid.NewV4().String() - - task := model2.PersonDownloadDBModel{} - task.UUID = uuid - task.Name = fileName - task.Length = 0 - task.From = token - task.Path = path - task.Size = 0 - task.State = types.DOWNLOADAWAIT - task.Created = time.Now().Unix() - task.Type = types.PERSONFILEDOWNLOAD - task.LocalPath = localPath - if service.MyService.Download().GetDownloadListByPath(task) > 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)}) - return - } - service.MyService.Download().AddDownloadTask(task) - - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONDOWNLOAD - m.UUId = uuid - go service.Dial(m, false) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary delete download file records -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param uuid path string true "download uuid" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/file/{uuid} [delete] -func DeletePersonDownloadFile(c *gin.Context) { - - id := c.Param("uuid") - _, err := uuid.FromString(id) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - task := service.MyService.Download().GetDownloadById(id) - if task.State == types.DOWNLOADING { - m := model.MessageModel{} - m.Data = "" - m.From = config.ServerInfo.Token - m.To = task.From - m.Type = types.PERSONCANCEL - m.UUId = task.UUID - service.CancelList[task.UUID] = task.UUID - service.Dial(m, false) - } - service.MyService.Download().DelDownload(id) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get file download list -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param state query int false "wait:0,downloading:1,pause:2,finish:3,error:4,finished:5" Enums(0,1,2,3,4,5) -// @Security ApiKeyAuth -// @Success 200 {object} []model2.PersonDownloadDBModel -// @Router /person/list [get] -func GetPersonDownloadList(c *gin.Context) { - state := c.DefaultQuery("state", "") - list := service.MyService.Download().GetDownloadListByState(state, types.PERSONFILEDOWNLOAD) - //if it is downloading, it need to add 'already' - for i := 0; i < len(list); i++ { - if list[i].State == types.DOWNLOADING { - tempDir := config.AppInfo.TempPath + "/" + list[i].UUID - files, err := ioutil.ReadDir(tempDir) - if err == nil { - list[i].Already = len(files) - } - } - list[i].Duration = time.Now().Unix() - list[i].Created - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary edit friend's remarks -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param remarks formData string true "remarks name" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/remarks/{shareid} [put] -func PutPersonRemarks(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - mark := c.PostForm("remarks") - if err != nil || len(mark) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - friend := model2.FriendModel{} - friend.Token = token - friend.Mark = mark - service.MyService.Friend().EditFriendMark(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary edit friend's -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param write formData bool true "write" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/write/{shareid} [put] -func PutPersonWrite(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - write, _ := strconv.ParseBool(c.PostForm("write")) - friend := model2.FriendModel{} - friend.Token = token - friend.Write = write - service.MyService.Friend().EditFriendMark(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary image thumbnail -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param write formData bool true "write" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/image/thumbnail/{shareid} [get] -func GetPersonImageThumbnail(c *gin.Context) { - token := c.Param("shareid") - path := c.Query("path") - _, err := uuid.FromString(token) - if err != nil || len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONIMAGETHUMBNAIL - m.UUId = uuid - - img, err := service.Dial(m, false) - if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - - // var buf bytes.Buffer - //err = gob.NewEncoder(&buf).Encode(img.Data) - - if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - var buf bytes.Buffer - err = gob.NewEncoder(&buf).Encode(img.Data) - if err != nil { - c.JSON(http.StatusInternalServerError, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - - imageBuffer, _ := base64.StdEncoding.DecodeString(img.Data.(string)) - c.Writer.WriteString(string(imageBuffer)) - // c.String(http.StatusOK, "data:image/"+filesuffix+";base64,"+img.Data.(string)) - //c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: img.Data.(string)}) -} - -// @Summary get my friend list -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {object} []model2.FriendModel -// @Router /person/users [get] -func GetPersonFriend(c *gin.Context) { - list := service.MyService.Friend().GetFriendList() - for i := 0; i < len(list); i++ { - if v, ok := service.UDPAddressMap[list[i].Token]; ok && len(v) > 0 { - list[i].OnLine = true - if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) { - list[i].LocalIP = strings.Split(v, ":")[0] - } - } - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary network type detection -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/detection [get] -func GetPersonDetection(c *gin.Context) { - // - Blocked - // - Open Internet - // - Full Cone - // - Symmetric UDP Firewall - // - Restric NAT - // - Restric Port NAT - // - Symmetric NAT - - result, err := natType.GetDeterminedNatType(true, 5, "stun.l.google.com") - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - //result := service.MyService.Person().GetPersionNetWorkTypeDetection() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: result}) -} - -// @Summary add friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/user/{shareids} [post] -func PostAddPersonFriend(c *gin.Context) { - token := c.Param("shareids") - tokenList := strings.Split(token, ",") - - for _, v := range tokenList { - _, err := uuid.FromString(v) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - if v == config.ServerInfo.Token { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_MYSELF, Message: common_err.GetMsg(common_err.PERSON_MYSELF)}) - return - } - - udb := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: v}) - if !reflect.DeepEqual(udb, model2.FriendModel{Token: v}) { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_FRIEND, Message: common_err.GetMsg(common_err.PERSON_EXIST_FRIEND)}) - return - } - - user := service.MyService.Casa().GetUserInfoByShareId(v) - if reflect.DeepEqual(user, model.UserInfo{}) { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_NOT_EXIST_USER, Message: common_err.GetMsg(common_err.PERSON_NOT_EXIST_USER)}) - return - } - - message := model.MessageModel{} - message.Type = types.PERSONCONNECTION - message.Data = v - message.From = config.ServerInfo.Token - message.To = v - message.UUId = uuid.NewV4().String() - - go service.Dial(message, true) - - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = v - msg.UUId = uuid.NewV4().String() - - service.Dial(msg, true) - - friend := model2.FriendModel{} - friend.Token = v - friend.Avatar = user.Avatar - friend.Block = false - friend.State = types.FRIENDSTATEWAIT - friend.NickName = user.NickName - friend.Profile = user.Desc - friend.Version = user.Version - service.MyService.Friend().AddFriend(friend) - } - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get a list of directories -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param share_id query string true "Opponent share_id" -// @Param path query string true "dir path" -// @Security ApiKeyAuth -// @Success 200 {object} []model.Path -// @Router /person/directory [get] -func GetPersonDirectory(c *gin.Context) { - path := c.Query("path") - token := c.Query("share_id") - _, err := uuid.FromString(token) - if len(path) == 0 || err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if _, ok := service.UDPAddressMap[token]; !ok { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_REMOTE_ERROR, Message: common_err.GetMsg(common_err.PERSON_REMOTE_ERROR)}) - return - } - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONDIRECTORY - m.UUId = uuid - result, err := service.Dial(m, false) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - dataModel := []model.Path{} - if uuid == m.UUId { - dataModelByte, _ := json.Marshal(result.Data) - err := json.Unmarshal(dataModelByte, &dataModel) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - } - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: dataModel}) -} - -// @Summary Modify the download storage directory -// @Produce application/json -// @Accept multipart/form-data -// @Tags person -// @Security ApiKeyAuth -// @Param path formData string true "path" -// @Success 200 {string} string "ok" -// @Router /person/down/dir [post] -func PostPersonDownDir(c *gin.Context) { - - downPath := c.PostForm("path") - - if len(downPath) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if file.CheckNotExist(downPath) { - c.JSON(http.StatusOK, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) - return - } - config.Cfg.Section("file").Key("DownloadDir").SetValue(downPath) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - config.FileSettingInfo.DownloadDir = downPath - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get the download storage directory -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/down/dir [get] -func GetPersonDownDir(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.DownloadDir}) -} - -// @Summary Modify the shared directory -// @Produce application/json -// @Accept multipart/form-data -// @Tags person -// @Security ApiKeyAuth -// @Param share formData string true "share" -// @Success 200 {string} string "ok" -// @Router /person/share [post] -func PostPersonShare(c *gin.Context) { - - share := c.PostForm("share") - - if len(share) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - var list []string - json.Unmarshal([]byte(share), &list) - - if len(list) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - for _, v := range list { - if !file.Exists(v) { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) - return - } - } - - config.Cfg.Section("file").Key("ShareDir").SetValue(strings.Join(list, "|")) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - config.FileSettingInfo.ShareDir = list - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get the shared directory -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/share [get] -func GetPersonShare(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.FileSettingInfo.ShareDir}) -} - -// @Summary Get the shareid -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/shareid [get] -func GetPersonShareId(c *gin.Context) { - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: config.ServerInfo.Token}) -} - -// @Summary Modify disabled status -// @Produce application/json -// @Accept application/json -// @Tags person -// @Param block formData bool false "Disable or not,Default:false " -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/block/{shareid} [put] -func PutPersonBlock(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - block, _ := strconv.ParseBool(c.PostForm("block")) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - friend := model2.FriendModel{} - friend.Token = token - friend.Block = block - service.MyService.Friend().EditFriendBlock(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Delete my friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/user/{shareid} [delete] -func DeletePersonFriend(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - friend := model2.FriendModel{} - friend.Token = token - - service.MyService.Friend().DeleteFriend(friend) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary Get public person -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/public [get] -func GetPersonPublic(c *gin.Context) { - list := service.MyService.Casa().GetPersonPublic() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary upload file to friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Param path formData string true "Destination path" -// @Param local_path formData string true "Full path of the file to be uploaded" -// @Success 200 {string} string "ok" -// @Router /person/file/{shareid} [post] -func PostPersonFile(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - path := c.PostForm("path") - localPath := c.PostForm("local_path") - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - if !file.Exists(localPath) { - c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)}) - return - } - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = path - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONUPLOAD - m.UUId = uuid - go service.UDPSendData(m, localPath) - - f, _ := os.Stat(localPath) - - task := model2.PersonDownloadDBModel{} - task.UUID = uuid - task.Name = f.Name() - task.Length = 0 - task.From = token - task.Path = path - task.Size = f.Size() - task.State = types.DOWNLOADFINISHED - task.Created = time.Now().Unix() - task.Type = types.PERSONFILEUPLOAD - task.LocalPath = localPath - if service.MyService.Download().GetDownloadListByPath(task) > 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.PERSON_EXIST_DOWNLOAD, Message: common_err.GetMsg(common_err.PERSON_EXIST_DOWNLOAD)}) - return - } - service.MyService.Download().AddDownloadTask(task) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary agree add friend -// @Produce application/json -// @Accept application/json -// @Tags person -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /person/friend/{shareid} [put] -func PutPersonAgreeFriend(c *gin.Context) { - token := c.Param("shareid") - _, err := uuid.FromString(token) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - user := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: token}) - - if user.State != types.FRIENDSTATEREQUEST { - c.JSON(http.StatusOK, model.Result{Success: common_err.COMMAND_ERROR_INVALID_OPERATION, Message: common_err.GetMsg(common_err.COMMAND_ERROR_INVALID_OPERATION)}) - return - } - service.MyService.Friend().AgreeFrined(user.Token) - - uuid := uuid.NewV4().String() - m := model.MessageModel{} - m.Data = "" - m.From = config.ServerInfo.Token - m.To = token - m.Type = types.PERSONAGREEFRIEND - m.UUId = uuid - go service.Dial(m, true) - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// // @Summary upload file -// // @Produce application/json -// // @Accept multipart/form-data -// // @Tags person -// // @Security ApiKeyAuth -// // @Param path formData string false "file path" -// // @Param file formData file true "file" -// // @Success 200 {string} string "ok" -// // @Router /person/upload/{shareid} [get] -// func GetPersonFileUpload(c *gin.Context) { - -// token := c.Param("shareid") -// _, err := uuid.FromString(token) -// path := c.Query("path") -// if err != nil { -// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) -// return -// } - -// relative := c.Query("relativePath") -// fileName := c.Query("filename") -// chunkNumber := c.Query("chunkNumber") -// totalChunks, _ := strconv.Atoi(c.DefaultQuery("totalChunks", "0")) -// dirPath := "" -// hash := file.GetHashByContent([]byte(fileName)) -// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/" -// if fileName != relative { -// dirPath = strings.TrimSuffix(relative, fileName) -// tempDir += dirPath -// file.MkDir(path + "/" + dirPath) -// } -// tempDir += chunkNumber -// if !file.CheckNotExist(tempDir) { -// c.JSON(200, model.Result{Success: 200, Message: common_err.GetMsg(common_err.FILE_ALREADY_EXISTS)}) -// return -// } - -// c.JSON(204, model.Result{Success: 204, Message: common_err.GetMsg(common_err.SUCCESS)}) -// } - -// // @Summary upload file -// // @Produce application/json -// // @Accept multipart/form-data -// // @Tags person -// // @Security ApiKeyAuth -// // @Param path formData string false "file path" -// // @Param file formData file true "file" -// // @Success 200 {string} string "ok" -// // @Router /person/upload [post] -// func PostPersonFileUpload(c *gin.Context) { -// token := c.Param("shareid") -// _, err := uuid.FromString(token) -// if err != nil { -// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) -// return -// } -// f, _, _ := c.Request.FormFile("file") -// relative := c.PostForm("relativePath") -// fileName := c.PostForm("filename") -// totalChunks, _ := strconv.Atoi(c.DefaultPostForm("totalChunks", "0")) -// chunkNumber := c.PostForm("chunkNumber") -// dirPath := "" -// path := c.PostForm("path") - -// hash := file.GetHashByContent([]byte(fileName)) - -// if len(path) == 0 { -// c.JSON(common_err.INVALID_PARAMS, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) -// return -// } -// tempDir := "/casaOS/temp/" + hash + strconv.Itoa(totalChunks) + "/" - -// if fileName != relative { -// dirPath = strings.TrimSuffix(relative, fileName) -// tempDir += dirPath -// file.MkDir(path + "/" + dirPath) -// } - -// path += "/" + relative - -// if !file.CheckNotExist(tempDir + chunkNumber) { -// file.RMDir(tempDir + chunkNumber) -// } - -// if totalChunks > 1 { -// file.IsNotExistMkDir(tempDir) - -// out, _ := os.OpenFile(tempDir+chunkNumber, os.O_WRONLY|os.O_CREATE, 0644) -// defer out.Close() -// _, err := io.Copy(out, f) -// if err != nil { -// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) -// return -// } -// } else { -// out, _ := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) -// defer out.Close() -// _, err := io.Copy(out, f) -// if err != nil { -// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) -// return -// } -// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -// return -// } - -// fileNum, err := ioutil.ReadDir(tempDir) -// if err != nil { -// c.JSON(common_err.ERROR, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) -// return -// } -// if totalChunks == len(fileNum) { -// file.RMDir(tempDir) -// } - -// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -// } diff --git a/service/down_record.go b/service/down_record.go deleted file mode 100644 index dfeae97..0000000 --- a/service/down_record.go +++ /dev/null @@ -1,33 +0,0 @@ -package service - -import ( - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "gorm.io/gorm" -) - -type DownRecordService interface { - AddDownRecord(m model2.PersonDownRecordDBModel) - GetDownloadListByFrom(id string) []model2.PersonDownRecordDBModel - GetDownloadListByPath(path string) (list []model2.PersonDownRecordDBModel) -} -type downRecordService struct { - db *gorm.DB -} - -func (d *downRecordService) AddDownRecord(m model2.PersonDownRecordDBModel) { - d.db.Create(&m) -} - -func (d *downRecordService) GetDownloadListByFrom(id string) []model2.PersonDownRecordDBModel { - var m []model2.PersonDownRecordDBModel - d.db.Model(m).Where("from = ?", id).Find(&m) - return m -} -func (d *downRecordService) GetDownloadListByPath(path string) (list []model2.PersonDownRecordDBModel) { - d.db.Where("path = ?", path).Find(&list) - return -} - -func NewDownRecordService(db *gorm.DB) DownRecordService { - return &downRecordService{db: db} -} diff --git a/service/download.go b/service/download.go deleted file mode 100644 index 8a2ef8f..0000000 --- a/service/download.go +++ /dev/null @@ -1,66 +0,0 @@ -package service - -import ( - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "gorm.io/gorm" -) - -type DownloadService interface { - AddDownloadTask(m model2.PersonDownloadDBModel) //添加下载任务 - EditDownloadState(m model2.PersonDownloadDBModel) //只修改状态 - SaveDownload(m model2.PersonDownloadDBModel) - DelDownload(uuid string) - GetDownloadById(uuid string) model2.PersonDownloadDBModel - GetDownloadListByState(state string, t int) []model2.PersonDownloadDBModel - SetDownloadError(m model2.PersonDownloadDBModel) - GetDownloadListByPath(m model2.PersonDownloadDBModel) int -} -type downloadService struct { - db *gorm.DB -} - -func (d *downloadService) GetDownloadListByPath(m model2.PersonDownloadDBModel) int { - var list []model2.PersonDownloadDBModel - d.db.Select("path").Where("path = ? AND `from` = ? AND state = 0", m.Path, m.From).Find(&list) - return len(list) -} - -func (d *downloadService) AddDownloadTask(m model2.PersonDownloadDBModel) { - - d.db.Create(&m) -} -func (d *downloadService) EditDownloadState(m model2.PersonDownloadDBModel) { - - d.db.Model(&m).Where("uuid = ?", m.UUID).Update("state", m.State) -} - -//failed during download -func (d *downloadService) SetDownloadError(m model2.PersonDownloadDBModel) { - d.db.Model(&m).Updates(m) -} - -func (d *downloadService) DelDownload(uuid string) { - var m model2.PersonDownloadDBModel - d.db.Where("uuid = ?", uuid).Delete(&m) -} -func (d *downloadService) GetDownloadById(uuid string) model2.PersonDownloadDBModel { - var m model2.PersonDownloadDBModel - d.db.Model(m).Where("uuid = ?", uuid).First(&m) - return m -} -func (d *downloadService) GetDownloadListByState(state string, t int) (list []model2.PersonDownloadDBModel) { - if len(state) == 0 { - d.db.Where("type = ?", t).Find(&list) - } else { - d.db.Where("state = ? AND type= ?", state, t).Find(&list) - } - - return -} - -func (d *downloadService) SaveDownload(m model2.PersonDownloadDBModel) { - d.db.Save(&m) -} -func NewDownloadService(db *gorm.DB) DownloadService { - return &downloadService{db: db} -} diff --git a/service/friend.go b/service/friend.go deleted file mode 100644 index f81cb03..0000000 --- a/service/friend.go +++ /dev/null @@ -1,155 +0,0 @@ -package service - -import ( - "context" - "fmt" - "net" - "reflect" - "strconv" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/quic_helper" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/lucas-clemente/quic-go" - uuid "github.com/satori/go.uuid" - "gorm.io/gorm" -) - -type FriendService interface { - AddFriend(m model2.FriendModel) - DeleteFriend(m model2.FriendModel) - EditFriendMark(m model2.FriendModel) - EditFriendWrite(m model2.FriendModel) - EditFriendBlock(m model2.FriendModel) - GetFriendById(m model2.FriendModel) model2.FriendModel - GetFriendList() (list []model2.FriendModel) - GetFriendListRemote() (list []model2.FriendModel) - UpdateAddFriendType(m model2.FriendModel) - AgreeFrined(id string) - GetFriendByToken(token string) model2.FriendModel - UpdateOrCreate(m model2.FriendModel) - InternalInspection(ips []string, token string) -} - -type friendService struct { - db *gorm.DB -} - -func (p *friendService) AgreeFrined(id string) { - var m model2.FriendModel - p.db.Model(&m).Where("token = ?", id).Update("state", types.FRIENDSTATEDEFAULT) -} -func (p *friendService) AddFriend(m model2.FriendModel) { - p.db.Create(&m) -} -func (p *friendService) DeleteFriend(m model2.FriendModel) { - p.db.Where("token = ?", m.Token).Delete(&m) -} -func (p *friendService) EditFriendMark(m model2.FriendModel) { - p.db.Model(&m).Where("token = ?", m.Token).Update("mark", m.Mark) -} -func (p *friendService) EditFriendWrite(m model2.FriendModel) { - p.db.Model(&m).Where("token = ?", m.Token).Update("write", m.Write) -} -func (p *friendService) EditFriendBlock(m model2.FriendModel) { - p.db.Model(&m).Where("token = ?", m.Token).Update("block", m.Block) -} -func (p *friendService) GetFriendById(m model2.FriendModel) model2.FriendModel { - p.db.Model(m).Where("token = ?", m.Token).First(&m) - return m -} - -func (p *friendService) GetFriendList() (list []model2.FriendModel) { - p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Find(&list) - return list -} -func (p *friendService) GetFriendListRemote() (list []model2.FriendModel) { - p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Where("internal_ip == '' OR internal_ip is null").Find(&list) - return list -} -func (p *friendService) GetFriendListInternal() (list []model2.FriendModel) { - p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Where("internal_ip != ''").Find(&list) - return list -} -func (p *friendService) UpdateOrCreate(m model2.FriendModel) { - friend := model2.FriendModel{} - p.db.Where("token = ?", m.Token).First(&friend) - if reflect.DeepEqual(friend, model2.FriendModel{}) { - p.db.Create(&m) - } else { - p.db.Model(&m).Updates(m) - } - -} - -func (p *friendService) UpdateAddFriendType(m model2.FriendModel) { - p.db.Model(&m).Updates(m) -} - -func (p *friendService) GetFriendByToken(token string) model2.FriendModel { - var m model2.FriendModel - p.db.Model(&m).Where("token = ?", token).First(&m) - return m -} - -func (p *friendService) InternalInspection(ips []string, token string) { - for _, v := range ips { - fmt.Println("开始遍历 ip:", v) - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - - dstAddr, err := net.ResolveUDPAddr("udp", v) - if err != nil { - fmt.Println("1", err.Error()) - continue - } - port, err := strconv.Atoi(config.ServerInfo.UDPPort) - if err != nil { - fmt.Println("2", err) - continue - } - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: port} - ticket := token - session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig()) - if err != nil { - fmt.Println("3", err, v) - continue - } - - stream, err := session.OpenStreamSync(ctx) - if err != nil { - fmt.Println("4", err) - continue - } - uuid := uuid.NewV4().String() - SayHello(stream, token) - msg := model.MessageModel{ - Type: types.PERSONPING, - Data: "", - From: config.ServerInfo.Token, - To: token, - UUId: uuid, - } - - SendData(stream, msg) - - go ReadContent(stream) - result := <-Message - fmt.Println("ping返回结果:", result, msg) - stream.Close() - if !reflect.DeepEqual(result, model.MessageModel{}) && result.Data.(string) == token && result.From == token { - fmt.Println("获取到正确的ip", v) - UDPAddressMap[result.From] = v - p.db.Model(&model2.FriendModel{}).Where("token = ?", token).Update("internal_ip", v) - return - } - } -} - -func NewFriendService(db *gorm.DB) FriendService { - return &friendService{db: db} -} diff --git a/service/model/o_down_record.go b/service/model/o_down_record.go deleted file mode 100644 index 37a5966..0000000 --- a/service/model/o_down_record.go +++ /dev/null @@ -1,16 +0,0 @@ -package model - -type PersonDownRecordDBModel struct { - UUID string `gorm:"column:uuid;primary_key" json:"uuid"` - Name string `json:"name"` //file name - Type int `json:"type"` - Size int64 `json:"size"` //file size - Downloader string `json:"downloader"` //Error message - Path string `json:"path"` - Created int64 `gorm:"autoCreateTime" json:"created"` - Updated int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated"` -} - -func (p *PersonDownRecordDBModel) TableName() string { - return "o_person_down_record" -} diff --git a/service/model/o_download.go b/service/model/o_download.go deleted file mode 100644 index af0b2d3..0000000 --- a/service/model/o_download.go +++ /dev/null @@ -1,24 +0,0 @@ -package model - -type PersonDownloadDBModel struct { - UUID string `gorm:"column:uuid;primary_key" json:"uuid"` - State int `json:"state"` // - Type int `json:"type"` //defult 0 - Name string `json:"name"` //file name - Size int64 `json:"size"` //file size - BlockSize int `json:"block_size"` //Size of each file block - Length int `json:"length"` //slice length - Hash string `json:"hash"` //File hash value - Error string `json:"error"` // - From string `json:"from"` //Error message - Path string `json:"path"` //Full path to the file - Already int `json:"already" gorm:"-"` //Folder blocks that have been downloaded - LocalPath string `json:"local_path"` //The address where the file is saved after download - Duration int64 `json:"duration" gorm:"-"` //Length of time - Created int64 `gorm:"autoCreateTime" json:"created"` - Updated int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated"` -} - -func (p *PersonDownloadDBModel) TableName() string { - return "o_person_download" -} diff --git a/service/model/o_friend.go b/service/model/o_friend.go deleted file mode 100644 index daea6a9..0000000 --- a/service/model/o_friend.go +++ /dev/null @@ -1,21 +0,0 @@ -package model - -type FriendModel struct { - State int `json:"state"` - CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"` - UpdatedAt int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated_at"` - NickName string `json:"nick_name"` - Mark string `json:"mark"` //Remarks - Block bool `json:"block"` //Disable or not - Avatar string `json:"avatar"` //User avatar - Token string `gorm:"column:token;primary_key" json:"token"` - Profile string `json:"profile"` //Description - OnLine bool `json:"on_line" gorm:"-"` - Version int `json:"version"` - Write bool `json:"write"` - LocalIP string `json:"local_ip"` -} - -func (p *FriendModel) TableName() string { - return "o_friend" -} diff --git a/service/person.go b/service/person.go deleted file mode 100644 index a4aa9e6..0000000 --- a/service/person.go +++ /dev/null @@ -1,482 +0,0 @@ -package service - -import ( - "bufio" - "context" - "encoding/json" - "fmt" - "io" - "net" - "os" - "reflect" - "strconv" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/quic_helper" - "github.com/IceWhaleTech/CasaOS/pkg/utils" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" - "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/lucas-clemente/quic-go" - "gorm.io/gorm" -) - -type PersonService interface { - GetPersionInfo(token string) (m model.PersionModel, err error) - GetPersionNetWorkTypeDetection() string -} - -type personService struct { - db *gorm.DB -} - -var IpInfo model.PersionModel -var CancelList map[string]string -var InternalInspection map[string][]string - -func PushIpInfo(token string) { - - m := model.PersionModel{} - m.Ips = ip_helper.GetDeviceAllIP("") - m.Token = token - b, _ := json.Marshal(m) - - if reflect.DeepEqual(IpInfo, m) { - return - } - head := make(map[string]string) - infoS := httper2.Post(config.ServerInfo.Handshake+"/v1/update", b, "application/json", head) - fmt.Println(infoS) -} -func (p *personService) GetPersionInfo(token string) (m model.PersionModel, err error) { - infoS := httper2.Get(config.ServerInfo.Handshake+"/v1/ips/"+token, nil) - err = json.Unmarshal([]byte(infoS), &m) - return -} -func (p *personService) GetPersionNetWorkTypeDetection() string { - data := make(chan string) - list := []string{"stun.l.google.com", "stun1.l.google.com", "stun2.l.google.com", "stun.sipgate.net"} - for _, v := range list { - go utils.GetNetWorkTypeDetection(data, v) - } - result := <-data - close(data) - return result -} - -func NewPersonService(db *gorm.DB) PersonService { - return &personService{db: db} -} - -//======================================================================================================================================================================= - -var StreamList map[string]quic.Stream -var ServiceMessage chan model.MessageModel - -func UDPService() { - port := 0 - if len(config.ServerInfo.UDPPort) > 0 { - port, _ = strconv.Atoi(config.ServerInfo.UDPPort) - if port != 0 && !port2.IsPortAvailable(port, "udp") { - port = 0 - } - } - - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: port} - var err error - UDPConn, err = net.ListenUDP("udp", srcAddr) - if err != nil { - fmt.Println(err) - } - listener, err := quic.Listen(UDPConn, quic_helper.GetGenerateTLSConfig(config.ServerInfo.Token), quic_helper.GetQUICConfig()) - if err != nil { - fmt.Println(err) - } - defer listener.Close() - ctx := context.Background() - acceptFailures := 0 - const maxAcceptFailures = 10 - if err != nil { - panic(err) - } - - for { - select { - case <-ctx.Done(): - fmt.Println(ctx.Err()) - return - default: - } - - session, err := listener.Accept(ctx) - if err != nil { - fmt.Println("Listen (BEP/quic): Accepting connection:", err) - - acceptFailures++ - if acceptFailures > maxAcceptFailures { - // Return to restart the listener, because something - // seems permanently damaged. - fmt.Println(err) - return - } - - // Slightly increased delay for each failure. - time.Sleep(time.Duration(acceptFailures) * time.Second) - - continue - } - - acceptFailures = 0 - - streamCtx, cancel := context.WithTimeout(ctx, time.Second*10) - stream, err := session.AcceptStream(streamCtx) - cancel() - if err != nil { - fmt.Println("failed to accept stream from %s: %v", session.RemoteAddr(), err) - _ = session.CloseWithError(1, err.Error()) - continue - } - - // prefixByte := make([]byte, 4) - // c1, err := io.ReadFull(stream, prefixByte) - // fmt.Println(c1, err) - // prefixLength, err := strconv.Atoi(string(prefixByte)) - // if err != nil { - // fmt.Println(err) - // } - // messageByte := make([]byte, prefixLength) - // t, err := io.ReadFull(stream, messageByte) - // fmt.Println(t, err) - // m := model.MessageModel{} - // err = json.Unmarshal(messageByte, &m) - // if err != nil { - // fmt.Println(err) - // } - - go ProcessingContent(stream) - } -} - -//处理内容 -func ProcessingContent(stream quic.Stream) { - for { - prefixByte := make([]byte, 6) - _, err := io.ReadFull(stream, prefixByte) - if err != nil { - fmt.Println(err) - return - } - prefixLength, err := strconv.Atoi(string(prefixByte)) - if err != nil { - fmt.Println(err) - } - messageByte := make([]byte, prefixLength) - _, err = io.ReadFull(stream, messageByte) - if err != nil { - return - } - m := model.MessageModel{} - err = json.Unmarshal(messageByte, &m) - if err != nil { - fmt.Println(err) - } - if m.Type == types.PERSONHELLO { - //nothing - continue - } else if m.Type == types.PERSONDIRECTORY { - friend := model2.FriendModel{} - friend.Token = m.From - var list []model.Path - rFriend := MyService.Friend().GetFriendById(friend) - if !reflect.DeepEqual(rFriend, model2.FriendModel{Token: m.From}) && !rFriend.Block { - if m.Data.(string) == "" || m.Data.(string) == "/" { - for _, v := range config.FileSettingInfo.ShareDir { - //tempList := MyService.ZiMa().GetDirPath(v) - temp := MyService.System().GetDirPathOne(v) - list = append(list, temp) - } - } else { - list = MyService.System().GetDirPath(m.Data.(string)) - } - } else { - list = []model.Path{} - } - if rFriend.Write { - for i := 0; i < len(list); i++ { - list[i].Write = true - } - } - m.To = m.From - m.Data = list - m.From = config.ServerInfo.Token - SendData(stream, m) - break - } else if m.Type == types.PERSONDOWNLOAD { - - SendFileData(stream, m.Data.(string), m.From, m.UUId, types.PERSONDOWNLOAD) - break - } else if m.Type == types.PERSONADDFRIEND { - friend := model2.FriendModel{} - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &friend) - if err != nil { - fmt.Println(err) - continue - } - go MyService.Friend().UpdateOrCreate(friend) - mi := model2.FriendModel{} - mi.Avatar = config.UserInfo.Avatar - mi.Profile = config.UserInfo.Description - mi.NickName = config.UserInfo.NickName - m.To = m.From - m.Data = mi - m.Type = types.PERSONADDFRIEND - m.From = config.ServerInfo.Token - - SendData(stream, m) - break - } else if m.Type == types.PERSONCONNECTION { - if len(m.Data.(string)) > 0 { - fmt.Println("设置ip", m.Data.(string)) - UDPAddressMap[m.From] = m.Data.(string) - } else { - delete(UDPAddressMap, m.From) - } - // mi := model2.FriendModel{} - // mi.Avatar = config.UserInfo.Avatar - // mi.Profile = config.UserInfo.Description - // mi.NickName = config.UserInfo.NickName - // mi.Token = config.ServerInfo.Token - - user := MyService.Casa().GetUserInfoByShareId(m.From) - //好友申请 //不是好友 - friend := model2.FriendModel{} - friend.Token = m.From - friend.Avatar = user.Avatar - friend.Block = false - friend.NickName = user.NickName - friend.Profile = user.Avatar - friend.Write = false - friend.Version = user.Version - if len(config.UserInfo.Public) > 0 { - friend.State = types.FRIENDSTATEREQUEST - } - MyService.Friend().AddFriend(friend) - - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "" - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - Dial(msg, false) - - //agree user - if len(config.UserInfo.Public) == 0 { - msg.Type = types.PERSONAGREEFRIEND - msg.Data = "" - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - Dial(msg, true) - } - break - } else if m.Type == types.PERSONAGREEFRIEND { - MyService.Friend().AgreeFrined(m.From) - break - } else if m.Type == types.PERSONCANCEL { - CancelList[m.UUId] = "cancel" - break - } else if m.Type == types.PERSONSUMMARY { - Summary(m, "upload") - continue - } else if m.Type == types.PERSONUPLOAD { - //TODO:检查是否存在如果存在直接结束 - task := model2.PersonDownloadDBModel{} - task.UUID = m.UUId - task.LocalPath = m.Data.(string) - MyService.Download().AddDownloadTask(task) - friend := MyService.Friend().GetFriendById(model2.FriendModel{Token: m.From}) - if friend.Write { - continue - } else { - break - } - } else if m.Type == types.PERSONUPLOADDATA { - r := SaveFile(m, stream) - if r { - break - } - continue - } else if m.Type == types.PERSONINTERNALINSPECTION { - fmt.Println("内网测试") - var ips []string - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &ips) - if err != nil { - fmt.Println(err) - break - } - - go MyService.Friend().InternalInspection(ips, m.From) - - } else if m.Type == types.PERSONPING { - fmt.Println("来自", m.From, "的ping", m.Data) - msg := m - m.To = m.From - m.Data = config.ServerInfo.Token - m.From = config.ServerInfo.Token - SendData(stream, m) - - var ips []string - dataModelByte, _ := json.Marshal(msg.Data) - err := json.Unmarshal(dataModelByte, &ips) - if err != nil { - fmt.Println(err) - break - } - backIP := false - if v, ok := UDPAddressMap[msg.From]; ok { - for _, ip := range ips { - if ip == v { - backIP = true - break - } - } - } - if !backIP { - fmt.Println("检测需要查询ip", msg.From) - go MyService.Friend().InternalInspection(ips, msg.From) - } - - break - } else if m.Type == types.PERSONIMAGETHUMBNAIL { - m.To = m.From - - if data, err := file.GetImage(m.Data.(string), 100, 0); err == nil { - m.Data = data - } else { - m.Data = "" - } - m.From = config.ServerInfo.Token - SendData(stream, m) - break - } else { - //不应有不做返回的数据 - //ServiceMessage <- m - break - } - } - stream.Close() - -} - -//文件分片发送 -func SendFileData(stream quic.Stream, filePath, to, uuid, t string) error { - summary := model.FileSummaryModel{} - - msg := model.MessageModel{} - msg.Type = types.PERSONSUMMARY - msg.From = config.ServerInfo.Token - msg.To = to - msg.UUId = uuid - - fStat, err := os.Stat(filePath) - if err != nil { - - summary.Message = err.Error() - - msg.Data = summary - - summaryByte, _ := json.Marshal(msg) - summaryPrefixLength := file.PrefixLength(len(summaryByte)) - summaryData := append(summaryPrefixLength, summaryByte...) - stream.Write(summaryData) - return err - } - - blockSize, length := file.GetBlockInfo(fStat.Size()) - - f, err := os.Open(filePath) - if err != nil { - - summary.Message = err.Error() - msg.Data = summary - - summaryByte, _ := json.Marshal(msg) - summaryPrefixLength := file.PrefixLength(len(summaryByte)) - summaryData := append(summaryPrefixLength, summaryByte...) - stream.Write(summaryData) - return err - } - - //send file summary first - summary.BlockSize = blockSize - summary.Hash = file.GetHashByPath(filePath) - summary.Length = length - summary.Name = fStat.Name() - summary.Size = fStat.Size() - - msg.Data = summary - - summaryByte, _ := json.Marshal(msg) - summaryPrefixLength := file.PrefixLength(len(summaryByte)) - summaryData := append(summaryPrefixLength, summaryByte...) - stream.Write(summaryData) - - bufferedReader := bufio.NewReader(f) - buf := make([]byte, blockSize) - - defer stream.Close() - - for i := 0; i < length; i++ { - - tran := model.TranFileModel{} - - n, err := bufferedReader.Read(buf) - - if err == io.EOF { - fmt.Println("读取完毕", err) - } - - tran.Hash = file.GetHashByContent(buf[:n]) - tran.Index = i - tran.Length = length - - fileMsg := model.MessageModel{} - fileMsg.Type = t - fileMsg.Data = tran - fileMsg.From = config.ServerInfo.Token - fileMsg.To = to - fileMsg.UUId = uuid - b, _ := json.Marshal(fileMsg) - prefixLength := file.PrefixLength(len(b)) - dataLength := file.DataLength(len(buf[:n])) - data := append(append(append(prefixLength, b...), dataLength...), buf[:n]...) - if _, ok := CancelList[uuid]; ok { - delete(CancelList, uuid) - return nil - } - stream.Write(data) - } - record := model2.PersonDownRecordDBModel{} - record.UUID = uuid - record.Name = f.Name() - record.Downloader = to - record.Path = filePath - record.Size = fStat.Size() - record.Type = types.PERSONFILEDOWNLOAD - if t == types.PERSONUPLOADDATA { - record.Type = types.PERSONFILEUPLOAD - } - - MyService.DownRecord().AddDownRecord(record) - - return nil -} diff --git a/service/service.go b/service/service.go index 1087d94..6d58b56 100644 --- a/service/service.go +++ b/service/service.go @@ -24,67 +24,42 @@ type Repository interface { Rely() RelyService System() SystemService Shortcuts() ShortcutsService - Person() PersonService - Friend() FriendService - Download() DownloadService - DownRecord() DownRecordService } func NewService(db *gorm.DB) Repository { - return &store{ - app: NewAppService(db), - user: NewUserService(db), - docker: NewDockerService(), - casa: NewCasaService(), - disk: NewDiskService(db), - notify: NewNotifyService(db), - rely: NewRelyService(db), - system: NewSystemService(), - shortcuts: NewShortcutsService(db), - person: NewPersonService(db), - friend: NewFriendService(db), - download: NewDownloadService(db), - downrecord: NewDownRecordService(db), + app: NewAppService(db), + user: NewUserService(db), + docker: NewDockerService(), + casa: NewCasaService(), + disk: NewDiskService(db), + notify: NewNotifyService(db), + rely: NewRelyService(db), + system: NewSystemService(), + shortcuts: NewShortcutsService(db), } } type store struct { - db *gorm.DB - app AppService - user UserService - docker DockerService - casa CasaService - disk DiskService - notify NotifyServer - rely RelyService - system SystemService - shortcuts ShortcutsService - person PersonService - friend FriendService - download DownloadService - downrecord DownRecordService + db *gorm.DB + app AppService + user UserService + docker DockerService + casa CasaService + disk DiskService + notify NotifyServer + rely RelyService + system SystemService + shortcuts ShortcutsService } -func (c *store) DownRecord() DownRecordService { - return c.downrecord -} - -func (c *store) Download() DownloadService { - return c.download -} -func (c *store) Friend() FriendService { - return c.friend -} func (c *store) Rely() RelyService { return c.rely } func (c *store) Shortcuts() ShortcutsService { return c.shortcuts } -func (c *store) Person() PersonService { - return c.person -} + func (c *store) System() SystemService { return c.system } diff --git a/service/udpconn.go b/service/udpconn.go deleted file mode 100644 index 20adb01..0000000 --- a/service/udpconn.go +++ /dev/null @@ -1,503 +0,0 @@ -package service - -import ( - "context" - "crypto/md5" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net" - "os" - path2 "path" - "reflect" - "strconv" - "strings" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/model/notify" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/quic_helper" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/lucas-clemente/quic-go" - uuid "github.com/satori/go.uuid" -) - -var UDPConn *net.UDPConn -var PeopleMap map[string]quic.Stream -var Message chan model.MessageModel -var UDPAddressMap map[string]string - -func UDPSendData(msg model.MessageModel, localFilePath string) error { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - Message = make(chan model.MessageModel) - _, port, err := net.SplitHostPort(UDPConn.LocalAddr().String()) - if config.ServerInfo.UDPPort != port { - config.ServerInfo.UDPPort = port - config.Cfg.Section("server").Key("UDPPort").SetValue(port) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - } - p, err := strconv.Atoi(port) - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: p} //注意端口必须固定 - addr := UDPAddressMap[msg.To] - ticket := msg.To - dstAddr, err := net.ResolveUDPAddr("udp", addr) - - session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig()) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - - return err - } - - stream, err := session.OpenStreamSync(ctx) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - session.CloseWithError(1, err.Error()) - return err - } - - SayHello(stream, msg.To) - //TODO:发送 - SendData(stream, msg) - SendFileData(stream, localFilePath, msg.To, msg.UUId, types.PERSONUPLOADDATA) - - stream.Close() - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, "OK", msg.From, msg.To, msg.Type) - } - return nil -} - -func Dial(msg model.MessageModel, server bool) (m model.MessageModel, err error) { - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) - defer cancel() - Message = make(chan model.MessageModel) - _, port, err := net.SplitHostPort(UDPConn.LocalAddr().String()) - if config.ServerInfo.UDPPort != port { - config.ServerInfo.UDPPort = port - config.Cfg.Section("server").Key("UDPPort").SetValue(port) - config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) - } - p, err := strconv.Atoi(port) - srcAddr := &net.UDPAddr{ - IP: net.IPv4zero, Port: p} //注意端口必须固定 - addr := UDPAddressMap[msg.To] - ticket := msg.To - if server { - addr = config.ServerInfo.Handshake + ":9527" - ticket = "bench" - } - dstAddr, err := net.ResolveUDPAddr("udp", addr) - - //DialTCP在网络协议net上连接本地地址laddr和远端地址raddr。net必须是"udp"、"udp4"、"udp6";如果laddr不是nil,将使用它作为本地地址,否则自动选择一个本地地址。 - //(conn)UDPConn代表一个UDP网络连接,实现了Conn和PacketConn接口 - - session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig()) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - - return m, err - } - - stream, err := session.OpenStreamSync(ctx) - if err != nil { - if msg.Type == types.PERSONDOWNLOAD { - task := MyService.Download().GetDownloadById(msg.UUId) - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type) - } - session.CloseWithError(1, err.Error()) - return m, err - } - - SayHello(stream, msg.To) - - SendData(stream, msg) - - go ReadContent(stream) - result := <-Message - stream.Close() - if config.SystemConfigInfo.Analyse != "False" { - go MyService.Casa().PushConnectionStatus(msg.UUId, "OK", msg.From, msg.To, msg.Type) - } - return result, nil -} - -func SayHello(stream quic.Stream, to string) { - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "hello" - msg.To = to - msg.From = config.ServerInfo.Token - msg.UUId = uuid.NewV4().String() - SendData(stream, msg) -} - -//发送数据 -func SendData(stream quic.Stream, m model.MessageModel) { - b, _ := json.Marshal(m) - prefixLength := file.PrefixLength(len(b)) - data := append(prefixLength, b...) - stream.Write(data) -} - -//读取数据 -func ReadContent(stream quic.Stream) { - for { - prefixByte := make([]byte, 6) - _, err := io.ReadFull(stream, prefixByte) - if err != nil { - fmt.Println(err) - time.Sleep(time.Second * 1) - for k, v := range CancelList { - tempPath := config.AppInfo.TempPath + "/" + v - fmt.Println(file.RMDir(tempPath)) - delete(CancelList, k) - } - break - } - prefixLength, err := strconv.Atoi(string(prefixByte)) - if err != nil { - fmt.Println(err) - break - } - messageByte := make([]byte, prefixLength) - _, err = io.ReadFull(stream, messageByte) - if err != nil { - fmt.Println(err) - break - } - m := model.MessageModel{} - err = json.Unmarshal(messageByte, &m) - if err != nil { - fmt.Println(err) - break - } - if m.Type == types.PERSONDOWNLOAD { - r := SaveFile(m, stream) - if r { - break - } - } else if m.Type == types.PERSONSUMMARY { - Summary(m, "download") - } else if m.Type == types.PERSONCONNECTION { - if len(m.Data.(string)) > 0 { - UDPAddressMap[m.From] = m.Data.(string) - } else { - delete(UDPAddressMap, m.From) - } - // mi := model2.FriendModel{} - // mi.Avatar = config.UserInfo.Avatar - // mi.Profile = config.UserInfo.Description - // mi.NickName = config.UserInfo.NickName - // mi.Token = config.ServerInfo.Token - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "" - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - go Dial(msg, false) - Message <- m - break - } else if m.Type == types.PERSONGETIP { - notify := notify.Person{} - notify.ShareId = m.From - if len(m.Data.(string)) == 0 { - if _, ok := UDPAddressMap[m.From]; ok { - notify.Type = "OFFLINE" - go MyService.Notify().SendPersonStatusBySocket(notify) - } - delete(UDPAddressMap, m.From) - Message <- m - break - } - if _, ok := UDPAddressMap[m.From]; !ok { - notify.Type = "ONLINE" - go MyService.Notify().SendPersonStatusBySocket(notify) - } - UDPAddressMap[m.From] = m.Data.(string) - if config.ServerInfo.Token != m.From && strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0] { - msg := model.MessageModel{} - msg.Type = types.PERSONINTERNALINSPECTION - msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort) - msg.To = m.From - msg.From = config.ServerInfo.Token - msg.UUId = m.UUId - go Dial(msg, true) - } - - Message <- m - break - } else if m.Type == types.PERSONINTERNALINSPECTION { - fmt.Println("接收到反验证") - var ips []string - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &ips) - if err != nil { - fmt.Println(err) - break - } - go MyService.Friend().InternalInspection(ips, m.From) - Message <- m - break - } else { - - Message <- m - } - } - Message <- model.MessageModel{} -} - -func SendIPToServer() { - msg := model.MessageModel{} - msg.Type = types.PERSONHELLO - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = config.ServerInfo.Token - msg.UUId = uuid.NewV4().String() - - Dial(msg, true) -} - -func LoopFriend() { - list := MyService.Friend().GetFriendList() - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = config.ServerInfo.Token - msg.UUId = uuid.NewV4().String() - Dial(msg, true) - - for i := 0; i < len(list); i++ { - if _, ok := UDPAddressMap[list[i].Token]; !ok { - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = list[i].Token - msg.UUId = uuid.NewV4().String() - Dial(msg, true) - } - - msg.Type = types.PERSONPING - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = list[i].Token - msg.UUId = uuid.NewV4().String() - - if v, ok := UDPAddressMap[list[i].Token]; ok { - if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) { - msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort) - } - oldIP := UDPAddressMap[list[i].Token] - data, err := Dial(msg, false) - if err != nil || reflect.DeepEqual(data, model.MessageModel{}) || len(data.Data.(string)) == 0 { - if oldIP == UDPAddressMap[list[i].Token] { - notify := notify.Person{} - notify.ShareId = data.From - notify.Type = "LEAVE" - go MyService.Notify().SendPersonStatusBySocket(notify) - - delete(UDPAddressMap, list[i].Token) - - msg := model.MessageModel{} - msg.Type = types.PERSONGETIP - msg.Data = "" - msg.From = config.ServerInfo.Token - msg.To = list[i].Token - msg.UUId = uuid.NewV4().String() - Dial(msg, true) - } - } - } - go func(shareId string) { - user := MyService.Casa().GetUserInfoByShareId(shareId) - m := model2.FriendModel{} - m.Token = shareId - friend := MyService.Friend().GetFriendById(m) - if friend.Version != user.Version { - friend.Avatar = user.Avatar - friend.NickName = user.NickName - friend.Profile = user.Desc - friend.Version = user.Version - MyService.Friend().UpdateOrCreate(friend) - } - }(list[i].Token) - - } -} - -//file summary -func Summary(m model.MessageModel, t string) { - dataModel := model.FileSummaryModel{} - dataModelByte, _ := json.Marshal(m.Data) - err := json.Unmarshal(dataModelByte, &dataModel) - if err != nil { - fmt.Println(err) - } - - task := MyService.Download().GetDownloadById(m.UUId) - - task.State = types.DOWNLOADING - fullPath := path2.Join(task.LocalPath, task.Name) - - if len(dataModel.Message) > 0 { - task.State = types.DOWNLOADERROR - task.Error = dataModel.Message - } - //The file already exists and the file is the same, no need to download - if t != "upload" && file.Exists(fullPath) && file.GetHashByPath(fullPath) == dataModel.Hash { - task.State = types.DOWNLOADFINISHED - go func(from, uuid string) { - m := model.MessageModel{} - m.Data = "" - m.From = config.ServerInfo.Token - m.To = from - m.Type = types.PERSONCANCEL - m.UUId = uuid - CancelList[uuid] = uuid - Dial(m, false) - }(task.From, task.UUID) - - } - task.UUID = m.UUId - task.Name = dataModel.Name - task.Length = dataModel.Length - task.Size = dataModel.Size - task.BlockSize = dataModel.BlockSize - task.Hash = dataModel.Hash - task.Type = types.PERSONFILEDOWNLOAD - task.From = m.From - if t == "upload" { - task.Type = types.PERSONFILERECEIVEUPLOAD - } - MyService.Download().SaveDownload(task) -} - -//Save file fragment -func SaveFile(m model.MessageModel, stream quic.Stream) bool { - dataModelByte, _ := json.Marshal(m.Data) - dataModel := model.TranFileModel{} - err := json.Unmarshal(dataModelByte, &dataModel) - if err != nil { - fmt.Println(err) - return false - } - - dataLengthByte := make([]byte, 8) - _, err = io.ReadFull(stream, dataLengthByte) - if err != nil { - fmt.Println(err) - return false - } - dataLength, err := strconv.Atoi(string(dataLengthByte)) - if err != nil { - fmt.Println(err) - return false - } - dataByte := make([]byte, dataLength) - _, err = io.ReadFull(stream, dataByte) - if err != nil { - fmt.Println(err) - return false - } - sum := md5.Sum(dataByte) - hash := hex.EncodeToString(sum[:]) - if dataModel.Hash != hash { - fmt.Println("hash不匹配", hash, dataModel.Hash) - return false - } - tempPath := config.AppInfo.TempPath + "/" + m.UUId - file.IsNotExistMkDir(tempPath) - filepath := tempPath + "/" + strconv.Itoa(dataModel.Index) - _, err = os.Stat(filepath) - - if os.IsNotExist(err) { - err = ioutil.WriteFile(filepath, dataByte, 0644) - task := model2.PersonDownloadDBModel{} - task.UUID = m.UUId - if err != nil { - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - - } else { - if file.GetHashByPath(filepath) != dataModel.Hash { - os.Remove(filepath) - err = ioutil.WriteFile(filepath, dataByte, 0644) - task := model2.PersonDownloadDBModel{} - task.UUID = m.UUId - if err != nil { - task.Error = err.Error() - task.State = types.DOWNLOADERROR - MyService.Download().SetDownloadError(task) - } - } - } - - files, err := ioutil.ReadDir(tempPath) - if err != nil { - fmt.Println(err) - return false - } - if len(files) >= dataModel.Length { - summary := MyService.Download().GetDownloadById(m.UUId) - summary.State = types.DOWNLOADFINISH - MyService.Download().EditDownloadState(summary) - fullPath := file.GetNoDuplicateFileName(path2.Join(summary.LocalPath, summary.Name)) - file.SpliceFiles(tempPath, fullPath, dataModel.Length, 0) - if file.GetHashByPath(fullPath) == summary.Hash { - file.RMDir(tempPath) - summary.State = types.DOWNLOADFINISHED - MyService.Download().EditDownloadState(summary) - } else { - os.Remove(config.FileSettingInfo.DownloadDir + "/" + summary.Name) - - summary.State = types.DOWNLOADERROR - summary.Error = "hash mismatch" - MyService.Download().SetDownloadError(summary) - } - - return true - } - return false -}