change branch

This commit is contained in:
a624669980@163.com 2022-06-24 09:26:34 +08:00
parent f1a1c05c94
commit aadb32404a
74 changed files with 1271 additions and 2653 deletions

View File

@ -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

2
UI

@ -1 +1 @@
Subproject commit 62a6bd44d5740e3cb0ba0694d37c943147bea362
Subproject commit c4cfe885e510a4fa3792f4e4fb5ee7debce4332e

40
conf/conf.conf Normal file
View File

@ -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

View File

@ -1,7 +1,7 @@
[app]
PAGE_SIZE = 10
RuntimeRootPath = runtime/
LogSavePath = /var/log/casaos/
LogPath = /var/log/casaos/
LogSaveName = log
LogFileExt = log
DateStrFormat = 20060102

40
main.go
View File

@ -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()
}
})

View File

@ -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()
}
}

View File

@ -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"`

View File

@ -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"`
//

View File

@ -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"`
}

View File

@ -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"
)

View File

@ -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()

View File

@ -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))
}

View File

@ -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
}

View File

@ -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")
}
}

View File

@ -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
}

View File

@ -1,8 +0,0 @@
package upnp
import "testing"
func TestGateway(t *testing.T) {
Gateway()
}

View File

@ -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("</" + n.Name + ">")
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
}

View File

@ -1,7 +0,0 @@
package upnp
import "testing"
func TestAddPortMapping(t *testing.T) {
//AddPortMapping(6666,6666,"TCP","192.168.2.15000",)
}

View File

@ -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)
}
}

View File

@ -1,9 +0,0 @@
package upnp
import (
"testing"
)
func TestTestaaa(t *testing.T) {
(Testaaa())
}

View File

@ -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",

View File

@ -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)

View File

@ -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")
}

View File

@ -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 ""
}
}

View File

@ -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)

View File

@ -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, ".")

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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
}

View File

@ -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) {

View File

@ -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)})
}

View File

@ -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})
}

View File

@ -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})
}

View File

@ -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

View File

@ -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})

View File

@ -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)})
}

View File

@ -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)})
}

View File

@ -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

View File

@ -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})
}

View File

@ -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)})
}

View File

@ -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})
}

View File

@ -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})
}

View File

@ -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" {

View File

@ -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{}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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")
}

View File

@ -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()
}

View File

@ -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"
}

View File

@ -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

View File

@ -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"
}

View File

