diff --git a/CHANGELOG.md b/CHANGELOG.md index d0cba07..d1f46b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +## [0.3.3] - + +### Added + +### Changed + +- Cache app store index and category data + + +### Removed + +- upnp +- ddns +- search +- zerotier +- task +- file share + +### Security + +### Fixed + ## [0.3.2.1] - 2022-06-16(UTC) ### Changed diff --git a/UI b/UI index 62a6bd4..c4cfe88 160000 --- a/UI +++ b/UI @@ -1 +1 @@ -Subproject commit 62a6bd44d5740e3cb0ba0694d37c943147bea362 +Subproject commit c4cfe885e510a4fa3792f4e4fb5ee7debce4332e diff --git a/conf/conf.conf b/conf/conf.conf new file mode 100644 index 0000000..fe5fa0c --- /dev/null +++ b/conf/conf.conf @@ -0,0 +1,40 @@ +[app] +PAGE_SIZE = 10 +RuntimeRootPath = runtime/ +LogPath = ./CasaOS/logs/server/ +LogSaveName = log +LogFileExt = log +DateStrFormat = 20060102 +DateTimeFormat = 2006-01-02 15:04:05 +TimeFormat = 15:04:05 +DateFormat = 2006-01-02 +DBPath = ./CasaOS/server/db +ShellPath = ./CasaOS/server/shell +UserDataPath = ./CasaOS/conf +TempPath = ./CasaOS/temp + +[server] +HttpPort = 8089 +UDPPort = 54216 +RunMode = release +;ServerApi = https://api.casaos.io/casaos-api +ServerApi = http://127.0.0.1:8091 +Handshake = socket.casaos.io +Token = af268e4f-9f3a-408a-b59b-cf1a4f7f88c8 +USBAutoMount = +SocketPort = 58313 + +[system] +ConfigStr = {"auto_update":false,"background":"","background_type":"","search_engine":"https://duckduckgo.com/?q=","search_switch":false,"shortcuts_switch":false,"widgets_switch":false,"lang":"en_us"} +WidgetList = [{"name":"clock","show":true},{"name":"cpu","show":true},{"name":"disks","show":true},{"name":"network","show":true}] + +[file] +ShareDir = +DownloadDir = ./CasaOS/DATA/Downloads + +[user] +Description = nothing +UserName = casaos +Initialized = true +PWD = 123456 + diff --git a/conf/conf.json.sample b/conf/conf.conf.sample similarity index 94% rename from conf/conf.json.sample rename to conf/conf.conf.sample index 8f8789e..c98cf52 100644 --- a/conf/conf.json.sample +++ b/conf/conf.conf.sample @@ -1,7 +1,7 @@ [app] PAGE_SIZE = 10 RuntimeRootPath = runtime/ -LogSavePath = /var/log/casaos/ +LogPath = /var/log/casaos/ LogSaveName = log LogFileExt = log DateStrFormat = 20060102 diff --git a/main.go b/main.go index 2f51b97..ccf2d9e 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,9 @@ import ( "github.com/IceWhaleTech/CasaOS/pkg/cache" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/sqlite" + "github.com/IceWhaleTech/CasaOS/pkg/utils/encryption" "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" + "github.com/IceWhaleTech/CasaOS/pkg/utils/random" "github.com/IceWhaleTech/CasaOS/route" "github.com/IceWhaleTech/CasaOS/service" @@ -23,6 +25,8 @@ var sqliteDB *gorm.DB var configFlag = flag.String("c", "", "config address") var dbFlag = flag.String("db", "", "db path") var showUserInfo = flag.Bool("show-user-info", false, "show user info") +var resetUser = flag.Bool("ru", false, "reset user") +var user = flag.String("user", "", "user name") func init() { flag.Parse() @@ -37,9 +41,7 @@ func init() { service.MyService = service.NewService(sqliteDB) service.Cache = cache.Init() - go service.UDPService() - - fmt.Println("t", service.GetToken()) + service.GetToken() service.UDPAddressMap = make(map[string]string) //go service.SocketConnect() service.CancelList = make(map[string]string) @@ -47,7 +49,6 @@ func init() { service.NewVersionApp = make(map[string]string) route.InitFunction() - go service.SendIPToServer() // go service.LoopFriend() // go service.MyService.App().CheckNewImage() @@ -72,7 +73,30 @@ func main() { fmt.Println("Password:" + config.UserInfo.PWD) return } + fmt.Println("Reset User", *resetUser) + if *resetUser { + if user == nil || len(*user) == 0 { + fmt.Println("user is empty") + return + } + userData := service.MyService.User().GetUserAllInfoByName(*user) + if userData.Id == 0 { + fmt.Println("user not exist") + return + } + password := random.RandomString(6, false) + userData.Password = encryption.GetMD5ByStr(password) + service.MyService.User().UpdateUserPassword(userData) + fmt.Println("User reset successful") + fmt.Println("UserName:" + userData.UserName) + fmt.Println("Password:" + password) + return + } + go func() { + service.UDPService() + service.SendIPToServer() + }() go route.SocketInit(service.NotifyMsg) go func() { for i := 0; i < 1000; i++ { @@ -102,11 +126,11 @@ func main() { } err = cron2.AddFunc("0/5 * * * * *", func() { if service.ClientCount > 0 { - // route.SendNetINfoBySocket() - // route.SendCPUBySocket() - // route.SendMemBySocket() + //route.SendNetINfoBySocket() + //route.SendCPUBySocket() + //route.SendMemBySocket() // route.SendDiskBySocket() - // route.SendUSBBySocket() + //route.SendUSBBySocket() route.SendAllHardwareStatusBySocket() } }) diff --git a/middleware/gin.go b/middleware/gin.go index c3647c1..d70dfb9 100644 --- a/middleware/gin.go +++ b/middleware/gin.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2021-10-08 10:29:08 * @LastEditors: LinkLeong - * @LastEditTime: 2022-05-25 19:17:45 + * @LastEditTime: 2022-06-21 15:10:03 * @FilePath: /CasaOS/middleware/gin.go * @Description: * @Website: https://www.casaos.io @@ -14,7 +14,9 @@ import ( "fmt" "net/http" + "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/gin-gonic/gin" + "go.uber.org/zap" ) func Cors() gin.HandlerFunc { @@ -48,3 +50,9 @@ func Cors() gin.HandlerFunc { c.Next() } } +func WriteLog() gin.HandlerFunc { + return func(c *gin.Context) { + loger.Info("request:", zap.Any("path", c.Request.URL.String()), zap.Any("param", c.Params), zap.Any("query", c.Request.URL.Query()), zap.Any("body", c.Request.Body), zap.Any("method", c.Request.Method)) + c.Next() + } +} diff --git a/model/app.go b/model/app.go index a96216f..6f0f6e3 100644 --- a/model/app.go +++ b/model/app.go @@ -6,6 +6,13 @@ import ( "time" ) +type ServerAppListCollection struct { + List []ServerAppList `json:"list"` + Recommend []ServerAppList `json:"recommend"` + Community []ServerAppList `json:"Community"` + Version string `json:"version"` +} + type ServerAppList struct { Id uint `gorm:"column:id;primary_key" json:"id"` Title string `json:"title"` @@ -15,6 +22,7 @@ type ServerAppList struct { Icon string `json:"icon"` ScreenshotLink Strings `gorm:"type:json" json:"screenshot_link"` Category string `json:"category"` + CategoryId int `json:"category_id"` CategoryFont string `json:"category_font"` PortMap string `json:"port_map"` ImageVersion string `json:"image_version"` @@ -38,6 +46,7 @@ type ServerAppList struct { Plugins Strings `json:"plugins"` Origin string `json:"origin"` Type int `json:"type"` + QueryCount int `json:"query_count"` Developer string `json:"developer"` HostName string `json:"host_name"` Privileged bool `json:"privileged"` diff --git a/model/category.go b/model/category.go index bfdca39..3ee71a0 100644 --- a/model/category.go +++ b/model/category.go @@ -1,19 +1,19 @@ /* * @Author: link a624669980@163.com * @Date: 2022-05-16 17:37:08 - * @LastEditors: link a624669980@163.com - * @LastEditTime: 2022-06-07 17:12:30 - * @FilePath: \CasaOS\model\category.go + * @LastEditors: LinkLeong + * @LastEditTime: 2022-06-22 17:45:53 + * @FilePath: /CasaOS/model/category.go * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ package model -// type ServerCategoryList struct { -// Version string `json:"version"` -// Item []CategoryList `json:"item"` -// } type ServerCategoryList struct { + Version string `json:"version"` + Item []CategoryList `json:"item"` +} +type CategoryList struct { Id uint `gorm:"column:id;primary_key" json:"id"` //CreatedAt time.Time `json:"created_at"` // diff --git a/model/system_model/verify_information.go b/model/system_model/verify_information.go index fc2cd9b..e35fc93 100644 --- a/model/system_model/verify_information.go +++ b/model/system_model/verify_information.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-06-15 11:30:47 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-15 17:25:48 + * @LastEditTime: 2022-06-23 18:40:40 * @FilePath: /CasaOS/model/system_model/verify_information.go * @Description: * @Website: https://www.casaos.io @@ -13,5 +13,5 @@ package system_model type VerifyInformation struct { RefreshToken string `json:"refresh_token"` AccessToken string `json:"access_token"` - ExpiresAt string `json:"expires_at"` + ExpiresAt int64 `json:"expires_at"` } diff --git a/pkg/config/config.go b/pkg/config/config.go index 94ec6a4..4db6725 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2021-09-30 18:18:14 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 18:11:41 + * @LastEditTime: 2022-06-21 11:09:30 * @FilePath: /CasaOS/pkg/config/config.go * @Description: * @Website: https://www.casaos.io @@ -11,5 +11,5 @@ package config const ( - USERCONFIGURL = "conf/conf.json" + USERCONFIGURL = "/etc/casaos.conf" ) diff --git a/pkg/config/init.go b/pkg/config/init.go index 031d174..efa495f 100644 --- a/pkg/config/init.go +++ b/pkg/config/init.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 17:44:23 + * @LastEditTime: 2022-06-21 16:01:26 * @FilePath: /CasaOS/pkg/config/init.go * @Description: * @Website: https://www.casaos.io @@ -52,6 +52,9 @@ func InitSetup(config string) { if len(config) > 0 { configDir = config } + if runtime.GOOS == "darwin" { + configDir = "./conf/conf.conf" + } var err error //读取文件 Cfg, err = ini.Load(configDir) @@ -69,18 +72,23 @@ func InitSetup(config string) { SystemConfigInfo.ConfigPath = configDir if len(AppInfo.DBPath) == 0 { AppInfo.DBPath = "/var/lib/casaos" + Cfg.SaveTo(configDir) } if len(AppInfo.LogPath) == 0 { AppInfo.LogPath = "/var/log/casaos/" + Cfg.SaveTo(configDir) } if len(AppInfo.ShellPath) == 0 { AppInfo.ShellPath = "/usr/share/casaos/shell" + Cfg.SaveTo(configDir) } if len(AppInfo.UserDataPath) == 0 { AppInfo.UserDataPath = "/var/lib/casaos/conf" + Cfg.SaveTo(configDir) } if len(AppInfo.TempPath) == 0 { AppInfo.TempPath = "/var/lib/casaos/temp" + Cfg.SaveTo(configDir) } // AppInfo.ProjectPath = getCurrentDirectory() //os.Getwd() diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go index 5367013..b395b0e 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-14 13:40:21 + * @LastEditTime: 2022-06-22 18:50:44 * @FilePath: /CasaOS/pkg/sqlite/db.go * @Description: * @Website: https://www.casaos.io @@ -42,7 +42,8 @@ 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.ApplicationModel{}, model2.UserDBModel{}) + err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersonDownloadDBModel{}, model2.FriendModel{}, model2.PersonDownRecordDBModel{}, model2.UserDBModel{}) + db.Exec("DROP TABLE IF EXISTS o_application") if err != nil { loger.Error("check or create db error", zap.Any("error", err)) } diff --git a/pkg/upnp/device.go b/pkg/upnp/device.go deleted file mode 100644 index 1791e9c..0000000 --- a/pkg/upnp/device.go +++ /dev/null @@ -1,89 +0,0 @@ -package upnp - -import ( - "encoding/xml" - "io/ioutil" - "net/http" - "strings" -) - -func GetCtrlUrl(host, device string) string { - request := ctrlUrlRequest(host, device) - response, _ := http.DefaultClient.Do(request) - resultBody, _ := ioutil.ReadAll(response.Body) - defer response.Body.Close() - if response.StatusCode == 200 { - return resolve(string(resultBody)) - - } - return "" -} - -func ctrlUrlRequest(host string, deviceDescUrl string) *http.Request { - //请求头 - header := http.Header{} - header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2") - header.Set("User-Agent", "preston") - header.Set("Host", host) - header.Set("Connection", "keep-alive") - request, _ := http.NewRequest("GET", "http://"+host+deviceDescUrl, nil) - request.Header = header - return request -} - -func resolve(resultStr string) string { - inputReader := strings.NewReader(resultStr) - - // 从文件读取,如可以如下: - // content, err := ioutil.ReadFile("studygolang.xml") - // decoder := xml.NewDecoder(bytes.NewBuffer(content)) - - lastLabel := "" - - ISUpnpServer := false - - IScontrolURL := false - var controlURL string //`controlURL` - // var eventSubURL string //`eventSubURL` - // var SCPDURL string //`SCPDURL` - - decoder := xml.NewDecoder(inputReader) - for t, err := decoder.Token(); err == nil && !IScontrolURL; t, err = decoder.Token() { - switch token := t.(type) { - // 处理元素开始(标签) - case xml.StartElement: - if ISUpnpServer { - name := token.Name.Local - lastLabel = name - } - - // 处理元素结束(标签) - case xml.EndElement: - // log.Println("结束标记:", token.Name.Local) - // 处理字符数据(这里就是元素的文本) - case xml.CharData: - //得到url后其他标记就不处理了 - content := string([]byte(token)) - //找到提供端口映射的服务 - if content == "urn:schemas-upnp-org:service:WANIPConnection:1" { - ISUpnpServer = true - continue - } - - if ISUpnpServer { - switch lastLabel { - case "controlURL": - controlURL = content - IScontrolURL = true - case "eventSubURL": - // eventSubURL = content - case "SCPDURL": - // SCPDURL = content - } - } - default: - // ... - } - } - return controlURL -} diff --git a/pkg/upnp/device_test.go b/pkg/upnp/device_test.go deleted file mode 100644 index 26ea0fd..0000000 --- a/pkg/upnp/device_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package upnp - -import ( - "testing" - - ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" -) - -func TestGetCtrlUrl(t *testing.T) { - upnp, err := Gateway() - if err == nil { - upnp.CtrlUrl = GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl) - upnp.LocalHost = ip_helper2.GetLoclIp() - upnp.AddPortMapping(8090, 8090, "TCP") - //upnp.DelPortMapping(9999, "TCP") - } -} diff --git a/pkg/upnp/gateway.go b/pkg/upnp/gateway.go deleted file mode 100644 index b3307a5..0000000 --- a/pkg/upnp/gateway.go +++ /dev/null @@ -1,76 +0,0 @@ -package upnp - -import ( - ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - "github.com/pkg/errors" - "net" - "strings" -) - -func Gateway() (*Upnp, error) { - result, error := send() - if result == "" || error != nil { - return nil, error - } - upnp := resolvesss(result) - return upnp, nil -} - -func send() (string, error) { - var str = "M-SEARCH * HTTP/1.1\r\n" + - "HOST: 239.255.255.250:1900\r\n" + - "ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n" + - "MAN: \"ssdp:discover\"\r\n" + "MX: 3\r\n\r\n" - var conn *net.UDPConn - remoteAddr, err := net.ResolveUDPAddr("udp", "239.255.255.250:1900") - if err != nil { - return "", errors.New("组播地址格式不正确") - } - localAddr, err := net.ResolveUDPAddr("udp", ip_helper2.GetLoclIp()+":") - - if err != nil { - return "", errors.New("本地ip地址格式不正确") - } - conn, err = net.ListenUDP("udp", localAddr) - defer conn.Close() - if err != nil { - return "", errors.New("监听udp出错") - } - _, err = conn.WriteToUDP([]byte(str), remoteAddr) - if err != nil { - return "", errors.New("发送msg到组播地址出错") - } - buf := make([]byte, 1024) - n, _, err := conn.ReadFromUDP(buf) - if err != nil { - return "", errors.New("从组播地址接搜消息出错") - } - result := string(buf[:n]) - return result, nil -} - -func resolvesss(result string) *Upnp { - var upnp = &Upnp{} - lines := strings.Split(result, "\r\n") - for _, line := range lines { - //按照第一个冒号分为两个字符串 - nameValues := strings.SplitAfterN(line, ":", 2) - if len(nameValues) < 2 { - continue - } - switch strings.ToUpper(strings.Trim(strings.Split(nameValues[0], ":")[0], " ")) { - case "ST": - //fmt.Println(nameValues[1]) - case "CACHE-CONTROL": - //fmt.Println(nameValues[1]) - case "LOCATION": - urls := strings.Split(strings.Split(nameValues[1], "//")[1], "/") - upnp.GatewayHost = (urls[0]) - upnp.DeviceDescUrl = ("/" + urls[1]) - case "SERVER": - upnp.GatewayName = (nameValues[1]) - default: - } - } - return upnp -} diff --git a/pkg/upnp/gateway_test.go b/pkg/upnp/gateway_test.go deleted file mode 100644 index 9fde2b3..0000000 --- a/pkg/upnp/gateway_test.go +++ /dev/null @@ -1,8 +0,0 @@ -package upnp - -import "testing" - -func TestGateway(t *testing.T) { - - Gateway() -} diff --git a/pkg/upnp/mapping.go b/pkg/upnp/mapping.go deleted file mode 100644 index 70c007d..0000000 --- a/pkg/upnp/mapping.go +++ /dev/null @@ -1,158 +0,0 @@ -package upnp - -import ( - "bytes" - "net/http" - "strconv" - "strings" - - loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" - "github.com/pkg/errors" -) - -// -////添加一个端口映射 -func (n *Upnp) AddPortMapping(localPort, remotePort int, protocol string) (err error) { - defer func() { - if errTemp := recover(); errTemp != nil { - loger2.NewOLoger().Error("upnp模块报错了", errTemp) - } - }() - - if isSuccess := addSend(localPort, remotePort, protocol, n.GatewayHost, n.CtrlUrl, n.LocalHost); isSuccess { - return nil - } else { - return errors.New("添加一个端口映射失败") - } -} - -func addSend(localPort, remotePort int, protocol, host, ctrUrl, localHost string) bool { - request := addRequest(localPort, remotePort, protocol, host, ctrUrl, localHost) - response, _ := http.DefaultClient.Do(request) - defer response.Body.Close() - //resultBody, _ := ioutil.ReadAll(response.Body) - //fmt.Println(string(resultBody)) - return response.StatusCode == 200 -} - -type Node struct { - Name string - Content string - Attr map[string]string - Child []Node -} - -func addRequest(localPort, remotePort int, protocol string, gatewayHost, ctlUrl, localHost string) *http.Request { - //请求头 - header := http.Header{} - header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2") - header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"`) - header.Set("Content-Type", "text/xml") - header.Set("Connection", "Close") - header.Set("Content-Length", "") - //请求体 - body := Node{Name: "SOAP-ENV:Envelope", - Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`, - "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}} - childOne := Node{Name: `SOAP-ENV:Body`} - childTwo := Node{Name: `m:AddPortMapping`, - Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}} - - childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)} - childList2 := Node{Name: "NewInternalPort", Content: strconv.Itoa(localPort)} - childList3 := Node{Name: "NewProtocol", Content: protocol} - childList4 := Node{Name: "NewEnabled", Content: "1"} - childList5 := Node{Name: "NewInternalClient", Content: localHost} - childList6 := Node{Name: "NewLeaseDuration", Content: "0"} - childList7 := Node{Name: "NewPortMappingDescription", Content: "Oasis"} - childList8 := Node{Name: "NewRemoteHost"} - childTwo.AddChild(childList1) - childTwo.AddChild(childList2) - childTwo.AddChild(childList3) - childTwo.AddChild(childList4) - childTwo.AddChild(childList5) - childTwo.AddChild(childList6) - childTwo.AddChild(childList7) - childTwo.AddChild(childList8) - - childOne.AddChild(childTwo) - body.AddChild(childOne) - bodyStr := body.BuildXML() - //请求 - request, _ := http.NewRequest("POST", "http://"+gatewayHost+ctlUrl, - strings.NewReader(bodyStr)) - request.Header = header - request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr)))) - return request -} - -func (n *Node) AddChild(node Node) { - n.Child = append(n.Child, node) -} - -func (n *Node) BuildXML() string { - buf := bytes.NewBufferString("<") - buf.WriteString(n.Name) - for key, value := range n.Attr { - buf.WriteString(" ") - buf.WriteString(key + "=" + value) - } - buf.WriteString(">" + n.Content) - - for _, node := range n.Child { - buf.WriteString(node.BuildXML()) - } - buf.WriteString("") - return buf.String() -} - -func (n *Upnp) DelPortMapping(remotePort int, protocol string) bool { - isSuccess := delSendSend(remotePort, protocol, n.GatewayHost, n.CtrlUrl) - if isSuccess { - //this.MappingPort.delMapping(remotePort, protocol) - //fmt.Println("删除了一个端口映射: remote:", remotePort) - } - return isSuccess -} - -func delSendSend(remotePort int, protocol, host, ctlUrl string) bool { - delrequest := delbuildRequest(remotePort, protocol, host, ctlUrl) - response, _ := http.DefaultClient.Do(delrequest) - //resultBody, _ := ioutil.ReadAll(response.Body) - defer response.Body.Close() - - return response.StatusCode == 200 -} - -func delbuildRequest(remotePort int, protocol, host, ctlUrl string) *http.Request { - //请求头 - header := http.Header{} - header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2") - header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"`) - header.Set("Content-Type", "text/xml") - header.Set("Connection", "Close") - header.Set("Content-Length", "") - //请求体 - body := Node{Name: "SOAP-ENV:Envelope", - Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`, - "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}} - childOne := Node{Name: `SOAP-ENV:Body`} - childTwo := Node{Name: `m:DeletePortMapping`, - Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}} - childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)} - childList2 := Node{Name: "NewProtocol", Content: protocol} - childList3 := Node{Name: "NewRemoteHost"} - childTwo.AddChild(childList1) - childTwo.AddChild(childList2) - childTwo.AddChild(childList3) - childOne.AddChild(childTwo) - body.AddChild(childOne) - bodyStr := body.BuildXML() - - //请求 - request, _ := http.NewRequest("POST", "http://"+host+ctlUrl, - strings.NewReader(bodyStr)) - request.Header = header - request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr)))) - return request -} diff --git a/pkg/upnp/mapping_test.go b/pkg/upnp/mapping_test.go deleted file mode 100644 index 08e4fbf..0000000 --- a/pkg/upnp/mapping_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package upnp - -import "testing" - -func TestAddPortMapping(t *testing.T) { - //AddPortMapping(6666,6666,"TCP","192.168.2.1:5000",) -} diff --git a/pkg/upnp/upnp.go b/pkg/upnp/upnp.go deleted file mode 100644 index 8f78c9c..0000000 --- a/pkg/upnp/upnp.go +++ /dev/null @@ -1,25 +0,0 @@ -package upnp - -import ( - "fmt" - "github.com/prestonTao/upnp" -) - -type Upnp struct { - LocalHost string `json:"local_host"` - GatewayName string `json:"gateway_name"` //网关名称 - GatewayHost string `json:"gateway_host"` //网关ip和端口 - DeviceDescUrl string `json:"device_desc_url"` //设备描述url - CtrlUrl string `json:"ctrl_url"` //控制请求url -} - -func Testaaa() { - upnpMan := new(upnp.Upnp) - err := upnpMan.SearchGateway() - if err != nil { - fmt.Println(err.Error()) - } else { - fmt.Println("local ip address: ", upnpMan.LocalHost) - fmt.Println("gateway ip address: ", upnpMan.Gateway.Host) - } -} diff --git a/pkg/upnp/upnp_test.go b/pkg/upnp/upnp_test.go deleted file mode 100644 index aa68666..0000000 --- a/pkg/upnp/upnp_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package upnp - -import ( - "testing" -) - -func TestTestaaa(t *testing.T) { - (Testaaa()) -} diff --git a/pkg/utils/common_err/e.go b/pkg/utils/common_err/e.go index e42764a..0983c62 100644 --- a/pkg/utils/common_err/e.go +++ b/pkg/utils/common_err/e.go @@ -7,14 +7,17 @@ const ( ERROR_AUTH_TOKEN = 401 //user - PWD_INVALID = 10001 - PWD_IS_EMPTY = 10002 - PWD_INVALID_OLD = 10003 - ACCOUNT_LOCK = 10004 - PWD_IS_TOO_SIMPLE = 10005 - USER_NOT_EXIST = 10006 - USER_EXIST = 10007 - KEY_NOT_EXIST = 10008 + PWD_INVALID = 10001 + PWD_IS_EMPTY = 10002 + PWD_INVALID_OLD = 10003 + ACCOUNT_LOCK = 10004 + PWD_IS_TOO_SIMPLE = 10005 + USER_NOT_EXIST = 10006 + USER_EXIST = 10007 + KEY_NOT_EXIST = 10008 + NOT_IMAGE = 10009 + IMAGE_TOO_LARGE = 10010 + INSUFFICIENT_PERMISSIONS = 10011 //system DIR_ALREADY_EXISTS = 20001 @@ -63,14 +66,17 @@ var MsgFlags = map[int]string{ ERROR_AUTH_TOKEN: "Error auth token", //user - PWD_INVALID: "Invalid password", - PWD_IS_EMPTY: "Password is empty", - PWD_INVALID_OLD: "Invalid old password", - ACCOUNT_LOCK: "Account is locked", - PWD_IS_TOO_SIMPLE: "Password is too simple", - USER_NOT_EXIST: "User does not exist", - USER_EXIST: "User already exists", - KEY_NOT_EXIST: "Key does not exist", + PWD_INVALID: "Invalid password", + PWD_IS_EMPTY: "Password is empty", + PWD_INVALID_OLD: "Invalid old password", + ACCOUNT_LOCK: "Account is locked", + PWD_IS_TOO_SIMPLE: "Password is too simple", + USER_NOT_EXIST: "User does not exist", + USER_EXIST: "User already exists", + KEY_NOT_EXIST: "Key does not exist", + IMAGE_TOO_LARGE: "Image is too large", + NOT_IMAGE: "Not a image", + INSUFFICIENT_PERMISSIONS: "Insufficient permissions", //system DIR_ALREADY_EXISTS: "Folder already exists", diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go index 48e1aa0..dac408e 100644 --- a/pkg/utils/file/file.go +++ b/pkg/utils/file/file.go @@ -225,6 +225,48 @@ func CopyFile(src, dst, style string) error { return os.Chmod(dst, srcinfo.Mode()) } +/** + * @description: + * @param {*} src + * @param {*} dst + * @param {string} style + * @return {*} + * @method: + * @router: + */ +func CopySingleFile(src, dst, style string) error { + var err error + var srcfd *os.File + var dstfd *os.File + var srcinfo os.FileInfo + + if Exists(dst) { + if style == "skip" { + return nil + } else { + os.Remove(dst) + } + } + + if srcfd, err = os.Open(src); err != nil { + return err + } + defer srcfd.Close() + + if dstfd, err = os.Create(dst); err != nil { + return err + } + defer dstfd.Close() + + if _, err = io.Copy(dstfd, srcfd); err != nil { + return err + } + if srcinfo, err = os.Stat(src); err != nil { + return err + } + return os.Chmod(dst, srcinfo.Mode()) +} + //Check for duplicate file names func GetNoDuplicateFileName(fullPath string) string { path, fileName := filepath.Split(fullPath) diff --git a/pkg/utils/file/image.go b/pkg/utils/file/image.go index 45b60f2..24b8ffc 100644 --- a/pkg/utils/file/image.go +++ b/pkg/utils/file/image.go @@ -2,9 +2,12 @@ package file import ( "bytes" + "errors" "fmt" "io" + "net/http" "os" + "strings" "github.com/disintegration/imaging" "github.com/dsoprea/go-exif/v3" @@ -82,3 +85,164 @@ func GetThumbnailByWebPhoto(path string, width, height int) ([]byte, error) { imaging.Encode(&buf, img, f) return buf.Bytes(), nil } + +func ImageExtArray() []string { + + ext := []string{ + "ase", + "art", + "bmp", + "blp", + "cd5", + "cit", + "cpt", + "cr2", + "cut", + "dds", + "dib", + "djvu", + "egt", + "exif", + "gif", + "gpl", + "grf", + "icns", + "ico", + "iff", + "jng", + "jpeg", + "jpg", + "jfif", + "jp2", + "jps", + "lbm", + "max", + "miff", + "mng", + "msp", + "nitf", + "ota", + "pbm", + "pc1", + "pc2", + "pc3", + "pcf", + "pcx", + "pdn", + "pgm", + "PI1", + "PI2", + "PI3", + "pict", + "pct", + "pnm", + "pns", + "ppm", + "psb", + "psd", + "pdd", + "psp", + "px", + "pxm", + "pxr", + "qfx", + "raw", + "rle", + "sct", + "sgi", + "rgb", + "int", + "bw", + "tga", + "tiff", + "tif", + "vtf", + "xbm", + "xcf", + "xpm", + "3dv", + "amf", + "ai", + "awg", + "cgm", + "cdr", + "cmx", + "dxf", + "e2d", + "egt", + "eps", + "fs", + "gbr", + "odg", + "svg", + "stl", + "vrml", + "x3d", + "sxd", + "v2d", + "vnd", + "wmf", + "emf", + "art", + "xar", + "png", + "webp", + "jxr", + "hdp", + "wdp", + "cur", + "ecw", + "iff", + "lbm", + "liff", + "nrrd", + "pam", + "pcx", + "pgf", + "sgi", + "rgb", + "rgba", + "bw", + "int", + "inta", + "sid", + "ras", + "sun", + "tga", + } + + return ext +} + +/** +* @description:get a image's ext +* @param {string} path "file path" +* @return {string} ext "file ext" +* @return {error} err "error info" + */ +func GetImageExt(p string) (string, error) { + file, err := os.Open(p) + if err != nil { + return "", err + } + + buff := make([]byte, 512) + + _, err = file.Read(buff) + + if err != nil { + return "", err + } + + filetype := http.DetectContentType(buff) + + ext := ImageExtArray() + + for i := 0; i < len(ext); i++ { + if strings.Contains(ext[i], filetype[6:]) { + return ext[i], nil + } + } + + return "", errors.New("invalid image type") +} diff --git a/pkg/utils/jwt/jwt_helper.go b/pkg/utils/jwt/jwt_helper.go index cfb167b..b9ba916 100644 --- a/pkg/utils/jwt/jwt_helper.go +++ b/pkg/utils/jwt/jwt_helper.go @@ -1,8 +1,17 @@ +/* + * @Author: LinkLeong link@icewhale.com + * @Date: 2022-06-17 14:01:25 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-06-23 19:15:26 + * @FilePath: /CasaOS/pkg/utils/jwt/jwt_helper.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ package jwt import ( "fmt" - "net/http" "strconv" "time" @@ -12,7 +21,7 @@ import ( "github.com/gin-gonic/gin" ) -func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc { +func JWT() gin.HandlerFunc { return func(c *gin.Context) { var code int code = common_err.SUCCESS @@ -23,23 +32,20 @@ func JWT(swagHandler gin.HandlerFunc) gin.HandlerFunc { if token == "" { code = common_err.INVALID_PARAMS } - if swagHandler == nil { - claims, err := ParseToken(token) - //_, err := ParseToken(token) - if err != nil { - code = common_err.ERROR_AUTH_TOKEN - } else if claims.VerifyExpiresAt(time.Now(), true) || claims.VerifyIssuer("casaos", true) { - code = common_err.ERROR_AUTH_TOKEN - } - c.Header("user_id", strconv.Itoa(claims.Id)) - } + claims, err := ParseToken(token) + //_, err := ParseToken(token) + if err != nil { + code = common_err.ERROR_AUTH_TOKEN + } else if !claims.VerifyExpiresAt(time.Now(), true) || !claims.VerifyIssuer("casaos", true) { + code = common_err.ERROR_AUTH_TOKEN + } if code != common_err.SUCCESS { - c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)}) + c.JSON(code, model.Result{Success: code, Message: common_err.GetMsg(code)}) c.Abort() return } - + c.Request.Header.Add("user_id", strconv.Itoa(claims.Id)) c.Next() } } @@ -50,7 +56,7 @@ func GetAccessToken(username, pwd string, id int) string { if err == nil { return token } else { - loger2.NewOLoger().Fatal(fmt.Sprintf("Get Token Fail: %V", err)) + loger2.Error(fmt.Sprintf("Get Token Fail: %V", err)) return "" } } @@ -60,7 +66,7 @@ func GetRefreshToken(username, pwd string, id int) string { if err == nil { return token } else { - loger2.NewOLoger().Fatal(fmt.Sprintf("Get Token Fail: %V", err)) + loger2.Error(fmt.Sprintf("Get Token Fail: %V", err)) return "" } } diff --git a/pkg/utils/loger/log.go b/pkg/utils/loger/log.go index 1165009..0b1e8df 100644 --- a/pkg/utils/loger/log.go +++ b/pkg/utils/loger/log.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-06-02 15:09:38 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 18:15:58 + * @LastEditTime: 2022-06-21 15:08:34 * @FilePath: /CasaOS/pkg/utils/loger/log.go * @Description: * @Website: https://www.casaos.io @@ -47,8 +47,8 @@ func LogInit() { encoder := zapcore.NewJSONEncoder(encoderConfig) fileWriteSyncer := getFileLogWriter() core := zapcore.NewTee( - zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel), - zapcore.NewCore(encoder, fileWriteSyncer, zapcore.DebugLevel), + zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.InfoLevel), + zapcore.NewCore(encoder, fileWriteSyncer, zapcore.InfoLevel), ) loggers = zap.New(core) diff --git a/pkg/utils/version/version.go b/pkg/utils/version/version.go index a2aaa39..d2c801a 100644 --- a/pkg/utils/version/version.go +++ b/pkg/utils/version/version.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 20:08:21 + * @LastEditTime: 2022-06-22 15:24:01 * @FilePath: /CasaOS/pkg/utils/version/version.go * @Description: * @Website: https://www.casaos.io @@ -11,22 +11,14 @@ package version import ( - json2 "encoding/json" "strconv" "strings" "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" "github.com/IceWhaleTech/CasaOS/types" - "github.com/tidwall/gjson" ) -func IsNeedUpdate() (bool, model.Version) { - var version model.Version - v := httper.OasisGet(config.ServerInfo.ServerApi + "/v1/sys/version") - data := gjson.Get(v, "data") - json2.Unmarshal([]byte(data.String()), &version) +func IsNeedUpdate(version model.Version) (bool, model.Version) { v1 := strings.Split(version.Version, ".") diff --git a/route/doc.go b/route/doc.go deleted file mode 100644 index fafe1d6..0000000 --- a/route/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build doc -// +build doc - -package route - -import ( - _ "github.com/IceWhaleTech/CasaOS/docs" - ginSwagger "github.com/swaggo/gin-swagger" - swaggerFiles "github.com/swaggo/gin-swagger/swaggerFiles" -) - -func init() { - // swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler) - swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler) -} diff --git a/route/init.go b/route/init.go index 32ec46d..77fd0d2 100644 --- a/route/init.go +++ b/route/init.go @@ -31,7 +31,6 @@ func InitFunction() { CheckToken2_11() ImportApplications() ChangeAPIUrl() - InitSystemApplication() MoveUserToDB() } @@ -83,7 +82,7 @@ func installSyncthing(appId string) { appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip) } - appInfo.MaxMemory = service.MyService.System().GetMemInfo().Total >> 20 + appInfo.MaxMemory = service.MyService.System().GetMemInfo()["total"].(uint64) >> 20 id := uuid.NewV4().String() @@ -239,7 +238,7 @@ func CheckToken2_11() { config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) } - if service.MyService.ZiMa().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.ZiMa().GetDeviceTree(), "Raspberry Pi") { + if service.MyService.System().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.System().GetDeviceTree(), "Raspberry Pi") { service.MyService.System().UpdateUSBAutoMount("False") service.MyService.System().ExecUSBAutoMountShell("False") } @@ -270,34 +269,13 @@ func ChangeAPIUrl() { } -// 0.3.1 -func InitSystemApplication() { - list := service.MyService.App().GetApplicationList() - if len(list) != 2 { - application := model2.ApplicationModel{} - application.Name = "Files" - application.Icon = "/ui/img/Files.svg" - application.Type = "system" - application.Order = 0 - service.MyService.App().CreateApplication(application) - - application.Name = "CasaConnect" - application.Icon = "/ui/img/CasaConnect.svg" - application.Type = "system" - application.Order = 0 - - service.MyService.App().CreateApplication(application) - } -} - //0.3.3 //Transferring user data to the database func MoveUserToDB() { - if service.MyService.User().GetUserInfoByUserName(config.UserInfo.UserName).Id == 0 { + if len(config.UserInfo.UserName) > 0 && service.MyService.User().GetUserInfoByUserName(config.UserInfo.UserName).Id == 0 { user := model2.UserDBModel{} user.UserName = config.UserInfo.UserName - user.Avatar = config.UserInfo.Avatar user.Email = config.UserInfo.Email user.NickName = config.UserInfo.NickName user.Password = encryption.GetMD5ByStr(config.UserInfo.PWD) diff --git a/route/periodical.go b/route/periodical.go index 0934014..7db7248 100644 --- a/route/periodical.go +++ b/route/periodical.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-27 15:55:36 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-10 12:17:59 + * @LastEditTime: 2022-06-21 19:00:12 * @FilePath: /CasaOS/route/periodical.go * @Description: * @Website: https://www.casaos.io @@ -29,7 +29,7 @@ func SendNetINfoBySocket() { for _, netCardName := range nets { if n.Name == netCardName { item := *(*model.IOCountersStat)(unsafe.Pointer(&n)) - item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name)) + item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name)) item.Time = time.Now().Unix() newNet = append(newNet, item) break @@ -163,7 +163,7 @@ func SendAllHardwareStatusBySocket() { for _, netCardName := range nets { if n.Name == netCardName { item := *(*model.IOCountersStat)(unsafe.Pointer(&n)) - item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name)) + item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name)) item.Time = time.Now().Unix() newNet = append(newNet, item) break @@ -273,13 +273,7 @@ func SendAllHardwareStatusBySocket() { } } memInfo := service.MyService.System().GetMemInfo() - memData := make(map[string]interface{}) - memData["total"] = memInfo.Total - memData["available"] = memInfo.Available - memData["used"] = memInfo.Used - memData["free"] = memInfo.Free - memData["usedPercent"] = memInfo.UsedPercent - service.MyService.Notify().SendAllHardwareStatusBySocket(summary, usb, memData, cpuData, newNet) + service.MyService.Notify().SendAllHardwareStatusBySocket(summary, usb, memInfo, cpuData, newNet) } diff --git a/route/route.go b/route/route.go index 3490d34..c827e3c 100644 --- a/route/route.go +++ b/route/route.go @@ -8,11 +8,11 @@ import ( jwt2 "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt" v1 "github.com/IceWhaleTech/CasaOS/route/v1" "github.com/IceWhaleTech/CasaOS/web" + "github.com/gin-contrib/gzip" "github.com/gin-gonic/gin" ) -var swagHandler gin.HandlerFunc var OnlineDemo bool = false func InitRouter() *gin.Engine { @@ -20,57 +20,62 @@ func InitRouter() *gin.Engine { r := gin.Default() r.Use(middleware.Cors()) + r.Use(middleware.WriteLog()) r.Use(gzip.Gzip(gzip.DefaultCompression)) gin.SetMode(config.ServerInfo.RunMode) - r.StaticFS("/ui", http.FS(web.Static)) r.GET("/", WebUIHome) + // r.StaticFS("/assets", http.Dir("./static/assets")) + // r.StaticFile("/favicon.ico", "./static/favicon.ico") //r.GET("/", func(c *gin.Context) { // c.Redirect(http.StatusMovedPermanently, "ui/") //}) - if swagHandler != nil { - r.GET("/swagger/*any", swagHandler) - } - r.POST("/v1/user/register", v1.PostUserRegister) - r.POST("/v1/user/login", v1.Login) - r.POST("/v1/user/all/name", v1.GetUserAllUserName) + r.POST("/v1/user/register/:key", v1.PostUserRegister) + r.POST("/v1/user/login", v1.PostUserLogin) + r.GET("/v1/user/all/name", v1.GetUserAllUserName) - r.GET("/v1/guide/check", v1.GetGuideCheck) + r.GET("/v1/sys/init/check", v1.GetSystemInitCheck) r.GET("/v1/debug", v1.GetSystemConfigDebug) + r.GET("/v1/user/avatar/:id", v1.GetUserAvatar) + r.GET("/v1/user/image", v1.GetUserImage) + //get user info //get user info r.GET("/v1/person/shareid", v1.GetPersonShareId) r.GET("/v1/sys/socket/port", v1.GetSystemSocketPort) - r.POST("/v1/sys/refresh/token", v1.PostSystemRefreshToken) + r.POST("/v1/user/refresh/token", v1.PostUserRefreshToken) v1Group := r.Group("/v1") - v1Group.Use(jwt2.JWT(swagHandler)) + v1Group.Use(jwt2.JWT()) { v1UserGroup := v1Group.Group("/user") v1UserGroup.Use() { + v1UserGroup.PUT("/avatar", v1.PutUserAvatar) + v1UserGroup.GET("/avatar", v1.GetUserAvatar) - //chang head - //v1UserGroup.POST("/head", v1.PostUserHead) - //chang user name - v1UserGroup.PUT("/username/:id", v1.PutUserName) - //chang pwd - v1UserGroup.PUT("/password/:id", v1.PutUserPwd) - //edit user info - //v1UserGroup.POST("/info", v1.PostUserChangeInfo) - v1UserGroup.PUT("/nick/:id", v1.PutUserNick) - v1UserGroup.PUT("/desc/:id", v1.PutUserDesc) - v1UserGroup.GET("/v1/user/info/:id", v1.GetUserInfo) - //v1UserGroup.POST("/person/info", v1.PostUserPersonInfo) + v1UserGroup.PUT("/name", v1.PutUserName) + v1UserGroup.PUT("/password", v1.PutUserPwd) + v1UserGroup.PUT("/nick", v1.PutUserNick) + v1UserGroup.PUT("/desc", v1.PutUserDesc) + v1UserGroup.GET("/info", v1.GetUserInfo) + + v1UserGroup.POST("/person/info", v1.PostUserPersonInfo) v1UserGroup.GET("/shareid", v1.GetUserShareID) - v1UserGroup.GET("/custom/:name") - v1UserGroup.POST("/custom/:name") + v1UserGroup.GET("/custom/:key", v1.GetUserCustomConf) + v1UserGroup.POST("/custom/:key", v1.PostUserCustomConf) + v1UserGroup.DELETE("/custom/:key", v1.DeleteUserCustomConf) + v1UserGroup.DELETE("/delete/:id", v1.DeleteUser) + v1UserGroup.POST("/upload/image/:key", v1.PostUserUploadImage) + v1UserGroup.POST("/file/image/:key", v1.PostUserFileImage) + v1UserGroup.DELETE("/image", v1.DeleteUserImage) + } v1AppGroup := v1Group.Group("/app") v1AppGroup.Use() @@ -87,12 +92,10 @@ func InitRouter() *gin.Engine { v1AppGroup.GET("/port", v1.GetPort) //检查端口 v1AppGroup.GET("/check/:port", v1.PortCheck) - //分类 + v1AppGroup.GET("/category", v1.CategoryList) - //容器相关 + v1AppGroup.GET("/terminal/:id", v1.DockerTerminal) - v1AppGroup.GET("/order", v1.GetAppOrder) - v1AppGroup.POST("/order", v1.PostAppOrder) //app容器详情 v1AppGroup.GET("/info/:id", v1.ContainerInfo) //app容器日志 @@ -118,7 +121,6 @@ func InitRouter() *gin.Engine { v1SysGroup := v1Group.Group("/sys") v1SysGroup.Use() { - v1SysGroup.GET("/check", v1.GetSystemCheckVersion) v1SysGroup.GET("/version/check", v1.GetSystemCheckVersion) v1SysGroup.GET("/hardware/info", v1.GetSystemHardwareInfo) v1SysGroup.POST("/update", v1.SystemUpdate) @@ -138,7 +140,6 @@ func InitRouter() *gin.Engine { v1SysGroup.GET("/mem", v1.GetSystemMemInfo) v1SysGroup.GET("/disk", v1.GetSystemDiskInfo) v1SysGroup.GET("/network", v1.GetSystemNetInfo) - } v1FileGroup := v1Group.Group("/file") v1FileGroup.Use() @@ -159,7 +160,6 @@ func InitRouter() *gin.Engine { v1FileGroup.PUT("/update", v1.PutFileContent) v1FileGroup.GET("/image", v1.GetFileImage) v1FileGroup.DELETE("/operate/:id", v1.DeleteOperateFileOrDir) - //v1FileGroup.GET("/download", v1.UserFileDownloadCommonService) } v1DiskGroup := v1Group.Group("/disk") @@ -173,10 +173,10 @@ func InitRouter() *gin.Engine { v1DiskGroup.GET("/info", v1.GetDiskInfo) //format storage - v1DiskGroup.POST("/format", v1.FormatDisk) + v1DiskGroup.POST("/format", v1.PostDiskFormat) // add storage - v1DiskGroup.POST("/storage", v1.AddPartition) + v1DiskGroup.POST("/storage", v1.PostDiskAddPartition) //mount SATA disk v1DiskGroup.POST("/mount", v1.PostMountDisk) @@ -192,24 +192,6 @@ func InitRouter() *gin.Engine { v1DiskGroup.GET("/usb", v1.GetUSBList) } - v1ShareGroup := v1Group.Group("/share") - v1ShareGroup.Use() - { - v1ShareGroup.POST("/add", v1.PostShareDirAdd) - v1ShareGroup.DELETE("/del/:id", v1.DeleteShareDirDel) - v1ShareGroup.GET("/list", v1.GetShareDirList) - v1ShareGroup.GET("/info/:id", v1.GetShareDirInfo) - v1ShareGroup.PUT("/update/:id", v1.PutShareDirEdit) - } - v1TaskGroup := v1Group.Group("/task") - v1TaskGroup.Use() - { - v1TaskGroup.GET("/list", v1.GetTaskList) - v1TaskGroup.PUT("/update", v1.PutTaskUpdate) - v1TaskGroup.POST("/add", v1.PostTaskAdd) - v1TaskGroup.PUT("/completion/:id", v1.PutTaskMarkerCompletion) - } - v1PersonGroup := v1Group.Group("/person") v1PersonGroup.Use() { @@ -236,14 +218,7 @@ func InitRouter() *gin.Engine { v1PersonGroup.GET("/image/thumbnail/:shareid", v1.GetPersonImageThumbnail) } - v1AnalyseGroup := v1Group.Group("/analyse") - v1AnalyseGroup.Use() - { - v1AnalyseGroup.POST("/app", v1.PostAppAnalyse) - } v1Group.GET("/sync/config", v1.GetSyncConfig) - v1Group.Any("/syncthing/*url", v1.SyncToSyncthing) - } return r } diff --git a/route/ui.go b/route/ui.go index 6702009..e4980c2 100644 --- a/route/ui.go +++ b/route/ui.go @@ -1,9 +1,20 @@ +/* + * @Author: LinkLeong link@icewhale.com + * @Date: 2022-06-23 17:27:43 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-06-23 17:27:48 + * @FilePath: /CasaOS/route/ui.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ package route import ( + "html/template" + "github.com/IceWhaleTech/CasaOS/web" "github.com/gin-gonic/gin" - "html/template" ) func WebUIHome(c *gin.Context) { diff --git a/route/v1/analyse.go b/route/v1/analyse.go deleted file mode 100644 index b729e5f..0000000 --- a/route/v1/analyse.go +++ /dev/null @@ -1,48 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2022-03-08 11:28:15 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-15 14:20:21 - * @FilePath: /CasaOS/route/v1/analyse.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package v1 - -import ( - "net/http" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/service" - "github.com/gin-gonic/gin" -) - -// @Summary post app analyse -// @Produce application/json -// @Accept multipart/form-data -// @Tags analyse -// @Param name formData string true "app name" -// @Param type formData string true "action" Enums(open,delete) -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /analyse/app [post] -func PostAppAnalyse(c *gin.Context) { - if config.SystemConfigInfo.Analyse == "False" { - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) - return - } - name := c.PostForm("name") - t := c.PostForm("type") - language := c.GetHeader("Language") - - if len(name) == 0 || len(t) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - service.MyService.Casa().PushAppAnalyse(config.ServerInfo.Token, t, name, language) - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} diff --git a/route/v1/app.go b/route/v1/app.go index 8d06ba4..eaea5cc 100644 --- a/route/v1/app.go +++ b/route/v1/app.go @@ -36,8 +36,11 @@ func AppList(c *gin.Context) { t := c.DefaultQuery("type", "rank") categoryId := c.DefaultQuery("category_id", "0") key := c.DefaultQuery("key", "") - language := c.GetHeader("Language") - recommend, list, community := service.MyService.Casa().GetServerList(index, size, t, categoryId, key, language) + if len(index) == 0 || len(size) == 0 || len(t) == 0 || len(categoryId) == 0 { + c.JSON(http.StatusOK, &model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + collection := service.MyService.Casa().GetServerList(index, size, t, categoryId, key) // for i := 0; i < len(recommend); i++ { // ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion) // if ct != nil { @@ -57,9 +60,9 @@ func AppList(c *gin.Context) { // } // } data := make(map[string]interface{}, 3) - data["recommend"] = recommend - data["list"] = list - data["community"] = community + data["recommend"] = collection.Community + data["list"] = collection.List + data["community"] = collection.Community c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) } @@ -210,7 +213,7 @@ func AppInfo(c *gin.Context) { // sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap)) // sort.DevSort(devOrder).Sort(info.Devices) - info.MaxMemory = service.MyService.System().GetMemInfo().Total >> 20 + info.MaxMemory = (service.MyService.System().GetMemInfo()["total"]).(uint64) >> 20 c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info}) } @@ -229,8 +232,8 @@ func CategoryList(c *gin.Context) { count += category.Count } - rear := append([]model.ServerCategoryList{}, list[0:]...) - list = append(list[:0], model.ServerCategoryList{Count: count, Name: "All", Font: "apps"}) + rear := append([]model.CategoryList{}, list[0:]...) + list = append(list[:0], model.CategoryList{Count: count, Name: "All", Font: "apps"}) list = append(list, rear...) c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) } diff --git a/route/v1/ddns.go b/route/v1/ddns.go deleted file mode 100644 index 387693f..0000000 --- a/route/v1/ddns.go +++ /dev/null @@ -1,175 +0,0 @@ -package v1 - -import ( - "fmt" - "net/http" - "os/exec" - "strconv" - "strings" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/forease/gotld" - "github.com/gin-gonic/gin" -) - -// @Summary 获取可以设置的ddns列表 -// @Produce application/json -// @Accept application/json -// @Tags ddns -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /ddns/getlist [get] -func DDNSGetDomainList(c *gin.Context) { - - host, domain, tld := gotld.GetSubdomain("bbb.aaa.liru-05.com.cn", 3) - fmt.Println(strings.Replace(host, "."+domain, "", 1)) - fmt.Println(domain) - fmt.Println(tld) - - data := make(map[string]interface{}, 2) - t, api := service.MyService.DDNS().GetType("godaddy") - data["godaddy"] = &model.GoDaddyModel{Type: t, ApiHost: api} - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: data, - }) - return -} - -// @Summary 添加新的ddns(按给定模型返回内容) -// @Produce application/json -// @Accept multipart/form-data -// @Tags ddns -// @Param type formData string true "类型" -// @Param host formData string true "host" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /ddns/set [post] -func DDNSAddConfig(c *gin.Context) { - t, _ := strconv.Atoi(c.PostForm("type")) - host := c.PostForm("host") - _, domain, _ := gotld.GetSubdomain("host", 3) - sub := strings.ReplaceAll(host, "."+domain, "") - - if service.MyService.DDNS().IsExis(t, domain, sub) { - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.ERROR, - Message: "Repeat add", - }) - return - } - var m model2.DDNSUpdateDBModel - c.Bind(&m) - if err := service.MyService.DDNS().SaveConfig(m); 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), - }) -} - -// @Summary 获取ip,仅做展示使用 -// @Produce application/json -// @Accept application/json -// @Tags ddns -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /ddns/ip [get] -func DDNSGetIP(c *gin.Context) { - ipv4, ipv6 := service.MyService.DDNS().GetExternalIP() - var ipjson = make(map[string]string, 2) - ipjson["ipv4"] = ipv4 - ipjson["ipv6"] = ipv6 - c.JSON(http.StatusOK, &model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: ipjson, - }) -} - -// @Summary 测试网址是否可以ping通 -// @Produce application/json -// @Accept application/json -// @Tags ddns -// @Param api_host path int true "api地址" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /ddns/ping/{api_host} [get] -func DDNSPing(c *gin.Context) { - url := c.Param("api_host") - url = strings.ReplaceAll(url, "https://", "") - url = strings.ReplaceAll(url, "http://", "") - cmd := exec.Command("ping", url, "-c", "1", "-W", "5") - err := cmd.Run() - if err != nil { - c.JSON(http.StatusOK, &model.Result{ - Success: common_err.ERROR, - Message: err.Error(), - Data: false, - }) - } else { - c.JSON(http.StatusOK, &model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: true, - }) - } -} - -// @Summary 获取已设置的列表 -// @Produce application/json -// @Accept application/json -// @Tags ddns -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /ddns/list [get] -func DDNSConfigList(c *gin.Context) { - j := service.MyService.DDNS().GetConfigList() - ip4 := ip_helper2.GetExternalIPV4() - ip6 := ip_helper2.GetExternalIPV6() - for i := 0; i < len(*j); i++ { - (*j)[i].IPV6 = ip6 - (*j)[i].IPV4 = ip4 - cmd := exec.Command("ping", (*j)[i].Host+"."+(*j)[i].Domain, "-c", "1", "-W", "3") - err := cmd.Run() - if err != nil { - (*j)[i].State = false - } else { - (*j)[i].State = true - } - } - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: j}) -} - -// @Summary 删除ddns -// @Produce application/json -// @Accept application/json -// @Tags ddns -// @Param id path int true "ID" -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /ddns/delete/{id} [delete] -func DDNSDelete(c *gin.Context) { - id, err := strconv.ParseUint(c.Param("id"), 10, 32) - if err != nil { - c.JSON(http.StatusOK, &model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - isok := service.MyService.DDNS().DeleteConfig(uint(id)) - c.JSON(http.StatusOK, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: isok}) -} diff --git a/route/v1/disk.go b/route/v1/disk.go index d7936c8..183703c 100644 --- a/route/v1/disk.go +++ b/route/v1/disk.go @@ -11,6 +11,7 @@ import ( "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/encryption" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/service" model2 "github.com/IceWhaleTech/CasaOS/service/model" @@ -201,13 +202,20 @@ func GetDiskInfo(c *gin.Context) { // @Param volume formData string true "mount point" // @Success 200 {string} string "ok" // @Router /disk/format [post] -func FormatDisk(c *gin.Context) { - path := c.PostForm("path") +func PostDiskFormat(c *gin.Context) { + json := make(map[string]string) + c.BindJSON(&json) + path := json["path"] t := "ext4" - pwd := c.PostForm("pwd") - volume := c.PostForm("volume") - - if pwd != config.UserInfo.PWD { + pwd := json["pwd"] + volume := json["volume"] + id := c.GetHeader("user_id") + user := service.MyService.User().GetUserAllInfoById(id) + if user.Id == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + if encryption.GetMD5ByStr(pwd) != user.Password { c.JSON(http.StatusOK, model.Result{Success: common_err.PWD_INVALID, Message: common_err.GetMsg(common_err.PWD_INVALID)}) return } @@ -278,10 +286,13 @@ func RemovePartition(c *gin.Context) { // @Param format formData bool true "need format(true)" // @Success 200 {string} string "ok" // @Router /disk/storage [post] -func AddPartition(c *gin.Context) { - name := c.PostForm("name") - path := c.PostForm("path") - format, _ := strconv.ParseBool(c.PostForm("format")) +func PostDiskAddPartition(c *gin.Context) { + json := make(map[string]string) + c.BindJSON(&json) + + name := json["name"] + path := json["path"] + format, _ := strconv.ParseBool(json["format"]) if len(name) == 0 || len(path) == 0 { c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return diff --git a/route/v1/docker.go b/route/v1/docker.go index 78d3760..5c252b7 100644 --- a/route/v1/docker.go +++ b/route/v1/docker.go @@ -2,7 +2,6 @@ package v1 import ( "bytes" - "encoding/json" json2 "encoding/json" "net/http" "path/filepath" @@ -14,10 +13,8 @@ import ( "github.com/IceWhaleTech/CasaOS/model/notify" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/docker" - upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port" "github.com/IceWhaleTech/CasaOS/pkg/utils/random" "github.com/IceWhaleTech/CasaOS/service" @@ -224,7 +221,6 @@ func InstallApp(c *gin.Context) { return } } - } if m.Origin == "custom" { for _, device := range m.Devices { @@ -375,53 +371,6 @@ func InstallApp(c *gin.Context) { // service.MyService.Notify().UpdateLog(installLog) } - if m.Origin != CUSTOM { - //step:enable upnp - if m.EnableUPNP { - upnp, err := upnp2.Gateway() - if err == nil { - for _, p := range m.Ports { - if p.Protocol == "udp" { - upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl) - upnp.LocalHost = ip_helper2.GetLoclIp() - tComment, _ := strconv.Atoi(p.CommendPort) - upnp.AddPortMapping(tComment, tComment, "UDP") - time.Sleep(time.Millisecond * 200) - } else if p.Protocol == "tcp" { - upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl) - upnp.LocalHost = ip_helper2.GetLoclIp() - tComment, _ := strconv.Atoi(p.CommendPort) - upnp.AddPortMapping(tComment, tComment, "TCP") - time.Sleep(time.Millisecond * 200) - } else if p.Protocol == "both" { - - upnp.CtrlUrl = upnp2.GetCtrlUrl(upnp.GatewayHost, upnp.DeviceDescUrl) - upnp.LocalHost = ip_helper2.GetLoclIp() - tComment, _ := strconv.Atoi(p.CommendPort) - upnp.AddPortMapping(tComment, tComment, "UDP") - time.Sleep(time.Millisecond * 200) - - upnp.AddPortMapping(tComment, tComment, "TCP") - time.Sleep(time.Millisecond * 200) - } - - } - - } - // if err != nil { - // //service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":95}", 100) - // installLog.State = 0 - // installLog.Type = types.NOTIFY_TYPE_ERROR - // installLog.Message = err.Error() - // service.MyService.Notify().UpdateLog(installLog) - // } else { - // //service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"checking\",\"speed\":95}", 100) - // installLog.Message = "checking" - // service.MyService.Notify().UpdateLog(installLog) - // } - } - } - //step: 启动成功 检查容器状态确认启动成功 container, err := service.MyService.Docker().DockerContainerInfo(m.Label) if err != nil && container.ContainerJSONBase.State.Running { @@ -1042,38 +991,6 @@ func PutAppUpdate(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) } -// @Summary get app index -// @Produce application/json -// @Accept application/json -// @Tags app -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /app/order [get] -func GetAppOrder(c *gin.Context) { - id := c.GetHeader("user_id") - data := service.MyService.System().GetAppOrderFile(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json.RawMessage(data)}) -} - -// @Summary update app index -// @Produce application/json -// @Accept application/json -// @Tags app -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /app/order [post] -func PostAppOrder(c *gin.Context) { - data := c.PostForm("data") - id := c.GetHeader("user_id") - service.MyService.System().UpAppOrderFile(data, id) - c.JSON(http.StatusOK, - model.Result{ - Success: common_err.SUCCESS, - Message: common_err.GetMsg(common_err.SUCCESS), - Data: json.RawMessage(data), - }) -} - // @Summary 获取容器详情 // @Produce application/json // @Accept application/json @@ -1087,7 +1004,7 @@ func ContainerInfo(c *gin.Context) { appInfo := service.MyService.App().GetAppDBInfo(appId) containerInfo, _ := service.MyService.Docker().DockerContainerStats(appId) var cpuModel = "arm" - if cpu := service.MyService.ZiMa().GetCpuInfo(); len(cpu) > 0 { + if cpu := service.MyService.System().GetCpuInfo(); len(cpu) > 0 { if strings.Count(strings.ToLower(strings.TrimSpace(cpu[0].ModelName)), "intel") > 0 { cpuModel = "intel" } else if strings.Count(strings.ToLower(strings.TrimSpace(cpu[0].ModelName)), "amd") > 0 { @@ -1111,7 +1028,7 @@ func ContainerInfo(c *gin.Context) { data := make(map[string]interface{}, 5) data["app"] = appInfo data["cpu"] = cpuModel - data["memory"] = service.MyService.System().GetMemInfo().Total + data["memory"] = service.MyService.System().GetMemInfo()["total"] data["container"] = json2.RawMessage(containerInfo) data["info"] = con c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) diff --git a/route/v1/file.go b/route/v1/file.go index 8df79da..ffc55ef 100644 --- a/route/v1/file.go +++ b/route/v1/file.go @@ -233,7 +233,7 @@ func GetDownloadSingleFile(c *gin.Context) { // @Router /file/dirpath [get] func DirPath(c *gin.Context) { path := c.DefaultQuery("path", "") - info := service.MyService.ZiMa().GetDirPath(path) + info := service.MyService.System().GetDirPath(path) if path == "/DATA/AppData" { list := service.MyService.Docker().DockerContainerList() apps := make(map[string]string, len(list)) @@ -318,7 +318,7 @@ func RenamePath(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } - success, err := service.MyService.ZiMa().RenameFile(op, np) + success, err := service.MyService.System().RenameFile(op, np) c.JSON(http.StatusOK, model.Result{Success: success, Message: common_err.GetMsg(success), Data: err}) } @@ -344,7 +344,7 @@ func MkdirAll(c *gin.Context) { // c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) // return // } - code, _ = service.MyService.ZiMa().MkdirAll(path) + code, _ = service.MyService.System().MkdirAll(path) c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)}) } @@ -370,7 +370,7 @@ func PostCreateFile(c *gin.Context) { // c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) // return // } - code, _ = service.MyService.ZiMa().CreateFile(path) + code, _ = service.MyService.System().CreateFile(path) c.JSON(http.StatusOK, model.Result{Success: code, Message: common_err.GetMsg(code)}) } diff --git a/route/v1/share_directory.go b/route/v1/share_directory.go deleted file mode 100644 index 496ca8d..0000000 --- a/route/v1/share_directory.go +++ /dev/null @@ -1,145 +0,0 @@ -package v1 - -import ( - "net/http" - "strconv" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/gin-gonic/gin" -) - -// @Summary 获取列表 -// @Produce application/json -// @Accept application/json -// @Tags share -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /share/list [get] -func GetShareDirList(c *gin.Context) { - list := service.MyService.ShareDirectory().List(true) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -// @Summary 添加文件共享 -// @Produce application/json -// @Accept multipart/form-data -// @Tags share -// @Security ApiKeyAuth -// @Param path formData string true "要分享的文件路径" -// @Param name formData string true "名称" -// @Param comment formData string true "描述" -// @Param read_only formData bool false "是否只读" -// @Param writeable formData bool false "是否可写" -// @Param browseable formData bool false "是否可浏览" -// @Param user formData string false "用户" -// @Success 200 {string} string "ok" -// @Router /share/add [post] -func PostShareDirAdd(c *gin.Context) { - - name := c.PostForm("name") - comment := c.PostForm("comment") - path := c.PostForm("path") - readOnly, _ := strconv.ParseBool(c.DefaultPostForm("read_only", "false")) - writeable, _ := strconv.ParseBool(c.DefaultPostForm("writeable", "true")) - browse, _ := strconv.ParseBool(c.DefaultPostForm("browseable", "true")) - user := c.PostForm("user") - - if len(name) == 0 || len(comment) == 0 || len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - var m model2.ShareDirDBModel - m.Name = name - m.Comment = comment - m.Path = path - m.ReadOnly = readOnly - m.Writeable = writeable - m.Browseable = browse - m.ValidUsers = user - - service.MyService.ShareDirectory().Add(&m) - service.MyService.ShareDirectory().UpConfig() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary 删除分享 -// @Produce application/json -// @Accept application/json -// @Tags share -// @Security ApiKeyAuth -// @Param id path string true "id" -// @Success 200 {string} string "ok" -// @Router /share/del/{id} [delete] -func DeleteShareDirDel(c *gin.Context) { - id := c.Param("id") - service.MyService.ShareDirectory().Delete(id) - service.MyService.ShareDirectory().UpConfig() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary 分享详情 -// @Produce application/json -// @Accept application/json -// @Tags share -// @Security ApiKeyAuth -// @Param id path string true "id" -// @Success 200 {string} string "ok" -// @Router /share/info/{id} [get] -func GetShareDirInfo(c *gin.Context) { - id := c.Param("id") - info := service.MyService.ShareDirectory().Info(id) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info}) -} - -// @Summary 更新分享详情 -// @Produce application/json -// @Accept application/json -// @Tags share -// @Security ApiKeyAuth -// @Param id path string true "id" -// @Param path formData string true "要分享的文件路径" -// @Param name formData string true "名称" -// @Param comment formData string true "描述" -// @Param read_only formData bool false "是否只读" -// @Param writeable formData bool false "是否可写" -// @Param browseable formData bool false "是否可浏览" -// @Param user formData string false "用户" -// @Success 200 {string} string "ok" -// @Router /share/update/{id} [put] -func PutShareDirEdit(c *gin.Context) { - id, err := strconv.ParseUint(c.Param("id"), 10, 32) - - if err != nil || id == 0 { - //todo 报错出去 - } - - name := c.PostForm("name") - comment := c.PostForm("comment") - path := c.PostForm("path") - readOnly, _ := strconv.ParseBool(c.DefaultPostForm("read_only", "false")) - writeable, _ := strconv.ParseBool(c.DefaultPostForm("writeable", "true")) - browse, _ := strconv.ParseBool(c.DefaultPostForm("browseable", "true")) - user := c.PostForm("user") - - if len(name) == 0 || len(comment) == 0 || len(path) == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - - var m model2.ShareDirDBModel - m.Id = uint(id) - m.Name = name - m.Comment = comment - m.Path = path - m.ReadOnly = readOnly - m.Writeable = writeable - m.Browseable = browse - m.ValidUsers = user - service.MyService.ShareDirectory().Update(&m) - service.MyService.ShareDirectory().UpConfig() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} diff --git a/route/v1/sync.go b/route/v1/sync.go index 8449312..14a7f65 100644 --- a/route/v1/sync.go +++ b/route/v1/sync.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2021-11-08 18:02:02 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-15 14:30:24 + * @LastEditTime: 2022-06-21 19:13:59 * @FilePath: /CasaOS/route/v1/sync.go * @Description: * @Website: https://www.casaos.io @@ -12,9 +12,6 @@ package v1 import ( "net/http" - "net/http/httputil" - "net/url" - "strings" "github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/pkg/config" @@ -22,21 +19,6 @@ import ( "github.com/gin-gonic/gin" ) -func SyncToSyncthing(c *gin.Context) { - u := c.Param("url") - target := "http://" + strings.Split(c.Request.Host, ":")[0] + ":" + config.SystemConfigInfo.SyncPort - remote, err := url.Parse(target) - if err != nil { - return - } - proxy := httputil.NewSingleHostReverseProxy(remote) - c.Request.Header.Add("X-API-Key", config.SystemConfigInfo.SyncKey) - //c.Request.Header.Add("X-API-Key", config.SystemConfigInfo.SyncKey) - c.Request.URL.Path = u - - proxy.ServeHTTP(c.Writer, c.Request) -} - func GetSyncConfig(c *gin.Context) { data := make(map[string]string) data["key"] = config.SystemConfigInfo.SyncKey diff --git a/route/v1/system.go b/route/v1/system.go index d7ef23f..b68e342 100644 --- a/route/v1/system.go +++ b/route/v1/system.go @@ -12,10 +12,8 @@ import ( "unsafe" "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/model/system_model" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt" port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port" "github.com/IceWhaleTech/CasaOS/pkg/utils/version" "github.com/IceWhaleTech/CasaOS/service" @@ -33,7 +31,7 @@ import ( // @Success 200 {string} string "ok" // @Router /sys/version/check [get] func GetSystemCheckVersion(c *gin.Context) { - need, version := version.IsNeedUpdate() + need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion()) if need { installLog := model2.AppNotify{} installLog.State = 0 @@ -44,7 +42,7 @@ func GetSystemCheckVersion(c *gin.Context) { installLog.Name = "CasaOS System" service.MyService.Notify().AddLog(installLog) } - data := make(map[string]interface{}, 1) + data := make(map[string]interface{}, 3) data["is_need"] = need data["version"] = version data["current_version"] = types.CURRENTVERSION @@ -59,7 +57,7 @@ func GetSystemCheckVersion(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /sys/update [post] func SystemUpdate(c *gin.Context) { - need, version := version.IsNeedUpdate() + need, version := version.IsNeedUpdate(service.MyService.Casa().GetCasaosVersion()) if need { service.MyService.System().UpdateSystemVersion(version.Version) } @@ -108,8 +106,8 @@ func PostSetSystemConfig(c *gin.Context) { func GetSystemConfigDebug(c *gin.Context) { array := service.MyService.System().GetSystemConfigDebug() - disk := service.MyService.ZiMa().GetDiskInfo() - sys := service.MyService.ZiMa().GetSysInfo() + disk := service.MyService.System().GetDiskInfo() + sys := service.MyService.System().GetSysInfo() //todo 准备sync需要显示的数据(镜像,容器) var systemAppStatus string images := service.MyService.Docker().IsExistImage("linuxserver/syncthing") @@ -224,20 +222,23 @@ func PutCasaOSPort(c *gin.Context) { // @Security ApiKeyAuth // @Success 200 {string} string "ok" // @Router /sys/init/check [get] -func GetGuideCheck(c *gin.Context) { +func GetSystemInitCheck(c *gin.Context) { data := make(map[string]interface{}, 2) if service.MyService.User().GetUserCount() > 0 { data["initialized"] = true + data["key"] = "" } else { - data["key"] = uuid.NewV4().String() + key := uuid.NewV4().String() + service.UserRegisterHash[key] = key + data["key"] = key data["initialized"] = false } c.JSON(http.StatusOK, model.Result{ Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), - Data: true, + Data: data, }) } @@ -307,7 +308,7 @@ func GetSystemUSBAutoMount(c *gin.Context) { func GetSystemHardwareInfo(c *gin.Context) { data := make(map[string]string, 1) - data["drive_model"] = service.MyService.ZiMa().GetDeviceTree() + data["drive_model"] = service.MyService.System().GetDeviceTree() c.JSON(http.StatusOK, model.Result{ Success: common_err.SUCCESS, @@ -438,7 +439,7 @@ func GetSystemUtilization(c *gin.Context) { for _, netCardName := range nets { if n.Name == netCardName { item := *(*model.IOCountersStat)(unsafe.Pointer(&n)) - item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name)) + item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name)) item.Time = time.Now().Unix() newNet = append(newNet, item) break @@ -506,7 +507,7 @@ func GetSystemMemInfo(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /sys/disk [get] func GetSystemDiskInfo(c *gin.Context) { - disk := service.MyService.ZiMa().GetDiskInfo() + disk := service.MyService.System().GetDiskInfo() c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: disk}) } @@ -525,7 +526,7 @@ func GetSystemNetInfo(c *gin.Context) { for _, netCardName := range service.MyService.System().GetNet(true) { if n.Name == netCardName { item := *(*model.IOCountersStat)(unsafe.Pointer(&n)) - item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name)) + item.State = strings.TrimSpace(service.MyService.System().GetNetState(n.Name)) item.Time = time.Now().Unix() newNet = append(newNet, item) break @@ -535,31 +536,3 @@ func GetSystemNetInfo(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: newNet}) } - -//refresh token -func PostSystemRefreshToken(c *gin.Context) { - json := make(map[string]string) - c.BindJSON(&json) - refresh := json["refresh_token"] - claims, err := jwt.ParseToken(refresh) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()}) - return - } - if claims.VerifyExpiresAt(time.Now(), true) || claims.VerifyIssuer("refresh", true) { - c.JSON(http.StatusOK, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)}) - return - } - newToken := jwt.GetAccessToken(claims.UserName, claims.PassWord, claims.Id) - if err != nil { - c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) - return - } - verifyInfo := system_model.VerifyInformation{} - verifyInfo.AccessToken = newToken - verifyInfo.RefreshToken = jwt.GetRefreshToken(claims.UserName, claims.PassWord, claims.Id) - verifyInfo.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Format("2006-01-02 15:04:05") - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo}) - -} diff --git a/route/v1/task.go b/route/v1/task.go deleted file mode 100644 index 4ead579..0000000 --- a/route/v1/task.go +++ /dev/null @@ -1,69 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2021-09-30 18:18:14 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-15 14:30:44 - * @FilePath: /CasaOS/route/v1/task.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package v1 - -import ( - "net/http" - "strconv" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/service" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/gin-gonic/gin" -) - -// @Summary 获取task列表 -// @Produce application/json -// @Accept application/json -// @Tags task -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /task/list [get] -func GetTaskList(c *gin.Context) { - //list := service.MyService.Task().List(true) - list := service.MyService.Task().GetServerTasks() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: list}) -} - -func PutTaskUpdate(c *gin.Context) { - service.MyService.Task().SyncTaskService() - - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -// @Summary 标记task已完成 -// @Produce application/json -// @Accept application/json -// @Tags task -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /task/completion/{id} [put] -func PutTaskMarkerCompletion(c *gin.Context) { - id, _ := strconv.Atoi(c.Param("id")) - if id == 0 { - c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) - return - } - var m model2.TaskDBModel - m.Id = uint(id) - m.State = types.TASK_STATE_COMPLETED - service.MyService.Task().Update(&m) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} - -func PostTaskAdd(c *gin.Context) { - var m model2.TaskDBModel - c.BindJSON(&m) - service.MyService.Task().Add(&m) - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) -} diff --git a/route/v1/user.go b/route/v1/user.go index 4e623b5..ae4d63a 100644 --- a/route/v1/user.go +++ b/route/v1/user.go @@ -1,8 +1,15 @@ package v1 import ( + "encoding/json" + "io/ioutil" "net/http" + url2 "net/url" + "os" + "path" + "path/filepath" "strconv" + "strings" "time" "github.com/IceWhaleTech/CasaOS/model" @@ -13,6 +20,7 @@ import ( "github.com/IceWhaleTech/CasaOS/pkg/utils/file" "github.com/IceWhaleTech/CasaOS/pkg/utils/jwt" model2 "github.com/IceWhaleTech/CasaOS/service/model" + "github.com/tidwall/gjson" "github.com/IceWhaleTech/CasaOS/service" "github.com/gin-gonic/gin" @@ -25,7 +33,7 @@ func PostUserRegister(c *gin.Context) { c.BindJSON(&json) username := json["user_name"] pwd := json["password"] - key := c.GetHeader("key") + key := c.Param("key") if _, ok := service.UserRegisterHash[key]; !ok { c.JSON(http.StatusOK, model.Result{Success: common_err.KEY_NOT_EXIST, Message: common_err.GetMsg(common_err.KEY_NOT_EXIST)}) @@ -73,7 +81,7 @@ func PostUserRegister(c *gin.Context) { // @Param pwd query string true "password" // @Success 200 {string} string "ok" // @Router /user/login [post] -func Login(c *gin.Context) { +func PostUserLogin(c *gin.Context) { json := make(map[string]string) c.BindJSON(&json) @@ -88,7 +96,7 @@ func Login(c *gin.Context) { }) return } - user := service.MyService.User().GetUserInfoByUserName(username) + user := service.MyService.User().GetUserAllInfoByName(username) if user.Id == 0 { c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) @@ -103,7 +111,7 @@ func Login(c *gin.Context) { token := system_model.VerifyInformation{} token.AccessToken = jwt.GetAccessToken(user.UserName, user.Password, user.Id) token.RefreshToken = jwt.GetRefreshToken(user.UserName, user.Password, user.Id) - token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Format("2006-01-02 15:04:05") + token.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix() data := make(map[string]interface{}, 2) data["token"] = token data["user"] = user @@ -116,24 +124,59 @@ func Login(c *gin.Context) { }) } -// // @Summary edit user head -// // @Produce application/json -// // @Accept multipart/form-data -// // @Tags user -// // @Param file formData file true "用户头像" -// // @Security ApiKeyAuth -// // @Success 200 {string} string "ok" -// // @Router /user/changhead [post] -// func PostUserHead(c *gin.Context) { -// file, _, _ := c.Request.FormFile("file") -// user_service.UpLoadFile(file, config.UserInfo.Head) -// c.JSON(http.StatusOK, -// model.Result{ -// Success: common_err.SUCCESS, -// Message: common_err.GetMsg(common_err.SUCCESS), -// Data: config.UserInfo.Head, -// }) -// } +// @Summary edit user head +// @Produce application/json +// @Accept multipart/form-data +// @Tags user +// @Param file formData file true "用户头像" +// @Security ApiKeyAuth +// @Success 200 {string} string "ok" +// @Router /user/avatar [put] +func PutUserAvatar(c *gin.Context) { + id := c.GetHeader("user_id") + user := service.MyService.User().GetUserInfoById(id) + if user.Id == 0 { + c.JSON(http.StatusOK, + model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + f, err := c.FormFile("file") + if err != nil { + c.JSON(http.StatusOK, + model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + return + } + if len(user.Avatar) > 0 { + os.RemoveAll(config.AppInfo.UserDataPath + "/" + id + "/" + user.Avatar) + } + ext := filepath.Ext(f.Filename) + avatarPath := config.AppInfo.UserDataPath + "/" + id + "/avatar" + ext + c.SaveUploadedFile(f, avatarPath) + user.Avatar = avatarPath + service.MyService.User().UpdateUser(user) + c.JSON(http.StatusOK, + model.Result{ + Success: common_err.SUCCESS, + Message: common_err.GetMsg(common_err.SUCCESS), + Data: user, + }) +} + +/** + * @description: get user avatar by user id + * @param {query} id string user id + * @method: GET + */ +func GetUserAvatar(c *gin.Context) { + id := c.Param("id") + user := service.MyService.User().GetUserInfoById(id) + + path := "default.png" + if user.Id > 0 { + path = user.Avatar + } + c.File(path) +} // @Summary edit user name // @Produce application/json @@ -144,7 +187,7 @@ func Login(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /user/name/:id [put] func PutUserName(c *gin.Context) { - id := c.Param("id") + id := c.GetHeader("user_id") json := make(map[string]string) c.BindJSON(&json) userName := json["user_name"] @@ -172,7 +215,7 @@ func PutUserName(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /user/password/:id [put] func PutUserPwd(c *gin.Context) { - id := c.Param("id") + id := c.GetHeader("user_id") json := make(map[string]string) c.BindJSON(&json) oldPwd := json["old_password"] @@ -181,7 +224,7 @@ func PutUserPwd(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) return } - user := service.MyService.User().GetUserInfoById(id) + user := service.MyService.User().GetUserAllInfoById(id) if user.Id == 0 { c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) @@ -192,7 +235,8 @@ func PutUserPwd(c *gin.Context) { return } user.Password = encryption.GetMD5ByStr(pwd) - service.MyService.User().UpdateUser(user) + service.MyService.User().UpdateUserPassword(user) + user.Password = "" c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) } @@ -232,16 +276,15 @@ func PutUserPwd(c *gin.Context) { // @Summary edit user nick // @Produce application/json -// @Accept multipart/form-data +// @Accept application/json // @Tags user -// @Param nick_name formData string false "nick name" +// @Param nick_name query string false "nick name" // @Security ApiKeyAuth // @Success 200 {string} string "ok" // @Router /user/nick [put] - func PutUserNick(c *gin.Context) { - id := c.Param("id") + id := c.GetHeader("user_id") json := make(map[string]string) c.BindJSON(&json) nickName := json["nick_name"] @@ -273,7 +316,7 @@ func PutUserNick(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /user/desc [put] func PutUserDesc(c *gin.Context) { - id := c.Param("id") + id := c.GetHeader("user_id") json := make(map[string]string) c.BindJSON(&json) @@ -295,29 +338,29 @@ func PutUserDesc(c *gin.Context) { c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: user}) } -// // @Summary Modify user person information (Initialization use) -// // @Produce application/json -// // @Accept multipart/form-data -// // @Tags user -// // @Param nick_name formData string false "user nick name" -// // @Param description formData string false "Description" -// // @Security ApiKeyAuth -// // @Success 200 {string} string "ok" -// // @Router /user/person/info [post] -// func PostUserPersonInfo(c *gin.Context) { -// desc := c.PostForm("description") -// nickName := c.PostForm("nick_name") -// if len(desc) == 0 || len(nickName) == 0 { -// c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) -// return -// } -// user_service.SetUser("", "", "", "", desc, nickName) -// data := make(map[string]string, 2) -// data["description"] = config.UserInfo.Description -// data["nick_name"] = config.UserInfo.NickName -// go service.MyService.Casa().PushUserInfo() -// c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) -// } +// @Summary Modify user person information (Initialization use) +// @Produce application/json +// @Accept multipart/form-data +// @Tags user +// @Param nick_name formData string false "user nick name" +// @Param description formData string false "Description" +// @Security ApiKeyAuth +// @Success 200 {string} string "ok" +// @Router /user/person/info [post] +func PostUserPersonInfo(c *gin.Context) { + desc := c.PostForm("description") + nickName := c.PostForm("nick_name") + if len(desc) == 0 || len(nickName) == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + //user_service.SetUser("", "", "", "", desc, nickName) + data := make(map[string]string, 2) + data["description"] = config.UserInfo.Description + data["nick_name"] = config.UserInfo.NickName + go service.MyService.Casa().PushUserInfo() + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) +} // @Summary get user info // @Produce application/json @@ -326,7 +369,7 @@ func PutUserDesc(c *gin.Context) { // @Success 200 {string} string "ok" // @Router /user/info/:id [get] func GetUserInfo(c *gin.Context) { - id := c.Param("id") + id := c.GetHeader("user_id") user := service.MyService.User().GetUserInfoById(id) c.JSON(http.StatusOK, model.Result{ @@ -347,10 +390,11 @@ func GetUserShareID(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 get user info -// @Produce application/json -// @Accept application/json -// @Tags user +/** + * @description: get all user name + * @method:GET + * @router:/user/all/name + */ func GetUserAllUserName(c *gin.Context) { users := service.MyService.User().GetAllUserName() names := []string{} @@ -364,3 +408,234 @@ func GetUserAllUserName(c *gin.Context) { Data: names, }) } + +/** + * @description:get custom file by user + * @param {path} name string "file name" + * @method: GET + * @router: /user/custom/:key + */ +func GetUserCustomConf(c *gin.Context) { + name := c.Param("key") + if len(name) == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + id := c.GetHeader("user_id") + filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json" + data := file.ReadFullFile(filePath) + if !gjson.ValidBytes(data) { + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)}) + return + } + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json.RawMessage(string(data))}) +} + +/** + * @description:create or update custom conf by user + * @param {path} name string "file name" + * @method:POST + * @router:/user/custom/:key + */ +func PostUserCustomConf(c *gin.Context) { + name := c.Param("key") + if len(name) == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + id := c.GetHeader("user_id") + data, _ := ioutil.ReadAll(c.Request.Body) + filePath := config.AppInfo.UserDataPath + "/" + id + file.WriteToPath(data, filePath, name+".json") + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json.RawMessage(string(data))}) +} + +/** + * @description: delete user custom config + * @param {path} key string + * @method:delete + * @router:/user/custom/:key + */ +func DeleteUserCustomConf(c *gin.Context) { + name := c.Param("key") + if len(name) == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + id := c.GetHeader("user_id") + filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json" + os.Remove(filePath) + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) +} + +/** + * @description: + * @param {path} id string "user id" + * @method:DELETE + * @router:/user/delete/:id + */ +func DeleteUser(c *gin.Context) { + id := c.Param("id") + service.MyService.User().DeleteUserById(id) + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) +} + +/** + * @description:update user image + * @method:POST + * @router:/user/file/image/:key + */ +func PostUserFileImage(c *gin.Context) { + id := c.GetHeader("user_id") + json := make(map[string]string) + c.BindJSON(&json) + path := json["path"] + key := c.Param("key") + if len(path) == 0 || len(key) == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + if !file.Exists(path) { + c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)}) + return + } + + _, err := file.GetImageExt(path) + + if err != nil { + c.JSON(http.StatusOK, model.Result{Success: common_err.NOT_IMAGE, Message: common_err.GetMsg(common_err.NOT_IMAGE)}) + return + } + user := service.MyService.User().GetUserInfoById(id) + if user.Id == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + fstat, _ := os.Stat(path) + if fstat.Size() > 10<<20 { + c.JSON(http.StatusOK, model.Result{Success: common_err.IMAGE_TOO_LARGE, Message: common_err.GetMsg(common_err.IMAGE_TOO_LARGE)}) + return + } + ext := file.GetExt(path) + filePath := config.AppInfo.UserDataPath + "/" + id + "/" + key + ext + file.CopySingleFile(path, filePath, "overwrite") + + data := make(map[string]string, 3) + data["path"] = filePath + data["file_name"] = key + ext + data["online_path"] = "/v1/user/image?path=" + filePath + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) +} + +/** + * @description:create or update user's custom image + * @param {formData} file file "a file to be uploaded" + * @param {path} key string "file name" + * @method:POST + * @router:/user/upload/image/:key + */ +func PostUserUploadImage(c *gin.Context) { + id := c.GetHeader("user_id") + file, err := c.FormFile("file") + key := c.Param("key") + if len(key) == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + if err != nil { + c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + return + } + ext := filepath.Ext(file.Filename) + path := config.AppInfo.UserDataPath + "/" + id + "/" + key + ext + c.SaveUploadedFile(file, path) + user := service.MyService.User().GetUserInfoById(id) + if user.Id == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + data := make(map[string]string, 3) + data["path"] = path + data["file_name"] = key + ext + data["online_path"] = "/v1/user/image?path=" + path + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data}) +} + +/** + * @description: get current user's image + * @method:GET + * @router:/user/image/:id + */ +func GetUserImage(c *gin.Context) { + filePath := c.Query("path") + if len(filePath) == 0 { + c.JSON(http.StatusNotFound, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + if !file.Exists(filePath) { + c.JSON(http.StatusNotFound, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)}) + return + } + if !strings.Contains(filePath, config.AppInfo.UserDataPath) { + c.JSON(http.StatusNotFound, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) + return + } + + fileTmp, _ := os.Open(filePath) + defer fileTmp.Close() + + fileName := path.Base(filePath) + c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName)) + c.File(filePath) +} +func DeleteUserImage(c *gin.Context) { + id := c.GetHeader("user_id") + path := c.Query("path") + if len(path) == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + user := service.MyService.User().GetUserInfoById(id) + if user.Id == 0 { + c.JSON(http.StatusOK, model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) + return + } + if !file.Exists(path) { + c.JSON(http.StatusOK, model.Result{Success: common_err.FILE_DOES_NOT_EXIST, Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST)}) + return + } + if !strings.Contains(path, config.AppInfo.UserDataPath+"/"+id) { + c.JSON(http.StatusOK, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) + return + } + os.Remove(path) + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS)}) +} + +//refresh token +func PostUserRefreshToken(c *gin.Context) { + json := make(map[string]string) + c.BindJSON(&json) + refresh := json["refresh_token"] + claims, err := jwt.ParseToken(refresh) + if err != nil { + c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE), Data: err.Error()}) + return + } + if claims.VerifyExpiresAt(time.Now(), true) || claims.VerifyIssuer("refresh", true) { + c.JSON(http.StatusOK, model.Result{Success: common_err.VERIFICATION_FAILURE, Message: common_err.GetMsg(common_err.VERIFICATION_FAILURE)}) + return + } + newToken := jwt.GetAccessToken(claims.UserName, claims.PassWord, claims.Id) + if err != nil { + c.JSON(http.StatusOK, model.Result{Success: common_err.ERROR, Message: common_err.GetMsg(common_err.ERROR), Data: err.Error()}) + return + } + verifyInfo := system_model.VerifyInformation{} + verifyInfo.AccessToken = newToken + verifyInfo.RefreshToken = jwt.GetRefreshToken(claims.UserName, claims.PassWord, claims.Id) + verifyInfo.ExpiresAt = time.Now().Add(3 * time.Hour * time.Duration(1)).Unix() + + c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: verifyInfo}) + +} diff --git a/route/v1/zima_info.go b/route/v1/zima_info.go deleted file mode 100644 index 558efda..0000000 --- a/route/v1/zima_info.go +++ /dev/null @@ -1,32 +0,0 @@ -/* - * @Author: LinkLeong link@icewhale.com - * @Date: 2021-09-30 18:18:14 - * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 17:54:10 - * @FilePath: /CasaOS/route/v1/zima_info.go - * @Description: - * @Website: https://www.casaos.io - * Copyright (c) 2022 by icewhale, All Rights Reserved. - */ -package v1 - -import ( - "net/http" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/service" - "github.com/gin-gonic/gin" -) - -// @Summary 获取信息系统信息 -// @Produce application/json -// @Accept application/json -// @Tags zima -// @Security ApiKeyAuth -// @Success 200 {string} string "ok" -// @Router /zima/sysinfo [get] -func SysInfo(c *gin.Context) { - info := service.MyService.ZiMa().GetSysInfo() - c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: info}) -} diff --git a/service/app.go b/service/app.go index f464dd9..98fa30a 100644 --- a/service/app.go +++ b/service/app.go @@ -7,7 +7,6 @@ import ( "io" "io/ioutil" "runtime" - "strconv" "strings" "sync" "time" @@ -27,12 +26,7 @@ import ( ) type AppService interface { - CreateApplication(m model2.ApplicationModel) model2.ApplicationModel - GetApplicationList() (m []model2.ApplicationModel) - GetApplicationById(id string) (m model2.ApplicationModel) - UpdateApplicationOrderById(id string, order int) GetMyList(index, size int, position bool) (*[]model2.MyAppList, *[]model2.MyAppList) - GetCasaOSCount() int SaveContainer(m model2.AppListDBModel) GetUninstallInfo(id string) model2.AppListDBModel DeleteApp(id string) @@ -54,24 +48,6 @@ type appStruct struct { db *gorm.DB } -func (a *appStruct) GetApplicationById(id string) (m model2.ApplicationModel) { - a.db.Where("id = ?", id).First(&m) - return -} - -func (a *appStruct) UpdateApplicationOrderById(id string, order int) { - a.db.Model(&model2.ApplicationModel{}).Where("id = ?", id).Update("order", order) -} - -func (a *appStruct) CreateApplication(m model2.ApplicationModel) model2.ApplicationModel { - a.db.Create(&m) - return m -} -func (a *appStruct) GetApplicationList() (m []model2.ApplicationModel) { - a.db.Find(&m) - return -} - func (a *appStruct) CheckNewImage() { list := MyService.Docker().DockerContainerList() for _, v := range list { @@ -155,28 +131,6 @@ func (a *appStruct) ImportApplications(casaApp bool) { // } // MyService.Docker().DockerContainerStart(container_id) //} - -} - -func (a *appStruct) GetCasaOSCount() int { - cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5)) - if err != nil { - loger.Error("Failed to init client", zap.Any("err", err)) - return 0 - } - defer cli.Close() - fts := filters.NewArgs() - fts.Add("label", "casaos=casaos") - //fts.Add("label", "casaos:casaos") - - containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: fts, Limit: 200}) - if err != nil { - loger.Error("failed to get container_list", zap.Any("err", err)) - return 0 - } - - systemApp := MyService.App().GetApplicationList() - return len(containers) + len(systemApp) } //获取我的应用列表 @@ -200,25 +154,6 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi list := []model2.MyAppList{} - systemApp := MyService.App().GetApplicationList() - for _, v := range systemApp { - list = append(list, model2.MyAppList{ - Name: v.Name, - Icon: v.Icon, - State: strconv.Itoa(v.State), - Id: strconv.Itoa(v.Id), - CustomId: strconv.Itoa(v.Id), - Port: "", - //Order: strconv.Itoa(v.Order), - Index: "/", - Image: "", - Type: v.Type, - Host: "", - Protocol: "", - NewVersion: false, - }) - } - for _, m := range containers { if m.Labels["casaos"] == "casaos" { if m.Labels["origin"] == "system" { diff --git a/service/casa.go b/service/casa.go index 496cd87..0216319 100644 --- a/service/casa.go +++ b/service/casa.go @@ -4,29 +4,34 @@ import ( "encoding/json" json2 "encoding/json" "fmt" + "sort" "strconv" "time" "github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/pkg/config" + "github.com/IceWhaleTech/CasaOS/pkg/utils/file" + "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" - model2 "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" + "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/tidwall/gjson" + "go.uber.org/zap" ) type CasaService interface { - GetServerList(index, size, tp, categoryId, key, language string) (recommend, list, community []model.ServerAppList) - GetServerCategoryList() []model.ServerCategoryList - GetTaskList(size int) []model2.TaskDBModel + GetServerList(index, size, tp, categoryId, key string) model.ServerAppListCollection + GetServerCategoryList() []model.CategoryList GetServerAppInfo(id, t string, language string) model.ServerAppList ShareAppFile(body []byte) string PushHeart(id, t string, language string) - PushAppAnalyse(uuid, t string, name, language string) + PushConnectionStatus(uuid, err string, from, to, event string) PushUserInfo() GetUserInfoByShareId(shareId string) model.UserInfo GetPersonPublic() (list []model.FriendsModel) + GetCasaosVersion() model.Version + AsyncGetServerList() (collection model.ServerAppListCollection) + AsyncGetServerCategoryList() []model.CategoryList } type casaService struct { @@ -41,108 +46,186 @@ func (o *casaService) ShareAppFile(body []byte) string { return content } -func (o *casaService) GetTaskList(size int) []model2.TaskDBModel { - head := make(map[string]string) - - head["Authorization"] = GetToken() - - listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/task/list/"+strconv.Itoa(size), head) - - list := []model2.TaskDBModel{} - json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list) - - return list -} - -func (o *casaService) GetServerList(index, size, tp, categoryId, key, language string) (recommend, list, community []model.ServerAppList) { - - keyName := fmt.Sprintf("list_%s_%s_%s_%s_%s", index, size, tp, categoryId, language) +func (o *casaService) GetServerList(index, size, tp, categoryId, key string) model.ServerAppListCollection { + keyName := fmt.Sprintf("list_%s_%s_%s_%s_%s", index, size, tp, categoryId, "en") + collection := model.ServerAppListCollection{} if result, ok := Cache.Get(keyName); ok { res, ok := result.(string) if ok { - json2.Unmarshal([]byte(gjson.Get(res, "data.list").String()), &list) - json2.Unmarshal([]byte(gjson.Get(res, "data.recommend").String()), &recommend) - json2.Unmarshal([]byte(gjson.Get(res, "data.community").String()), &community) - return + json2.Unmarshal([]byte(res), &collection) + return collection } } + collectionStr := file.ReadFullFile(config.AppInfo.DBPath + "/app_list.json") + + err := json2.Unmarshal(collectionStr, &collection) + if err != nil { + loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(collectionStr))) + collection = o.AsyncGetServerList() + } + + go o.AsyncGetServerList() + + if categoryId != "0" { + categoryInt, _ := strconv.Atoi(categoryId) + nList := []model.ServerAppList{} + for _, v := range collection.List { + if v.CategoryId == categoryInt { + nList = append(nList, v) + } + } + collection.List = nList + nCommunity := []model.ServerAppList{} + for _, v := range collection.Community { + if v.CategoryId == categoryInt { + nCommunity = append(nCommunity, v) + } + } + collection.Community = nCommunity + } + if tp != "name" { + if tp == "new" { + sort.Slice(collection.List, func(i, j int) bool { + return collection.List[i].CreatedAt.After(collection.List[j].CreatedAt) + }) + sort.Slice(collection.Community, func(i, j int) bool { + return collection.Community[i].CreatedAt.After(collection.Community[j].CreatedAt) + }) + } else if tp == "rank" { + sort.Slice(collection.List, func(i, j int) bool { + return collection.List[i].QueryCount > collection.List[j].QueryCount + }) + sort.Slice(collection.Community, func(i, j int) bool { + return collection.Community[i].QueryCount > collection.Community[j].QueryCount + }) + } + } + sizeInt, _ := strconv.Atoi(size) + + if index != "1" { + indexInt, _ := strconv.Atoi(index) + collection.List = collection.List[(indexInt-1)*sizeInt : indexInt*sizeInt] + collection.Community = collection.Community[(indexInt-1)*sizeInt : indexInt*sizeInt] + } else { + if len(collection.List) > sizeInt { + collection.List = collection.List[:sizeInt] + } + if len(collection.Community) > sizeInt { + collection.Community = collection.Community[:sizeInt] + } + } + + if len(collection.List) > 0 { + by, _ := json.Marshal(collection) + Cache.Set(keyName, string(by), time.Minute*10) + } + + return collection + +} + +func (o *casaService) AsyncGetServerList() (collection model.ServerAppListCollection) { + + results := file.ReadFullFile(config.AppInfo.DBPath + "/app_list.json") + err := json2.Unmarshal(results, &collection) + if err != nil { + loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) + } + + if collection.Version == o.GetCasaosVersion().Version { + return collection + } + head := make(map[string]string) head["Authorization"] = GetToken() - listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/newlist?index="+index+"&size="+size+"&rank="+tp+"&category_id="+categoryId+"&key="+key+"&language="+language, head) + listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/newlist?index=1&size=1000&rank=name&category_id=0&key=&language=en", head) + listModel := []model.ServerAppList{} + communityModel := []model.ServerAppList{} + recommendModel := []model.ServerAppList{} + json2.Unmarshal([]byte(gjson.Get(listS, "data.list").String()), &listModel) + json2.Unmarshal([]byte(gjson.Get(listS, "data.recommend").String()), &recommendModel) + json2.Unmarshal([]byte(gjson.Get(listS, "data.community").String()), &communityModel) - json2.Unmarshal([]byte(gjson.Get(listS, "data.list").String()), &list) - json2.Unmarshal([]byte(gjson.Get(listS, "data.recommend").String()), &recommend) - json2.Unmarshal([]byte(gjson.Get(listS, "data.community").String()), &community) - - if len(list) > 0 { - Cache.Set(keyName, listS, time.Hour*24) + if len(listModel) > 0 { + collection.Community = communityModel + collection.List = listModel + collection.Recommend = recommendModel + collection.Version = o.GetCasaosVersion().Version + by, err := json.Marshal(collection) + if err != nil { + loger.Error("marshal error", zap.Any("err", err)) + } + file.WriteToPath(by, config.AppInfo.DBPath, "app_list.json") } return } -func (o *casaService) GetServerCategoryList() (list []model.ServerCategoryList) { +// func (o *casaService) GetServerCategoryList() (list []model.ServerCategoryList) { - keyName := fmt.Sprintf("category_list") - if result, ok := Cache.Get(keyName); ok { - res, ok := result.(string) - if ok { - json2.Unmarshal([]byte(gjson.Get(res, "data").String()), &list) - return list - } - } +// keyName := fmt.Sprintf("category_list") +// if result, ok := Cache.Get(keyName); ok { +// res, ok := result.(string) +// if ok { +// json2.Unmarshal([]byte(gjson.Get(res, "data").String()), &list) +// return list +// } +// } - head := make(map[string]string) - head["Authorization"] = GetToken() +// head := make(map[string]string) +// head["Authorization"] = GetToken() - listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head) +// listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head) - json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list) - if len(list) > 0 { - Cache.Set(keyName, listS, time.Hour*24) - } - return list -} - -// func (o *casaService) GetServerCategoryList() (list model.ServerCategoryList) { - -// results := file.ReadFullFile(config.AppInfo.ProjectPath + "/conf/app_category.json") -// err := json2.Unmarshal(results, &list) -// if err != nil { -// loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) +// json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list) +// if len(list) > 0 { +// Cache.Set(keyName, listS, time.Hour*24) // } // return list // } -// func (o *casaService) AsyncGetServerCategoryList() { -// list := model.ServerCategoryList{} -// results := file.ReadFullFile(config.AppInfo.ProjectPath + "/conf/app_category.json") -// err := json2.Unmarshal(results, &list) -// if err != nil { -// loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) -// } +func (o *casaService) GetServerCategoryList() (list []model.CategoryList) { + category := model.ServerCategoryList{} + results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json") + err := json2.Unmarshal(results, &category) + if err != nil { + loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) + return o.AsyncGetServerCategoryList() + } + go o.AsyncGetServerCategoryList() + return category.Item +} -// if list.Version == GetAppVersion() { -// return -// } -// item := []model.CategoryList{} -// head := make(map[string]string) -// head["Authorization"] = GetToken() -// listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head) -// json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &item) -// if len(item) > 0 { -// list.Version = GetAppVersion() -// list.Item = item -// by, err := json.Marshal(list) -// if err != nil { -// loger.Error("marshal error", zap.Any("err", err)) -// } -// file.WriteToPath(by, config.AppInfo.ProjectPath+"/conf", "app_category.json") -// } -// } +func (o *casaService) AsyncGetServerCategoryList() []model.CategoryList { + list := model.ServerCategoryList{} + results := file.ReadFullFile(config.AppInfo.DBPath + "/app_category.json") + err := json2.Unmarshal(results, &list) + if err != nil { + loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results))) + } + + if list.Version == o.GetCasaosVersion().Version { + return nil + } + item := []model.CategoryList{} + head := make(map[string]string) + head["Authorization"] = GetToken() + listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head) + json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &item) + if len(item) > 0 { + list.Version = o.GetCasaosVersion().Version + list.Item = item + by, err := json.Marshal(list) + if err != nil { + loger.Error("marshal error", zap.Any("err", err)) + } + file.WriteToPath(by, config.AppInfo.DBPath, "app_category.json") + } + return item +} func (o *casaService) GetServerAppInfo(id, t string, language string) model.ServerAppList { @@ -178,6 +261,34 @@ func GetToken() string { return auth } +/** + * @description: get remote version + * @return {model.Version} + */ +func (o *casaService) GetCasaosVersion() model.Version { + keyName := "casa_version" + var dataStr string + var version model.Version + if result, ok := Cache.Get(keyName); ok { + dataStr, ok = result.(string) + if ok { + data := gjson.Get(dataStr, "data") + json2.Unmarshal([]byte(data.String()), &version) + return version + } + } + + v := httper.OasisGet(config.ServerInfo.ServerApi + "/v1/sys/version") + data := gjson.Get(v, "data") + json2.Unmarshal([]byte(data.String()), &version) + + if len(version.Version) > 0 { + Cache.Set(keyName, v, time.Minute*20) + } + + return version +} + func (o *casaService) PushHeart(id, t string, language string) { m := model.CasaOSHeart{} @@ -196,26 +307,6 @@ func (o *casaService) PushHeart(id, t string, language string) { } -func (o *casaService) PushAppAnalyse(uuid, t string, name, language string) { - - m := model.AppAnalyse{} - m.UUId = uuid - m.Type = t - m.Name = name - m.Language = language - m.Version = types.CURRENTVERSION - b, _ := json.Marshal(m) - - head := make(map[string]string) - - head["Authorization"] = GetToken() - - infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/app", b, "application/json", head) - - info := model.ServerAppList{} - json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info) - -} func (o *casaService) PushConnectionStatus(uuid, err string, from, to, event string) { m := model.ConnectionStatus{} diff --git a/service/ddns.go b/service/ddns.go deleted file mode 100644 index c55bcb4..0000000 --- a/service/ddns.go +++ /dev/null @@ -1,118 +0,0 @@ -package service - -import ( - "os/exec" - - ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper" - loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" - "github.com/IceWhaleTech/CasaOS/service/ddns" - "github.com/IceWhaleTech/CasaOS/service/model" - "gorm.io/gorm" -) - -type ddnsStruct struct { - db *gorm.DB - log loger2.OLog -} - -type DDNSService interface { - IsExis(t int, domain string, host string) bool - GetExternalIP() (string, string) - GetConfigList() *[]model.DDNSList - DeleteConfig(id uint) bool - GetType(name string) (uint, string) - SaveConfig(model model.DDNSUpdateDBModel) error -} - -//判断当前添加的是否存在 -func (d *ddnsStruct) IsExis(t int, domain string, host string) bool { - var count int64 - d.db.Table(model.DDNSLISTTABLENAME).Where("type=? AND domain=? AND host=?", t, domain, host).Count(&count) - - return count > 0 -} - -//前台获取已配置的ddns列表 -func (d *ddnsStruct) GetConfigList() *[]model.DDNSList { - var s []model.DDNSList - d.db.Table(model.DDNSLISTTABLENAME).Select("o_ddns_type.name as name,o_ddns.id,host,domain,created_at,updated_at,message,state").Joins("left join o_ddns_type on o_ddns.type=o_ddns_type.id").Scan(&s) - return &s -} - -func (d *ddnsStruct) DeleteConfig(id uint) bool { - d.db.Delete(&model.DDNSUpdateDBModel{Id: id}) - return true -} - -func (d *ddnsStruct) GetExternalIP() (string, string) { - ipv4 := make(chan string) - ipv6 := make(chan string) - go func() { ipv4 <- ip_helper2.GetExternalIPV4() }() - go func() { ipv6 <- ip_helper2.GetExternalIPV6() }() - - return <-ipv4, <-ipv6 -} - -func NewDDNSService(db *gorm.DB, log loger2.OLog) DDNSService { - return &ddnsStruct{db, log} -} - -//根据名称获取类型 -func (d *ddnsStruct) GetType(name string) (uint, string) { - var result model.DDNSTypeDBModel - d.db.Model(&model.DDNSTypeDBModel{}).Where("name = ?", name).First(&result) - return result.Id, result.Name -} - -//保存配置到数据库 -func (d *ddnsStruct) GetDockerRootDir(model model.DDNSUpdateDBModel) error { - return d.db.Create(&model).Error -} - -//保存配置到数据库 -func (d *ddnsStruct) SaveConfig(model model.DDNSUpdateDBModel) error { - return d.db.Create(&model).Error -} - -//更新数据库ping状态 -func chackPing(b chan bool, url string) { - cmd := exec.Command("ping", url, "-c", "1", "-W", "5") - err := cmd.Run() - if err != nil { - b <- false - } else { - b <- true - } -} - -//更新列表 -func UpdateDDNSList(db *gorm.DB) { - var s []model.DDNSCoreList - db.Table(model.DDNSLISTTABLENAME).Select("o_ddns_type.name as name,o_ddns_type.api_host as api_host,o_ddns.id,`host`,domain,user_name,`password`,`key`,secret,type").Joins("left join o_ddns_type on o_ddns.type=o_ddns_type.id").Scan(&s) - for _, item := range s { - var msg string - switch item.Type { - case 1: - var godaddy = &ddns.GoDaddy{ - Host: item.Host, - Key: item.Key, - Secret: item.Secret, - Domain: item.Domain, - IPV4: ip_helper2.GetExternalIPV4(), - IPV6: ip_helper2.GetExternalIPV6(), - ApiHost: item.ApiHost, - } - msg = godaddy.Update() - } - - b := make(chan bool) - - //获取ping状态 - go chackPing(b, item.Host+"."+item.Domain) - - item.State = <-b - item.Message = msg - db.Table(model.DDNSLISTTABLENAME).Model(&item).Select("state", "message").Updates(&item) - - } -} diff --git a/service/ddns/common.go b/service/ddns/common.go deleted file mode 100644 index 2ace08c..0000000 --- a/service/ddns/common.go +++ /dev/null @@ -1,33 +0,0 @@ -package ddns - -import ( - "net/http" -) - -func SetUserAgent(request *http.Request) { - request.Header.Set("User-Agent", "Oasis lauren.pan@icewhale.org") -} - -func SetContentType(request *http.Request, contentType string) { - request.Header.Set("Content-Type", contentType) -} - -func SetAccept(request *http.Request, acceptContent string) { - request.Header.Set("Accept", acceptContent) -} - -func SetAuthBearer(request *http.Request, token string) { - request.Header.Set("Authorization", "Bearer "+token) -} - -func SetAuthSSOKey(request *http.Request, key, secret string) { - request.Header.Set("Authorization", "sso-key "+key+":"+secret) -} - -func SetOauth(request *http.Request, value string) { - request.Header.Set("oauth", value) -} - -func SetXFilter(request *http.Request, value string) { - request.Header.Set("X-Filter", value) -} diff --git a/service/ddns/goddy.go b/service/ddns/goddy.go deleted file mode 100644 index 411d9ea..0000000 --- a/service/ddns/goddy.go +++ /dev/null @@ -1,87 +0,0 @@ -package ddns - -import ( - "bytes" - "context" - "fmt" - "github.com/IceWhaleTech/CasaOS/pkg/ddns" - "github.com/tidwall/gjson" - "io/ioutil" - "net/http" - "time" -) - -type GoDaddyService interface { - Update(ctx context.Context, client *http.Client) -} -type GoDaddy struct { - Host string `json:"host"` - Key string `json:"key"` - Secret string `json:"secret"` - Domain string `json:"domain"` - IPV4 string `json:"ipv_4"` - IPV6 string `json:"ipv_6"` - ApiHost string `json:"api_host"` -} - -func (g *GoDaddy) Update() string { - client := &http.Client{Timeout: 30 * time.Second} - recordType := ddns.A - buffer1 := bytes.NewBuffer(nil) - buffer1.WriteString(`[{"data":"`) - buffer1.WriteString(g.IPV4) - buffer1.WriteString(`"}]`) - request, err := http.NewRequest(http.MethodPut, fmt.Sprintf("%s/v1/domains/%s/records/%s/%s", g.ApiHost, g.Domain, recordType, g.Host), buffer1) - if err != nil { - return err.Error() - } - g.setHead(request) - response, err := client.Do(request) - if err != nil { - return err.Error() - } - defer response.Body.Close() - b, err := ioutil.ReadAll(response.Body) - if err != nil { - return err.Error() - } - defer response.Body.Close() - if len(b) > 0 { - r := gjson.GetBytes(b, "message") - return r.String() - } - if len(g.IPV6) > 0 { - recordType = ddns.AAAA - buffer1 := bytes.NewBuffer(nil) - buffer1.WriteString(`[{"data":"`) - buffer1.WriteString(g.IPV6) - buffer1.WriteString(`"}]`) - request6, err := http.NewRequest(http.MethodPut, fmt.Sprintf("%s/v1/domains/%s/records/%s/%s", ddns.GODADDYAPIURL, g.Domain, recordType, g.Host), buffer1) - if err != nil { - return err.Error() - } - g.setHead(request6) - response6, err := client.Do(request6) - if err != nil { - return err.Error() - } - defer response6.Body.Close() - - d, err := ioutil.ReadAll(response6.Body) - if err != nil { - return err.Error() - } - if len(d) > 0 { - r := gjson.GetBytes(d, "message") - return r.String() - } - } - return "" -} - -func (g *GoDaddy) setHead(request *http.Request) { - SetUserAgent(request) - SetAuthSSOKey(request, g.Key, g.Secret) - SetContentType(request, "application/json") - SetAccept(request, "application/json") -} diff --git a/service/ddns/goddy_test.go b/service/ddns/goddy_test.go deleted file mode 100644 index 7738af6..0000000 --- a/service/ddns/goddy_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package ddns - -import ( - "testing" -) - -func TestSetConfig(t *testing.T) { - var model GoDaddy - model.IPV4 = "180.164.179.198" - model.Domain = "link-liang.xyz" - model.Secret = "secret" - model.Key = "key" - //model.Type=ddns.GOGADDY - //model.SetConfig() -} diff --git a/service/disk.go b/service/disk.go index 943dace..fcb3ac9 100644 --- a/service/disk.go +++ b/service/disk.go @@ -163,7 +163,7 @@ func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel { } c = append(c, child) } - i.Format = strings.TrimSpace(command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskType " + i.Path)) + //i.Format = strings.TrimSpace(command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDiskType " + i.Path)) if health { i.Health = "OK" } diff --git a/service/docker.go b/service/docker.go index 593794c..88dc966 100644 --- a/service/docker.go +++ b/service/docker.go @@ -540,7 +540,6 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi config.Labels["show_env"] = strings.Join(showENV, ",") config.Labels["protocol"] = m.Protocol config.Labels["host"] = m.Host - //config.Labels["order"] = strconv.Itoa(MyService.App().GetCasaOSCount() + 1) hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(m.NetworkModel), Privileged: m.Privileged, CapAdd: m.CapAdd} //if net != "host" { config.ExposedPorts = ports diff --git a/service/model/o_application.go b/service/model/o_application.go deleted file mode 100644 index e3522fb..0000000 --- a/service/model/o_application.go +++ /dev/null @@ -1,20 +0,0 @@ -package model - -import ( - "time" -) - -type ApplicationModel struct { - Id int `gorm:"column:id;primary_key" json:"id"` - Name string `json:"name"` - Icon string `json:"icon"` - State int `json:"state"` - Type string `json:"type"` - Order int `json:"order"` - CreatedAt time.Time `gorm:"<-:create" json:"created_at"` - UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"` -} - -func (p *ApplicationModel) TableName() string { - return "o_application" -} diff --git a/service/model/o_ddns.go b/service/model/o_ddns.go deleted file mode 100644 index d669a90..0000000 --- a/service/model/o_ddns.go +++ /dev/null @@ -1,56 +0,0 @@ -package model - -import "time" - -func (p *DDNSUpdateDBModel) TableName() string { - return "o_ddns" -} - -type DDNSUpdateDBModel struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - Ipv4 string `gorm:"-"` - Ipv6 string `gorm:"-"` - Type uint `json:"type" form:"type"` - Domain string `json:"domain" form:"domain"` - Host string `json:"host" form:"host"` - Key string `json:"key" form:"key"` - Secret string `json:"secret" form:"secret"` - UserName string `json:"user_name" form:"user_name"` - Password string `json:"password" form:"password"` - CreatedAt time.Time `gorm:"<-:create" json:"created_at"` - UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"` -} - -const DDNSLISTTABLENAME = "o_ddns" - -//返回给前台使用 -type DDNSList struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - Name string `json:"name"` - Domain string `json:"domain" form:"domain"` - Host string `json:"host" form:"host"` - IPV4 string `json:"ipv_4" gorm:"-"` - IPV6 string `json:"ipv_6" gorm:"-"` - Message string `json:"message"` - State bool `json:"state"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` -} - -//定时任务使用 -type DDNSCoreList struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - Domain string `json:"domain" form:"domain"` - Name string `json:"name" form:"name"` - Type uint `json:"type"` - Key string `json:"key"` - Message string `json:"message"` - State bool `json:"state"` - Secret string `json:"secret" form:"secret"` - UserName string `json:"user_name" form:"user_name"` - Password string `json:"password" form:"password"` - ApiHost string `json:"api_host"` - Host string `json:"host"` - IPV4 string `json:"ipv_4" gorm:"-"` - IPV6 string `json:"ipv_6" gorm:"-"` -} diff --git a/service/model/o_ddns_type.go b/service/model/o_ddns_type.go deleted file mode 100644 index e236a86..0000000 --- a/service/model/o_ddns_type.go +++ /dev/null @@ -1,11 +0,0 @@ -package model - -type DDNSTypeDBModel struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - Name string `json:"name"` - ApiHost string `json:"api_host"` -} - -func (p *DDNSTypeDBModel) TableName() string { - return "o_ddns_type" -} diff --git a/service/model/o_share_directory.go b/service/model/o_share_directory.go deleted file mode 100644 index ea1dac2..0000000 --- a/service/model/o_share_directory.go +++ /dev/null @@ -1,20 +0,0 @@ -package model - -import "time" - -type ShareDirDBModel struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - Name string `gorm:"size:50" json:"name"` - Comment string `gorm:"size:200" json:"comment"` - Path string `json:"path"` - ReadOnly bool `json:"read_only"` - Writeable bool `json:"writeable"` - Browseable bool `json:"browseable"` - ValidUsers string `gorm:"size:200" json:"valid_users"` //可以访问的用户 多用户用 , 分割 - CreatedAt time.Time `gorm:"<-:create" json:"created_at"` - UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"` -} - -func (p *ShareDirDBModel) TableName() string { - return "o_share_directory" -} diff --git a/service/model/o_task.go b/service/model/o_task.go deleted file mode 100644 index 9c42bab..0000000 --- a/service/model/o_task.go +++ /dev/null @@ -1,17 +0,0 @@ -package model - -type TaskDBModel struct { - Id uint `gorm:"column:id;primary_key" json:"id"` - Title string `gorm:"size:200" json:"title"` - ImageUrl string `json:"image_url"` - Content string `gorm:"size:255" json:"content"` - Url string `json:"url"` - State int `json:"state"` // 0:未阅读,1:已阅读 - Type int `json:"type"` - CreatedAt string `gorm:"<-:create;autoCreateTime" json:"created_at"` - UpdatedAt string `gorm:"<-:create;<-:update;autoUpdateTime" json:"updated_at"` -} - -func (p *TaskDBModel) TableName() string { - return "o_task" -} diff --git a/service/model/o_user.go b/service/model/o_user.go index d1aa61d..d66895d 100644 --- a/service/model/o_user.go +++ b/service/model/o_user.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-15 16:53:00 + * @LastEditTime: 2022-06-23 15:43:07 * @FilePath: /CasaOS/service/model/o_user.go * @Description: * @Website: https://www.casaos.io @@ -10,18 +10,22 @@ */ package model +import "time" + //Soon to be removed type UserDBModel struct { - Id int `gorm:"column:id;primary_key" json:"id"` - UserName string `json:"user_name"` - Password string `json:"password omitempty"` - Role string `json:"role"` - Email string `json:"email"` - Avatar string `json:"avatar"` - NickName string `json:"nick_name"` - Description string `json:"description"` + Id int `gorm:"column:id;primary_key" json:"id"` + UserName string `json:"user_name"` + Password string `json:"password,omitempty"` + Role string `json:"role"` + Email string `json:"email"` + NickName string `json:"nick_name"` + Avatar string `json:"avatar"` + Description string `json:"description"` + CreatedAt time.Time `gorm:"<-:create;autoCreateTime" json:"created_at,omitempty"` + UpdatedAt time.Time `gorm:"<-:create;<-:update;autoUpdateTime" json:"updated_at,omitempty"` } -func (p *UserDBModel) UserDBModel() string { +func (p *UserDBModel) TableName() string { return "o_user" } diff --git a/service/notify.go b/service/notify.go index 6159f14..b68532a 100644 --- a/service/notify.go +++ b/service/notify.go @@ -12,7 +12,6 @@ import ( "github.com/ambelovsky/gosf" socketio "github.com/googollee/go-socket.io" "github.com/gorilla/websocket" - "github.com/shirou/gopsutil/v3/mem" "gorm.io/gorm" ) @@ -31,7 +30,7 @@ type NotifyServer interface { SendUninstallAppBySocket(app notify.Application) SendNetInfoBySocket(netList []model2.IOCountersStat) SendCPUInfoBySocket(cpu map[string]interface{}) - SendMemInfoBySocket(mem *mem.VirtualMemoryStat) + SendMemInfoBySocket(mem map[string]interface{}) SendUSBInfoBySocket(list []model2.DriveUSB) SendDiskInfoBySocket(disk model2.Summary) SendPersonStatusBySocket(status notify.Person) @@ -273,7 +272,7 @@ func (i *notifyServer) SendUSBInfoBySocket(list []model2.DriveUSB) { NotifyMsg <- notify } -func (i *notifyServer) SendMemInfoBySocket(mem *mem.VirtualMemoryStat) { +func (i *notifyServer) SendMemInfoBySocket(mem map[string]interface{}) { body := make(map[string]interface{}) body["data"] = mem diff --git a/service/person.go b/service/person.go index 011a2c7..a4aa9e6 100644 --- a/service/person.go +++ b/service/person.go @@ -198,11 +198,11 @@ func ProcessingContent(stream quic.Stream) { if m.Data.(string) == "" || m.Data.(string) == "/" { for _, v := range config.FileSettingInfo.ShareDir { //tempList := MyService.ZiMa().GetDirPath(v) - temp := MyService.ZiMa().GetDirPathOne(v) + temp := MyService.System().GetDirPathOne(v) list = append(list, temp) } } else { - list = MyService.ZiMa().GetDirPath(m.Data.(string)) + list = MyService.System().GetDirPath(m.Data.(string)) } } else { list = []model.Path{} diff --git a/service/search.go b/service/search.go deleted file mode 100644 index d4e2332..0000000 --- a/service/search.go +++ /dev/null @@ -1,57 +0,0 @@ -package service - -import ( - "fmt" - "io/ioutil" - "path" - "strings" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/types" -) - -type SearchService interface { - SearchList(key string) ([]model.SearchFileInfo, error) -} - -type searchService struct { -} - -func (s *searchService) SearchList(key string) ([]model.SearchFileInfo, error) { - pathName := "/Users/liangjianli/go/CasaOSNew/searchTest" - resArr := []model.SearchFileInfo{} - files, _ := ioutil.ReadDir(pathName) - for _, file := range files { - if file.IsDir() { - tempArr, err := s.SearchList(pathName + "/" + file.Name()) - if err != nil { - resArr = append(resArr, tempArr...) - } - } else { - if strings.Contains(file.Name(), key) { - resArr = append(resArr, model.SearchFileInfo{Path: pathName, Name: file.Name(), Type: GetSearchType(path.Ext(file.Name()))}) - } - fmt.Println(pathName + "/" + file.Name()) - } - } - return resArr, nil -} - -func GetSearchType(ext string) int { - var reType int = types.UNKNOWN - switch ext { - case ".png": - reType = types.PICTURE - case ".mp4": - reType = types.MEDIA - case ".mp3": - reType = types.MUSIC - default: - reType = types.UNKNOWN - } - return reType -} - -func NewSearchService() SearchService { - return &searchService{} -} diff --git a/service/service.go b/service/service.go index 0e75470..1087d94 100644 --- a/service/service.go +++ b/service/service.go @@ -16,20 +16,14 @@ var SocketRun bool type Repository interface { App() AppService - DDNS() DDNSService User() UserService Docker() DockerService - //Redis() RedisService - ZiMa() ZiMaService Casa() CasaService Disk() DiskService Notify() NotifyServer - ShareDirectory() ShareDirService - Task() TaskService Rely() RelyService System() SystemService Shortcuts() ShortcutsService - Search() SearchService Person() PersonService Friend() FriendService Download() DownloadService @@ -39,47 +33,37 @@ type Repository interface { func NewService(db *gorm.DB) Repository { return &store{ - app: NewAppService(db), - user: NewUserService(db), - docker: NewDockerService(), - //redis: NewRedisService(rp), - zima: NewZiMaService(), - casa: NewCasaService(), - disk: NewDiskService(db), - notify: NewNotifyService(db), - shareDirectory: NewShareDirService(db), - task: NewTaskService(db), - rely: NewRelyService(db), - system: NewSystemService(), - shortcuts: NewShortcutsService(db), - search: NewSearchService(), - 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), + person: NewPersonService(db), + friend: NewFriendService(db), + download: NewDownloadService(db), + downrecord: NewDownRecordService(db), } } type store struct { - db *gorm.DB - app AppService - ddns DDNSService - user UserService - docker DockerService - zima ZiMaService - casa CasaService - disk DiskService - notify NotifyServer - shareDirectory ShareDirService - task TaskService - rely RelyService - system SystemService - shortcuts ShortcutsService - search SearchService - 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 + person PersonService + friend FriendService + download DownloadService + downrecord DownRecordService } func (c *store) DownRecord() DownRecordService { @@ -113,10 +97,6 @@ func (c *store) App() AppService { return c.app } -func (c *store) DDNS() DDNSService { - return c.ddns -} - func (c *store) User() UserService { return c.user } @@ -125,9 +105,6 @@ func (c *store) Docker() DockerService { return c.docker } -func (c *store) ZiMa() ZiMaService { - return c.zima -} func (c *store) Casa() CasaService { return c.casa } @@ -135,12 +112,3 @@ func (c *store) Casa() CasaService { func (c *store) Disk() DiskService { return c.disk } -func (c *store) ShareDirectory() ShareDirService { - return c.shareDirectory -} -func (c *store) Task() TaskService { - return c.task -} -func (c *store) Search() SearchService { - return c.search -} diff --git a/service/share_directory.go b/service/share_directory.go deleted file mode 100644 index a65586d..0000000 --- a/service/share_directory.go +++ /dev/null @@ -1,324 +0,0 @@ -package service - -import ( - "os" - "strconv" - - "github.com/IceWhaleTech/CasaOS/pkg/config" - "github.com/IceWhaleTech/CasaOS/pkg/utils/command" - "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" - "github.com/IceWhaleTech/CasaOS/service/model" - "go.uber.org/zap" - "gorm.io/gorm" -) - -type ShareDirService interface { - UpConfig() - List(desc bool) []model.ShareDirDBModel - Delete(id string) - Add(m *model.ShareDirDBModel) - Update(m *model.ShareDirDBModel) - Info(id string) model.ShareDirDBModel -} - -type shareDirService struct { - db *gorm.DB -} - -func (s *shareDirService) List(desc bool) []model.ShareDirDBModel { - var list []model.ShareDirDBModel - var orderBy string - if desc { - orderBy = "id" - } else { - orderBy = "id DESC" - } - s.db.Order(orderBy).Find(&list) - return list -} - -func (s *shareDirService) Delete(id string) { - var m model.ShareDirDBModel - s.db.Where("id = ?", id).Delete(&m) -} - -func (s *shareDirService) Add(m *model.ShareDirDBModel) { - s.db.Save(m) -} -func (s *shareDirService) Update(m *model.ShareDirDBModel) { - s.db.Save(m) -} -func (s *shareDirService) UpConfig() { - var list []model.ShareDirDBModel - - s.db.Find(&list) - - str := `# -# Sample configuration file for the Samba suite for Debian GNU/Linux. -# -# -# This is the main Samba configuration file. You should read the -# smb.conf(5) manual page in order to understand the options listed -# here. Samba has a huge number of configurable options most of which -# are not shown in this example -# -# Some options that are often worth tuning have been included as -# commented-out examples in this file. -# - When such options are commented with ";", the proposed setting -# differs from the default Samba behaviour -# - When commented with "#", the proposed setting is the default -# behaviour of Samba but the option is considered important -# enough to be mentioned here -# -# NOTE: Whenever you modify this file you should run the command -# "testparm" to check that you have not made any basic syntactic -# errors. - -#======================= Global Settings ======================= - -[global] - -## Browsing/Identification ### - -# Change this to the workgroup/NT-domain name your Samba server will part of - workgroup = WORKGROUP - -#### Networking #### - -# The specific set of interfaces / networks to bind to -# This can be either the interface name or an IP address/netmask; -# interface names are normally preferred -; interfaces = 127.0.0.0/8 eth0 - -# Only bind to the named interfaces and/or networks; you must use the -# 'interfaces' option above to use this. -# It is recommended that you enable this feature if your Samba machine is -# not protected by a firewall or is a firewall itself. However, this -# option cannot handle dynamic or non-broadcast interfaces correctly. -; bind interfaces only = yes - - - -#### Debugging/Accounting #### - -# This tells Samba to use a separate log file for each machine -# that connects - log file = /var/log/samba/log.%m - -# Cap the size of the individual log files (in KiB). - max log size = 1000 - -# We want Samba to only log to /var/log/samba/log.{smbd,nmbd}. -# Append syslog@1 if you want important messages to be sent to syslog too. - logging = file - -# Do something sensible when Samba crashes: mail the admin a backtrace - panic action = /usr/share/samba/panic-action %d - - -####### Authentication ####### - -# Server role. Defines in which mode Samba will operate. Possible -# values are "standalone server", "member server", "classic primary -# domain controller", "classic backup domain controller", "active -# directory domain controller". -# -# Most people will want "standalone server" or "member server". -# Running as "active directory domain controller" will require first -# running "samba-tool domain provision" to wipe databases and create a -# new domain. - server role = standalone server - - obey pam restrictions = yes - -# This boolean parameter controls whether Samba attempts to sync the Unix -# password with the SMB password when the encrypted SMB password in the -# passdb is changed. - unix password sync = yes - -# For Unix password sync to work on a Debian GNU/Linux system, the following -# parameters must be set (thanks to Ian Kahan < for -# sending the correct chat script for the passwd program in Debian Sarge). - passwd program = /usr/bin/passwd %u - passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* . - -# This boolean controls whether PAM will be used for password changes -# when requested by an SMB client instead of the program listed in -# 'passwd program'. The default is 'no'. - pam password change = yes - -# This option controls how unsuccessful authentication attempts are mapped -# to anonymous connections - map to guest = bad user - -########## Domains ########### - -# -# The following settings only takes effect if 'server role = primary -# classic domain controller', 'server role = backup domain controller' -# or 'domain logons' is set -# - -# It specifies the location of the user's -# profile directory from the client point of view) The following -# required a [profiles] share to be setup on the samba server (see -# below) -; logon path = \\%N\profiles\%U -# Another common choice is storing the profile in the user's home directory -# (this is Samba's default) -# logon path = \\%N\%U\profile - -# The following setting only takes effect if 'domain logons' is set -# It specifies the location of a user's home directory (from the client -# point of view) -; logon drive = H: -# logon home = \\%N\%U - -# The following setting only takes effect if 'domain logons' is set -# It specifies the script to run during logon. The script must be stored -# in the [netlogon] share -# NOTE: Must be store in 'DOS' file format convention -; logon script = logon.cmd - -# This allows Unix users to be created on the domain controller via the SAMR -# RPC pipe. The example command creates a user account with a disabled Unix -# password; please adapt to your needs -; add user script = /usr/sbin/adduser --quiet --disabled-password --gecos "" %u - -# This allows machine accounts to be created on the domain controller via the -# SAMR RPC pipe. -# The following assumes a "machines" group exists on the system -; add machine script = /usr/sbin/useradd -g machines -c "%u machine account" -d /var/lib/samba -s /bin/false %u - -# This allows Unix groups to be created on the domain controller via the SAMR -# RPC pipe. -; add group script = /usr/sbin/addgroup --force-badname %g - -############ Misc ############ - -# Using the following line enables you to customise your configuration -# on a per machine basis. The %m gets replaced with the netbios name -# of the machine that is connecting -; include = /home/samba/etc/smb.conf.%m - -# Some defaults for winbind (make sure you're not using the ranges -# for something else.) -; idmap config * : backend = tdb -; idmap config * : range = 3000-7999 -; idmap config YOURDOMAINHERE : backend = tdb -; idmap config YOURDOMAINHERE : range = 100000-999999 -; template shell = /bin/bash - -# Setup usershare options to enable non-root users to share folders -# with the net usershare command. - -# Maximum number of usershare. 0 means that usershare is disabled. -# usershare max shares = 100 - -# Allow users who've been granted usershare privileges to create -# public shares, not just authenticated ones - usershare allow guests = yes - -#======================= Share Definitions ======================= - -[homes] - comment = Home Directories - browseable = no - -# By default, the home directories are exported read-only. Change the -# next parameter to 'no' if you want to be able to write to them. - read only = yes - -# File creation mask is set to 0700 for security reasons. If you want to -# create files with group=rw permissions, set next parameter to 0775. - create mask = 0700 - -# Directory creation mask is set to 0700 for security reasons. If you want to -# create dirs. with group=rw permissions, set next parameter to 0775. - directory mask = 0700 - -# By default, \\server\username shares can be connected to by anyone -# with access to the samba server. -# The following parameter makes sure that only "username" can connect -# to \\server\username -# This might need tweaking when using external authentication schemes - valid users = %S - -# Un-comment the following and create the netlogon directory for Domain Logons -# (you need to configure Samba to act as a domain controller too.) -;[netlogon] -; comment = Network Logon Service -; path = /home/samba/netlogon -; guest ok = yes -; read only = yes - -# Un-comment the following and create the profiles directory to store -# users profiles (see the "logon path" option above) -# (you need to configure Samba to act as a domain controller too.) -# The path below should be writable by all users so that their -# profile directory may be created the first time they log on -;[profiles] -; comment = Users profiles -; path = /home/samba/profiles -; guest ok = no -; browseable = no -; create mask = 0600 -; directory mask = 0700 - -[printers] - comment = All Printers - browseable = no - path = /var/spool/samba - printable = yes - guest ok = no - read only = yes - create mask = 0700 - -# Windows clients look for this share name as a source of downloadable -# printer drivers -[print$] - comment = Printer Drivers - path = /var/lib/samba/printers - browseable = yes - read only = yes - guest ok = no -# Uncomment to allow remote administration of Windows print drivers. -# You may need to replace 'lpadmin' with the name of the group your -# admin users are members of. -# Please note that you also need to set appropriate Unix permissions -# to the drivers directory for these users to have write rights in it -; write list = root, @lpadmin` - - for _, i := range list { - str += "\n[" + i.Name + "]" - str += "\n comment = " + i.Comment - str += "\n path = " + i.Path - str += "\n browseable = " + strconv.FormatBool(i.Browseable) - str += "\n read only = " + strconv.FormatBool(i.ReadOnly) - str += "\n writeable = " + strconv.FormatBool(i.Writeable) - if len(i.ValidUsers) == 0 { - str += "\n guest ok = yes" - } else { - str += "\n valid users = " + i.ValidUsers - } - } - - // /etc/samba/smb.conf - f, err := os.OpenFile("/etc/samba/smb.conf", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) - if err != nil { - loger.Error("Failed to create file", zap.Any("err", err)) - } else { - defer f.Close() - f.WriteString(str) - command.OnlyExec("source " + config.AppInfo.ShellPath + "/helper.sh ;ReloadSamba") - } -} -func (s *shareDirService) Info(id string) model.ShareDirDBModel { - var m model.ShareDirDBModel - s.db.Where("id = ?", id).First(&m) - return m -} - -func NewShareDirService(db *gorm.DB) ShareDirService { - return &shareDirService{db: db} -} diff --git a/service/system.go b/service/system.go index f5dce1f..ec58bbf 100644 --- a/service/system.go +++ b/service/system.go @@ -5,13 +5,20 @@ import ( "io/ioutil" net2 "net" "os" + "path/filepath" + "runtime" "strconv" + "strings" + "time" + "github.com/IceWhaleTech/CasaOS/model" "github.com/IceWhaleTech/CasaOS/pkg/config" command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" + "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/IceWhaleTech/CasaOS/pkg/utils/loger" "github.com/shirou/gopsutil/v3/cpu" + "github.com/shirou/gopsutil/v3/disk" + "github.com/shirou/gopsutil/v3/host" "github.com/shirou/gopsutil/v3/mem" "github.com/shirou/gopsutil/v3/net" ) @@ -32,16 +39,149 @@ type SystemService interface { GetNetInfo() []net.IOCountersStat GetCpuCoreNum() int GetCpuPercent() float64 - GetMemInfo() *mem.VirtualMemoryStat + GetMemInfo() map[string]interface{} + GetCpuInfo() []cpu.InfoStat + GetDirPath(path string) []model.Path + GetDirPathOne(path string) (m model.Path) + GetNetState(name string) string + GetDiskInfo() *disk.UsageStat + GetSysInfo() host.InfoStat + GetDeviceTree() string + CreateFile(path string) (int, error) + RenameFile(oldF, newF string) (int, error) + MkdirAll(path string) (int, error) } type systemService struct { - log loger.OLog } -func (c *systemService) GetMemInfo() *mem.VirtualMemoryStat { +func (c *systemService) MkdirAll(path string) (int, error) { + _, err := os.Stat(path) + if err == nil { + return common_err.DIR_ALREADY_EXISTS, nil + } else { + if os.IsNotExist(err) { + os.MkdirAll(path, os.ModePerm) + return common_err.SUCCESS, nil + } else if strings.Contains(err.Error(), ": not a directory") { + return common_err.FILE_OR_DIR_EXISTS, err + } + } + return common_err.ERROR, err +} +func (c *systemService) RenameFile(oldF, newF string) (int, error) { + + _, err := os.Stat(newF) + if err == nil { + return common_err.DIR_ALREADY_EXISTS, nil + } else { + if os.IsNotExist(err) { + err := os.Rename(oldF, newF) + if err != nil { + return common_err.ERROR, err + } + return common_err.SUCCESS, nil + } + } + return common_err.ERROR, err +} +func (c *systemService) CreateFile(path string) (int, error) { + _, err := os.Stat(path) + if err == nil { + return common_err.FILE_OR_DIR_EXISTS, nil + } else { + if os.IsNotExist(err) { + file.CreateFile(path) + return common_err.SUCCESS, nil + } + } + return common_err.ERROR, err +} +func (c *systemService) GetDeviceTree() string { + return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDeviceTree") +} +func (c *systemService) GetSysInfo() host.InfoStat { + info, _ := host.Info() + return *info +} + +func (c *systemService) GetDiskInfo() *disk.UsageStat { + path := "/" + if runtime.GOOS == "windows" { + path = "C:" + } + diskInfo, _ := disk.Usage(path) + diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64) + diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64) + return diskInfo +} + +func (c *systemService) GetNetState(name string) string { + return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;CatNetCardState " + name) +} + +func (c *systemService) GetDirPathOne(path string) (m model.Path) { + + f, err := os.Stat(path) + + if err != nil { + return + } + m.IsDir = f.IsDir() + m.Name = f.Name() + m.Path = path + m.Size = f.Size() + m.Date = f.ModTime() + return +} + +func (c *systemService) GetDirPath(path string) []model.Path { + if path == "/DATA" { + sysType := runtime.GOOS + if sysType == "windows" { + path = "C:\\CasaOS\\DATA" + } + if sysType == "darwin" { + path = "./CasaOS/DATA" + } + + } + + ls, _ := ioutil.ReadDir(path) + dirs := []model.Path{} + if len(path) > 0 { + for _, l := range ls { + filePath := filepath.Join(path, l.Name()) + link, err := filepath.EvalSymlinks(filePath) + if err != nil { + link = filePath + } + temp := model.Path{Name: l.Name(), Path: filePath, IsDir: l.IsDir(), Date: l.ModTime(), Size: l.Size()} + if filePath != link { + file, _ := os.Stat(link) + temp.IsDir = file.IsDir() + } + dirs = append(dirs, temp) + } + } else { + dirs = append(dirs, model.Path{Name: "DATA", Path: "/DATA/", IsDir: true, Date: time.Now()}) + } + return dirs +} +func (c *systemService) GetCpuInfo() []cpu.InfoStat { + info, _ := cpu.Info() + return info +} + +func (c *systemService) GetMemInfo() map[string]interface{} { memInfo, _ := mem.VirtualMemory() memInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", memInfo.UsedPercent), 64) - return memInfo + memData := make(map[string]interface{}) + memData["total"] = memInfo.Total + memData["available"] = memInfo.Available + memData["used"] = memInfo.Used + memData["free"] = memInfo.Free + memData["usedPercent"] = memInfo.UsedPercent + return memData } func (c *systemService) GetCpuPercent() float64 { @@ -70,11 +210,11 @@ func (c *systemService) GetNet(physics bool) []string { func (s *systemService) UpdateSystemVersion(version string) { //command2.OnlyExec(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version) //s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version) - s.log.Error(command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/tools.sh ;update " + version)) + command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/tools.sh ;update " + version) //s.log.Error(command2.ExecResultStr(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)) } func (s *systemService) UpdateAssist() { - s.log.Error(command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/assist.sh")) + command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/assist.sh") } func (s *systemService) GetTimeZone() string { @@ -123,7 +263,10 @@ func (s *systemService) UpSystemPort(port string) { config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath) } func (s *systemService) GetCasaOSLogs(lineNumber int) string { - file, err := os.Open(s.log.Path()) + file, err := os.Open(filepath.Join(config.AppInfo.LogPath, fmt.Sprintf("%s.%s", + config.AppInfo.LogSaveName, + config.AppInfo.LogFileExt, + ))) if err != nil { return err.Error() } diff --git a/service/task.go b/service/task.go deleted file mode 100644 index a0634f1..0000000 --- a/service/task.go +++ /dev/null @@ -1,144 +0,0 @@ -package service - -import ( - json2 "encoding/json" - "strconv" - - "github.com/IceWhaleTech/CasaOS/pkg/config" - httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper" - "github.com/IceWhaleTech/CasaOS/service/model" - "github.com/IceWhaleTech/CasaOS/types" - "github.com/tidwall/gjson" - "gorm.io/gorm" -) - -type TaskService interface { - List(desc bool) []model.TaskDBModel - Delete(id string) - Add(m *model.TaskDBModel) - Update(m *model.TaskDBModel) - Info(id string) model.TaskDBModel - SyncTaskService() - GetServerTasks() []model.TaskDBModel -} - -type taskService struct { - db *gorm.DB -} - -func (s *taskService) List(desc bool) []model.TaskDBModel { - var list []model.TaskDBModel - var orderBy string - if !desc { - orderBy = "id" - } else { - orderBy = "id DESC" - } - s.db.Order(orderBy).Where("state=?", types.TASK_STATE_UNCOMPLETE).Find(&list) - return list -} - -func (s *taskService) Delete(id string) { - var m model.TaskDBModel - s.db.Where("id = ?", id).Delete(&m) -} - -func (s *taskService) Add(m *model.TaskDBModel) { - s.db.Save(m) -} -func (s *taskService) Update(m *model.TaskDBModel) { - s.db.Model(&m).Update("state", m.State) -} -func (s *taskService) taskDirService(id string) model.TaskDBModel { - var m model.TaskDBModel - s.db.Where("id = ?", id).First(&m) - return m -} - -func (s *taskService) Info(id string) model.TaskDBModel { - var m model.TaskDBModel - s.db.Where("id = ?", id).Delete(&m) - return m -} -func (s *taskService) GetServerTasks() []model.TaskDBModel { - var count int64 - s.db.Model(&model.TaskDBModel{}).Count(&count) - head := make(map[string]string) - - t := make(chan string) - - go func() { - str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil) - - t <- gjson.Get(str, "data").String() - }() - head["Authorization"] = <-t - - listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/task/list/0?desc=true", head) - - list := []model.TaskDBModel{} - json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list) - - //go func(list []model.TaskDBModel) { - // for _, dbModel := range list { - // dbModel.Id = 0 - // s.db.Create(&dbModel) - // } - //}(list) - return list -} -func (s *taskService) SyncTaskService() { - var count int64 - s.db.Model(&model.TaskDBModel{}).Count(&count) - head := make(map[string]string) - - t := make(chan string) - - go func() { - str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil) - - t <- gjson.Get(str, "data").String() - }() - head["Authorization"] = <-t - - listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/task/list/"+strconv.Itoa(int(count)), head) - - list := []model.TaskDBModel{} - json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list) - - go func(list []model.TaskDBModel) { - for _, dbModel := range list { - dbModel.Id = 0 - s.db.Create(&dbModel) - } - }(list) -} -func SyncTask(db *gorm.DB) { - var count int64 - db.Model(&model.TaskDBModel{}).Count(&count) - head := make(map[string]string) - - t := make(chan string) - - go func() { - str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil) - - t <- gjson.Get(str, "data").String() - }() - head["Authorization"] = <-t - - listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/task/list/"+strconv.Itoa(int(count)), head) - - list := []model.TaskDBModel{} - json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list) - - go func(list []model.TaskDBModel) { - for _, dbModel := range list { - dbModel.Id = 0 - db.Create(&dbModel) - } - }(list) -} -func NewTaskService(db *gorm.DB) TaskService { - return &taskService{db: db} -} diff --git a/service/user.go b/service/user.go index 46ec860..e9f5930 100644 --- a/service/user.go +++ b/service/user.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-03-18 11:40:55 * @LastEditors: LinkLeong - * @LastEditTime: 2022-06-16 19:08:09 + * @LastEditTime: 2022-06-23 19:45:49 * @FilePath: /CasaOS/service/user.go * @Description: * @Website: https://www.casaos.io @@ -26,7 +26,11 @@ type UserService interface { CreateUser(m model.UserDBModel) model.UserDBModel GetUserCount() (userCount int64) UpdateUser(m model.UserDBModel) + UpdateUserPassword(m model.UserDBModel) GetUserInfoById(id string) (m model.UserDBModel) + GetUserAllInfoById(id string) (m model.UserDBModel) + GetUserAllInfoByName(userName string) (m model.UserDBModel) + DeleteUserById(id string) GetUserInfoByUserName(userName string) (m model.UserDBModel) GetAllUserName() (list []model.UserDBModel) } @@ -37,6 +41,10 @@ type userService struct { db *gorm.DB } +func (u *userService) DeleteUserById(id string) { + u.db.Where("id= ?", id).Delete(&model.UserDBModel{}) +} + func (u *userService) GetAllUserName() (list []model.UserDBModel) { u.db.Select("user_name").Find(&list) return @@ -52,16 +60,26 @@ func (u *userService) GetUserCount() (userCount int64) { } func (u *userService) UpdateUser(m model.UserDBModel) { - u.db.Save(&m) + u.db.Model(&m).Omit("password").Updates(&m) } - -func (u *userService) GetUserInfoById(id string) (m model.UserDBModel) { +func (u *userService) UpdateUserPassword(m model.UserDBModel) { + u.db.Model(&m).Update("password", m.Password) +} +func (u *userService) GetUserAllInfoById(id string) (m model.UserDBModel) { u.db.Where("id= ?", id).First(&m) return } +func (u *userService) GetUserAllInfoByName(userName string) (m model.UserDBModel) { + u.db.Where("user_name= ?", userName).First(&m) + return +} +func (u *userService) GetUserInfoById(id string) (m model.UserDBModel) { + u.db.Select("user_name", "id", "role", "nick_name", "description", "avatar").Where("id= ?", id).First(&m) + return +} func (u *userService) GetUserInfoByUserName(userName string) (m model.UserDBModel) { - u.db.Where("user_name= ?", userName).First(&m) + u.db.Select("user_name", "id", "role", "nick_name", "description", "avatar").Where("user_name= ?", userName).First(&m) return } diff --git a/service/zima_info.go b/service/zima_info.go deleted file mode 100644 index aff24bf..0000000 --- a/service/zima_info.go +++ /dev/null @@ -1,215 +0,0 @@ -package service - -import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" - "time" - - "github.com/IceWhaleTech/CasaOS/model" - "github.com/IceWhaleTech/CasaOS/pkg/config" - command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" - "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" - "github.com/IceWhaleTech/CasaOS/pkg/utils/file" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/disk" - "github.com/shirou/gopsutil/v3/host" -) - -//系统信息 -type ZiMaService interface { - GetDiskInfo() *disk.UsageStat - - GetNetState(name string) string - GetSysInfo() host.InfoStat - GetDirPath(path string) []model.Path - GetDirPathOne(path string) (m model.Path) - MkdirAll(path string) (int, error) - CreateFile(path string) (int, error) - RenameFile(oldF, newF string) (int, error) - GetCpuInfo() []cpu.InfoStat - GetDeviceTree() string -} - -var NetArray [][]model.IOCountersStat - -type zima struct { -} - -//cpu详情 -func (c *zima) GetCpuInfo() []cpu.InfoStat { - info, _ := cpu.Info() - return info -} - -//获取硬盘详情 -func (c *zima) GetDiskInfo() *disk.UsageStat { - path := "/" - if runtime.GOOS == "windows" { - path = "C:" - } - diskInfo, _ := disk.Usage(path) - diskInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.UsedPercent), 64) - diskInfo.InodesUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", diskInfo.InodesUsedPercent), 64) - return diskInfo -} - -//获取硬盘目录 -func (c *zima) GetDirPath(path string) []model.Path { - if path == "/DATA" { - sysType := runtime.GOOS - if sysType == "windows" { - path = "C:\\CasaOS\\DATA" - } - if sysType == "darwin" { - path = "./CasaOS/DATA" - } - - } - - ls, _ := ioutil.ReadDir(path) - dirs := []model.Path{} - if len(path) > 0 { - for _, l := range ls { - filePath := filepath.Join(path, l.Name()) - link, err := filepath.EvalSymlinks(filePath) - if err != nil { - link = filePath - } - temp := model.Path{Name: l.Name(), Path: filePath, IsDir: l.IsDir(), Date: l.ModTime(), Size: l.Size()} - if filePath != link { - file, _ := os.Stat(link) - temp.IsDir = file.IsDir() - } - dirs = append(dirs, temp) - } - } else { - dirs = append(dirs, model.Path{Name: "DATA", Path: "/DATA/", IsDir: true, Date: time.Now()}) - } - return dirs -} - -func (c *zima) GetDirPathOne(path string) (m model.Path) { - - f, err := os.Stat(path) - - if err != nil { - return - } - m.IsDir = f.IsDir() - m.Name = f.Name() - m.Path = path - m.Size = f.Size() - m.Date = f.ModTime() - return -} - -//获取系统信息 -func (c *zima) GetSysInfo() host.InfoStat { - info, _ := host.Info() - return *info -} - -func (c *zima) GetDeviceTree() string { - return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;GetDeviceTree") -} - -//shell脚本参数 { 网卡名称 } -func (c *zima) GetNetState(name string) string { - return command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;CatNetCardState " + name) -} - -//mkdir -func (c *zima) MkdirAll(path string) (int, error) { - _, err := os.Stat(path) - if err == nil { - return common_err.DIR_ALREADY_EXISTS, nil - } else { - if os.IsNotExist(err) { - os.MkdirAll(path, os.ModePerm) - return common_err.SUCCESS, nil - } else if strings.Contains(err.Error(), ": not a directory") { - return common_err.FILE_OR_DIR_EXISTS, err - } - } - return common_err.ERROR, err -} - -//create -func (c *zima) CreateFile(path string) (int, error) { - _, err := os.Stat(path) - if err == nil { - return common_err.FILE_OR_DIR_EXISTS, nil - } else { - if os.IsNotExist(err) { - file.CreateFile(path) - return common_err.SUCCESS, nil - } - } - return common_err.ERROR, err -} - -//修改文件 -func (c *zima) RenameFile(oldF, newF string) (int, error) { - - _, err := os.Stat(newF) - if err == nil { - return common_err.DIR_ALREADY_EXISTS, nil - } else { - if os.IsNotExist(err) { - err := os.Rename(oldF, newF) - if err != nil { - return common_err.ERROR, err - } - return common_err.SUCCESS, nil - } - } - return common_err.ERROR, err -} - -//获取zima服务 -func NewZiMaService() ZiMaService { - return &zima{} -} - -// func LoopNet() { -// netList := MyService.ZiMa().GetNetInfo() - -// nets := MyService.ZiMa().GetNet(true) -// num := 0 -// for i := 0; i < len(netList); i++ { - -// for _, netCardName := range nets { - -// if netList[i].Name == netCardName { -// var netArray []model.IOCountersStat -// if len(NetArray) < (num + 1) { -// netArray = []model.IOCountersStat{} -// } else { -// netArray = NetArray[num] -// } -// item := *(*model.IOCountersStat)(unsafe.Pointer(&netList[i])) -// item.State = strings.TrimSpace(MyService.ZiMa().GetNetState(netList[i].Name)) -// item.Time = time.Now().Unix() - -// if len(netArray) >= 60 { -// netArray = netArray[1:] -// } -// netArray = append(netArray, item) -// if len(NetArray) < (num + 1) { -// NetArray = append(NetArray, []model.IOCountersStat{}) -// } - -// NetArray[num] = netArray - -// num++ -// break -// } -// } - -// } -// } diff --git a/web/index.html b/web/index.html index 84e74cf..ca8c80e 100644 --- a/web/index.html +++ b/web/index.html @@ -20,7 +20,7 @@ CasaOS - +