@ -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:"-"`
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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

View File

@ -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{}

View File

@ -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{}
}

View File

@ -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
}

View File

@ -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 <<kahan@informatik.tu-muenchen.de> 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}
}

View File

@ -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()
}

View File

@ -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}
}

View File

@ -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
}

View File

@ -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
// }
// }
// }
// }

View File

@ -20,7 +20,7 @@
<title>
CasaOS
</title>
<link href="/ui/css/10.d72d6157.css" rel="prefetch"><link href="/ui/css/11.f8326b27.css" rel="prefetch"><link href="/ui/css/16.a16d5119.css" rel="prefetch"><link href="/ui/css/17.cf8c898a.css" rel="prefetch"><link href="/ui/css/8.8acf69a4.css" rel="prefetch"><link href="/ui/css/9.e57f27f9.css" rel="prefetch"><link href="/ui/js/0.js" rel="prefetch"><link href="/ui/js/1.js" rel="prefetch"><link href="/ui/js/10.js" rel="prefetch"><link href="/ui/js/11.js" rel="prefetch"><link href="/ui/js/12.js" rel="prefetch"><link href="/ui/js/13.js" rel="prefetch"><link href="/ui/js/14.js" rel="prefetch"><link href="/ui/js/15.js" rel="prefetch"><link href="/ui/js/16.js" rel="prefetch"><link href="/ui/js/17.js" rel="prefetch"><link href="/ui/js/18.js" rel="prefetch"><link href="/ui/js/2.js" rel="prefetch"><link href="/ui/js/3.js" rel="prefetch"><link href="/ui/js/4.js" rel="prefetch"><link href="/ui/js/5.js" rel="prefetch"><link href="/ui/js/6.js" rel="prefetch"><link href="/ui/js/7.js" rel="prefetch"><link href="/ui/js/8.js" rel="prefetch"><link href="/ui/js/9.js" rel="prefetch"><link href="/ui/css/app.fccf59b0.css" rel="preload" as="style"><link href="/ui/css/vendors~app.8a2c28d7.css" rel="preload" as="style"><link href="/ui/js/app.js" rel="preload" as="script"><link href="/ui/js/vendors~app.js" rel="preload" as="script"><link href="/ui/css/vendors~app.8a2c28d7.css" rel="stylesheet"><link href="/ui/css/app.fccf59b0.css" rel="stylesheet"></head>
<link href="/ui/css/10.32be8789.css" rel="prefetch"><link href="/ui/css/11.dc77452d.css" rel="prefetch"><link href="/ui/css/16.1f93b660.css" rel="prefetch"><link href="/ui/css/17.046fd3d8.css" rel="prefetch"><link href="/ui/css/8.332ce37a.css" rel="prefetch"><link href="/ui/css/9.e1b97a16.css" rel="prefetch"><link href="/ui/js/0.js" rel="prefetch"><link href="/ui/js/1.js" rel="prefetch"><link href="/ui/js/10.js" rel="prefetch"><link href="/ui/js/11.js" rel="prefetch"><link href="/ui/js/12.js" rel="prefetch"><link href="/ui/js/13.js" rel="prefetch"><link href="/ui/js/14.js" rel="prefetch"><link href="/ui/js/15.js" rel="prefetch"><link href="/ui/js/16.js" rel="prefetch"><link href="/ui/js/17.js" rel="prefetch"><link href="/ui/js/18.js" rel="prefetch"><link href="/ui/js/2.js" rel="prefetch"><link href="/ui/js/3.js" rel="prefetch"><link href="/ui/js/4.js" rel="prefetch"><link href="/ui/js/5.js" rel="prefetch"><link href="/ui/js/6.js" rel="prefetch"><link href="/ui/js/7.js" rel="prefetch"><link href="/ui/js/8.js" rel="prefetch"><link href="/ui/js/9.js" rel="prefetch"><link href="/ui/css/app.7c063b35.css" rel="preload" as="style"><link href="/ui/css/vendors~app.a048753d.css" rel="preload" as="style"><link href="/ui/js/app.js" rel="preload" as="script"><link href="/ui/js/vendors~app.js" rel="preload" as="script"><link href="/ui/css/vendors~app.a048753d.css" rel="stylesheet"><link href="/ui/css/app.7c063b35.css" rel="stylesheet"></head>
<body>
<noscript>

View File

@ -26,7 +26,7 @@
/*!*************************************!*\
!*** ./src/plugins/vee-validate.js ***!
\*************************************/
/*! no exports provided */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/objectSpread2 */ "./node_modules/@babel/runtime/helpers/esm/objectSpread2.js");\n/* harmony import */ var vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vee-validate/dist/rules */ "./node_modules/vee-validate/dist/rules.js");\n/* harmony import */ var vee_validate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vee-validate */ "./node_modules/vee-validate/dist/vee-validate.esm.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! is-valid-hostname */ "./node_modules/is-valid-hostname/index.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid-validate */ "./node_modules/uuid-validate/index.js");\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid_validate__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("required", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["required"]), {}, {\n message: "This field is required"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("email", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["email"]), {}, {\n message: "This field must be a valid email"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("confirmed", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["confirmed"]), {}, {\n message: "This field confirmation does not match"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("length", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["length"]), {}, {\n message: "This field must have 2 options"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("min", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["min"]), {}, {\n message: "This field must have more than {length} characters"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'rfc1123\', {\n validate: function validate(value) {\n return is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default()(value);\n },\n message: \'You entered an invalid RFC1123 hostname\'\n});\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'uuid\', {\n validate: function validate(value) {\n return uuid_validate__WEBPACK_IMPORTED_MODULE_4___default()(value);\n },\n message: \'You entered an invalid share ID\'\n});\n\n//# sourceURL=webpack:///./src/plugins/vee-validate.js?')},"./src/views/Welcome.vue":
/*! no exports provided */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/objectSpread2 */ "./node_modules/@babel/runtime/helpers/esm/objectSpread2.js");\n/* harmony import */ var vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vee-validate/dist/rules */ "./node_modules/vee-validate/dist/rules.js");\n/* harmony import */ var vee_validate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vee-validate */ "./node_modules/vee-validate/dist/vee-validate.esm.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! is-valid-hostname */ "./node_modules/is-valid-hostname/index.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid-validate */ "./node_modules/uuid-validate/index.js");\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid_validate__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("required", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["required"]), {}, {\n message: "This field is required"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("email", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["email"]), {}, {\n message: "This field must be a valid email"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("confirmed", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["confirmed"]), {}, {\n message: "This field confirmation does not match"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("length", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["length"]), {}, {\n message: "This field must have 2 options"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("min", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["min"]), {}, {\n message: "This field must have more than {length} characters"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'rfc1123\', {\n validate: function validate(value) {\n return is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default()(value);\n },\n message: \'You entered an invalid RFC1123 hostname\'\n});\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'uuid\', {\n validate: function validate(value) {\n return uuid_validate__WEBPACK_IMPORTED_MODULE_4___default()(value);\n },\n message: \'You entered an invalid share ID\'\n});\n\n//# sourceURL=webpack:///./src/plugins/vee-validate.js?')},"./src/views/Welcome.vue":
/*!*******************************!*\
!*** ./src/views/Welcome.vue ***!
\*******************************/

View File

@ -14,7 +14,7 @@
/*!*************************************!*\
!*** ./src/plugins/vee-validate.js ***!
\*************************************/
/*! no exports provided */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/objectSpread2 */ "./node_modules/@babel/runtime/helpers/esm/objectSpread2.js");\n/* harmony import */ var vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vee-validate/dist/rules */ "./node_modules/vee-validate/dist/rules.js");\n/* harmony import */ var vee_validate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vee-validate */ "./node_modules/vee-validate/dist/vee-validate.esm.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! is-valid-hostname */ "./node_modules/is-valid-hostname/index.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid-validate */ "./node_modules/uuid-validate/index.js");\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid_validate__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("required", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["required"]), {}, {\n message: "This field is required"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("email", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["email"]), {}, {\n message: "This field must be a valid email"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("confirmed", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["confirmed"]), {}, {\n message: "This field confirmation does not match"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("length", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["length"]), {}, {\n message: "This field must have 2 options"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("min", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["min"]), {}, {\n message: "This field must have more than {length} characters"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'rfc1123\', {\n validate: function validate(value) {\n return is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default()(value);\n },\n message: \'You entered an invalid RFC1123 hostname\'\n});\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'uuid\', {\n validate: function validate(value) {\n return uuid_validate__WEBPACK_IMPORTED_MODULE_4___default()(value);\n },\n message: \'You entered an invalid share ID\'\n});\n\n//# sourceURL=webpack:///./src/plugins/vee-validate.js?')},"./src/views/Login.vue":
/*! no exports provided */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/objectSpread2 */ "./node_modules/@babel/runtime/helpers/esm/objectSpread2.js");\n/* harmony import */ var vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vee-validate/dist/rules */ "./node_modules/vee-validate/dist/rules.js");\n/* harmony import */ var vee_validate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vee-validate */ "./node_modules/vee-validate/dist/vee-validate.esm.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! is-valid-hostname */ "./node_modules/is-valid-hostname/index.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid-validate */ "./node_modules/uuid-validate/index.js");\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid_validate__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("required", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["required"]), {}, {\n message: "This field is required"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("email", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["email"]), {}, {\n message: "This field must be a valid email"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("confirmed", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["confirmed"]), {}, {\n message: "This field confirmation does not match"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("length", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["length"]), {}, {\n message: "This field must have 2 options"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("min", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["min"]), {}, {\n message: "This field must have more than {length} characters"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'rfc1123\', {\n validate: function validate(value) {\n return is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default()(value);\n },\n message: \'You entered an invalid RFC1123 hostname\'\n});\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'uuid\', {\n validate: function validate(value) {\n return uuid_validate__WEBPACK_IMPORTED_MODULE_4___default()(value);\n },\n message: \'You entered an invalid share ID\'\n});\n\n//# sourceURL=webpack:///./src/plugins/vee-validate.js?')},"./src/views/Login.vue":
/*!*****************************!*\
!*** ./src/views/Login.vue ***!
\*****************************/

View File

@ -62,4 +62,4 @@
/*!*************************************!*\
!*** ./src/plugins/vee-validate.js ***!
\*************************************/
/*! no exports provided */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/objectSpread2 */ "./node_modules/@babel/runtime/helpers/esm/objectSpread2.js");\n/* harmony import */ var vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vee-validate/dist/rules */ "./node_modules/vee-validate/dist/rules.js");\n/* harmony import */ var vee_validate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vee-validate */ "./node_modules/vee-validate/dist/vee-validate.esm.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! is-valid-hostname */ "./node_modules/is-valid-hostname/index.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid-validate */ "./node_modules/uuid-validate/index.js");\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid_validate__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("required", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["required"]), {}, {\n message: "This field is required"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("email", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["email"]), {}, {\n message: "This field must be a valid email"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("confirmed", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["confirmed"]), {}, {\n message: "This field confirmation does not match"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("length", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["length"]), {}, {\n message: "This field must have 2 options"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("min", Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_jerry_Desktop_CasaOS_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["min"]), {}, {\n message: "This field must have more than {length} characters"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'rfc1123\', {\n validate: function validate(value) {\n return is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default()(value);\n },\n message: \'You entered an invalid RFC1123 hostname\'\n});\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'uuid\', {\n validate: function validate(value) {\n return uuid_validate__WEBPACK_IMPORTED_MODULE_4___default()(value);\n },\n message: \'You entered an invalid share ID\'\n});\n\n//# sourceURL=webpack:///./src/plugins/vee-validate.js?')}}]);
/*! no exports provided */function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/objectSpread2 */ "./node_modules/@babel/runtime/helpers/esm/objectSpread2.js");\n/* harmony import */ var vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vee-validate/dist/rules */ "./node_modules/vee-validate/dist/rules.js");\n/* harmony import */ var vee_validate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vee-validate */ "./node_modules/vee-validate/dist/vee-validate.esm.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! is-valid-hostname */ "./node_modules/is-valid-hostname/index.js");\n/* harmony import */ var is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(is_valid_hostname__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! uuid-validate */ "./node_modules/uuid-validate/index.js");\n/* harmony import */ var uuid_validate__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(uuid_validate__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("required", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["required"]), {}, {\n message: "This field is required"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("email", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["email"]), {}, {\n message: "This field must be a valid email"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("confirmed", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["confirmed"]), {}, {\n message: "This field confirmation does not match"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("length", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["length"]), {}, {\n message: "This field must have 2 options"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])("min", Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])(Object(_Users_liangjianli_go_CasaOSNew_CasaOS_UI_node_modules_babel_runtime_helpers_esm_objectSpread2__WEBPACK_IMPORTED_MODULE_0__["default"])({}, vee_validate_dist_rules__WEBPACK_IMPORTED_MODULE_1__["min"]), {}, {\n message: "This field must have more than {length} characters"\n}));\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'rfc1123\', {\n validate: function validate(value) {\n return is_valid_hostname__WEBPACK_IMPORTED_MODULE_3___default()(value);\n },\n message: \'You entered an invalid RFC1123 hostname\'\n});\nObject(vee_validate__WEBPACK_IMPORTED_MODULE_2__["extend"])(\'uuid\', {\n validate: function validate(value) {\n return uuid_validate__WEBPACK_IMPORTED_MODULE_4___default()(value);\n },\n message: \'You entered an invalid share ID\'\n});\n\n//# sourceURL=webpack:///./src/plugins/vee-validate.js?')}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,13 @@
/*
* @Author: LinkLeong link@icewhale.com
* @Date: 2022-06-23 17:28:51
* @LastEditors: LinkLeong
* @LastEditTime: 2022-06-23 17:28:54
* @FilePath: /CasaOS/web/static.go
* @Description:
* @Website: https://www.casaos.io
* Copyright (c) 2022 by icewhale, All Rights Reserved.
*/
package web
import "embed"