diff --git a/go.mod b/go.mod index f329d17..47e365e 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( github.com/googollee/go-socket.io v1.6.2 github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.4.2 + github.com/hirochachacha/go-smb2 v1.1.0 github.com/jinzhu/copier v0.3.2 github.com/json-iterator/go v1.1.11 // indirect github.com/klauspost/compress v1.13.6 // indirect diff --git a/go.sum b/go.sum index f5c119c..b472d34 100644 --- a/go.sum +++ b/go.sum @@ -330,6 +330,8 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/geoffgarside/ber v1.1.0 h1:qTmFG4jJbwiSzSXoNJeHcOprVzZ8Ulde2Rrrifu5U9w= +github.com/geoffgarside/ber v1.1.0/go.mod h1:jVPKeCbj6MvQZhwLYsGwaGI52oUorHoHKNecGT85ZCc= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/gzip v0.0.2 h1:VMBkd4ZB1Hl7e1lOA5gEZ/qdD3d9vLIq57xKWgPCCV8= @@ -513,6 +515,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hirochachacha/go-smb2 v1.1.0 h1:b6hs9qKIql9eVXAiN0M2wSFY5xnhbHAQoCwRKbaRTZI= +github.com/hirochachacha/go-smb2 v1.1.0/go.mod h1:8F1A4d5EZzrGu5R7PU163UcMRDJQl4FtcxjBfsY8TZE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= diff --git a/model/connections.go b/model/connections.go new file mode 100644 index 0000000..c0ab07b --- /dev/null +++ b/model/connections.go @@ -0,0 +1,21 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-07-27 10:30:43 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 11:36:08 + * @FilePath: /CasaOS/model/connections.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package model + +type Connections struct { + ID uint `json:"id"` + Username string `json:"username"` + Password string `json:"password,omitempty"` + Host string `json:"host"` + Port string `json:"port"` + Directory string `json:"directory"` + MountPoint string `json:"mount_point"` +} diff --git a/model/share.go b/model/share.go new file mode 100644 index 0000000..f164db1 --- /dev/null +++ b/model/share.go @@ -0,0 +1,17 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-07-26 11:12:12 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 14:58:55 + * @FilePath: /CasaOS/model/share.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package model + +type Shares struct { + ID uint `json:"id"` + Anonymous bool `json:"anonymous"` + Path string `json:"path"` +} diff --git a/pkg/samba/smaba.go b/pkg/samba/smaba.go new file mode 100644 index 0000000..0d35e0b --- /dev/null +++ b/pkg/samba/smaba.go @@ -0,0 +1,49 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-07-27 10:35:29 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 10:40:26 + * @FilePath: /CasaOS/pkg/samba/smaba.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package samba + +import ( + "errors" + "net" + + "github.com/hirochachacha/go-smb2" +) + +func ConnectSambaService(host, port, username, password, directory string) error { + conn, err := net.Dial("tcp", host+":"+port) + if err != nil { + return err + } + defer conn.Close() + d := &smb2.Dialer{ + Initiator: &smb2.NTLMInitiator{ + User: username, + Password: password, + }, + } + + s, err := d.Dial(conn) + if err != nil { + return err + } + defer s.Logoff() + names, err := s.ListSharenames() + if err != nil { + return err + } + + for _, name := range names { + if name == directory { + return nil + } + } + return errors.New("directory not found") +} diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go index 3503cd0..383d2c4 100644 --- a/pkg/sqlite/db.go +++ b/pkg/sqlite/db.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-05-13 18:15:46 * @LastEditors: LinkLeong - * @LastEditTime: 2022-07-11 18:10:53 + * @LastEditTime: 2022-07-27 11:25:26 * @FilePath: /CasaOS/pkg/sqlite/db.go * @Description: * @Website: https://www.casaos.io @@ -53,7 +53,7 @@ func GetDb(dbPath string) *gorm.DB { drop table o_user; `) - err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.UserDBModel{}) + err = db.AutoMigrate(&model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.UserDBModel{}, model2.SharesDBModel{}, model2.ConnectionsDBModel{}) db.Exec("DROP TABLE IF EXISTS o_application") db.Exec("DROP TABLE IF EXISTS o_friend") db.Exec("DROP TABLE IF EXISTS o_person_download") diff --git a/pkg/utils/common_err/e.go b/pkg/utils/common_err/e.go index 79ee8cd..251084c 100644 --- a/pkg/utils/common_err/e.go +++ b/pkg/utils/common_err/e.go @@ -27,6 +27,8 @@ const ( PORT_IS_OCCUPIED = 20004 COMMAND_ERROR_INVALID_OPERATION = 20005 VERIFICATION_FAILURE = 20006 + Record_NOT_EXIST = 20007 + Record_ALREADY_EXIST = 20008 //disk NAME_NOT_AVAILABLE = 40001 @@ -48,8 +50,9 @@ const ( DIR_NOT_EXISTS = 60004 SOURCE_DES_SAME = 60005 - //shortcuts - SHORTCUTS_URL_ERROR = 70001 + //share + SHARE_ALREADY_EXISTS = 70001 + SHARE_NAME_ALREADY_EXISTS = 70002 ) var MsgFlags = map[int]string{ @@ -78,6 +81,8 @@ var MsgFlags = map[int]string{ FILE_OR_DIR_EXISTS: "File or folder already exists", PORT_IS_OCCUPIED: "Port is occupied", VERIFICATION_FAILURE: "Verification failure", + Record_ALREADY_EXIST: "Record already exists", + Record_NOT_EXIST: "Record does not exist", //app UNINSTALL_APP_ERROR: "Error uninstalling app", @@ -91,16 +96,17 @@ var MsgFlags = map[int]string{ REMOVE_MOUNT_POINT_ERROR: "Failed to remove mount point", DISK_BUSYING: "Drive is busy", FORMAT_ERROR: "Formatting failed, please check if the directory is occupied", - + //share + SHARE_ALREADY_EXISTS: "Share already exists", + SHARE_NAME_ALREADY_EXISTS: "Share name already exists", // SOURCE_DES_SAME: "Source and destination cannot be the same.", FILE_DOES_NOT_EXIST: "File does not exist", DIR_NOT_EXISTS: "Directory does not exist", - FILE_READ_ERROR: "File read error", - FILE_DELETE_ERROR: "Delete error", - SHORTCUTS_URL_ERROR: "URL error", + FILE_READ_ERROR: "File read error", + FILE_DELETE_ERROR: "Delete error", COMMAND_ERROR_INVALID_OPERATION: "invalid operation", } diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go index 20460ed..b08dcda 100644 --- a/pkg/utils/file/file.go +++ b/pkg/utils/file/file.go @@ -547,3 +547,20 @@ func MoveFile(sourcePath, destPath string) error { } return nil } + +func ReadLine(lineNumber int, path string) string { + file, err := os.Open(path) + if err != nil { + return "" + } + fileScanner := bufio.NewScanner(file) + lineCount := 1 + for fileScanner.Scan() { + if lineCount == lineNumber { + return fileScanner.Text() + } + lineCount++ + } + defer file.Close() + return "" +} diff --git a/route/init.go b/route/init.go index 7aedb2f..af082d2 100644 --- a/route/init.go +++ b/route/init.go @@ -15,15 +15,16 @@ import ( ) func InitFunction() { - ShellInit() CheckSerialDiskMount() CheckToken2_11() ImportApplications() + // Soon to be removed ChangeAPIUrl() MoveUserToDB() + InitSamba() } func CheckSerialDiskMount() { @@ -138,3 +139,66 @@ func MoveUserToDB() { } } + +func InitSamba() { + if file.Exists("/etc/samba/smb.conf") { + str := file.ReadLine(1, "/etc/samba/smb.conf") + if strings.Contains(str, "# Copyright (c) 2021-2022 CasaOS Inc. All rights reserved.") { + + return + } + file.MoveFile("/etc/samba/smb.conf", "/etc/samba/smb.conf.bak") + var smbConf = "" + smbConf += `# Copyright (c) 2021-2022 CasaOS Inc. All rights reserved. +# +# +# ______ _______ +# ( __ \ ( ___ ) +# | ( \ ) | ( ) | +# | | ) | | | | | +# | | | | | | | | +# | | ) | | | | | +# | (__/ ) | (___) | +# (______/ (_______) +# +# _ _______ _________ +# ( ( /| ( ___ ) \__ __/ +# | \ ( | | ( ) | ) ( +# | \ | | | | | | | | +# | (\ \) | | | | | | | +# | | \ | | | | | | | +# | ) \ | | (___) | | | +# |/ )_) (_______) )_( +# +# _______ _______ ______ _________ _______ +# ( ) ( ___ ) ( __ \ \__ __/ ( ____ \ |\ /| +# | () () | | ( ) | | ( \ ) ) ( | ( \/ ( \ / ) +# | || || | | | | | | | ) | | | | (__ \ (_) / +# | |(_)| | | | | | | | | | | | | __) \ / +# | | | | | | | | | | ) | | | | ( ) ( +# | ) ( | | (___) | | (__/ ) ___) (___ | ) | | +# |/ \| (_______) (______/ \_______/ |/ \_/ +# +# +# IMPORTANT: CasaOS will not provide technical support for any issues +# caused by unauthorized modification to the configuration. + +[global] +## fruit settings + min protocol = SMB2 + ea support = yes + vfs objects = fruit streams_xattr + fruit:metadata = stream + fruit:model = Macmini + fruit:veto_appledouble = no + fruit:posix_rename = yes + fruit:zero_file_id = yes + fruit:wipe_intentionally_left_blank_rfork = yes + fruit:delete_empty_adfiles = yes + map to guest = bad user + include=/etc/samba/smb.casa.conf + + ` + file.WriteToPath([]byte(smbConf), "/etc/samba", "smb.conf") + } +} diff --git a/route/route.go b/route/route.go index d6af7a8..cd2471b 100644 --- a/route/route.go +++ b/route/route.go @@ -217,6 +217,24 @@ func InitRouter() *gin.Engine { v1StorageGroup.DELETE("", v1.PostDiskUmount) } + v1SambaGroup := v1Group.Group("/samba") + v1SambaGroup.Use() + { + v1ConnectionsGroup := v1SambaGroup.Group("/connections") + v1ConnectionsGroup.Use() + { + v1ConnectionsGroup.GET("", v1.GetSambaConnectionsList) + v1ConnectionsGroup.POST("", v1.PostSambaConnectionsCreate) + v1ConnectionsGroup.DELETE("/:id", v1.DeleteSambaConnections) + } + v1SharesGroup := v1SambaGroup.Group("/shares") + v1SharesGroup.Use() + { + v1SharesGroup.GET("", v1.GetSambaSharesList) + v1SharesGroup.POST("", v1.PostSambaSharesCreate) + v1SharesGroup.DELETE("/:id", v1.DeleteSambaShares) + } + } } return r } diff --git a/route/v1/samba.go b/route/v1/samba.go new file mode 100644 index 0000000..adf5f9c --- /dev/null +++ b/route/v1/samba.go @@ -0,0 +1,154 @@ +/* + * @Author: LinkLeong link@icewhale.com + * @Date: 2022-07-26 11:08:48 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 15:30:08 + * @FilePath: /CasaOS/route/v1/samba.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package v1 + +import ( + "fmt" + "path/filepath" + + "github.com/IceWhaleTech/CasaOS/model" + "github.com/IceWhaleTech/CasaOS/pkg/samba" + "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err" + "github.com/IceWhaleTech/CasaOS/pkg/utils/file" + "github.com/IceWhaleTech/CasaOS/service" + model2 "github.com/IceWhaleTech/CasaOS/service/model" + "github.com/gin-gonic/gin" +) + +// service + +func GetSambaSharesList(c *gin.Context) { + shares := service.MyService.Shares().GetSharesList() + shareList := []model.Shares{} + for _, v := range shares { + shareList = append(shareList, model.Shares{ + Anonymous: v.Anonymous, + Path: v.Path, + ID: v.ID, + }) + } + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shareList}) +} + +func PostSambaSharesCreate(c *gin.Context) { + shares := []model.Shares{} + c.ShouldBindJSON(&shares) + for _, v := range shares { + if v.Path == "" { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) + return + } + if !file.Exists(v.Path) { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)}) + return + } + if len(service.MyService.Shares().GetSharesByPath(v.Path)) > 0 { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_ALREADY_EXISTS)}) + return + } + if len(service.MyService.Shares().GetSharesByPath(filepath.Base(v.Path))) > 0 { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_NAME_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_NAME_ALREADY_EXISTS)}) + return + } + + } + for _, v := range shares { + shareDBModel := model2.SharesDBModel{} + shareDBModel.Anonymous = true + shareDBModel.Path = v.Path + shareDBModel.Name = filepath.Base(v.Path) + service.MyService.Shares().CreateShare(shareDBModel) + } + + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shares}) +} +func DeleteSambaShares(c *gin.Context) { + id := c.Param("id") + if id == "" { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)}) + return + } + service.MyService.Shares().DeleteShare(id) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) +} + +//client + +func GetSambaConnectionsList(c *gin.Context) { + connections := service.MyService.Connections().GetConnectionsList() + connectionList := []model.Connections{} + for _, v := range connections { + connectionList = append(connectionList, model.Connections{ + ID: v.ID, + Username: v.Username, + MountPoint: v.MountPoint, + Directory: v.Directory, + Port: v.Port, + Host: v.Host, + }) + } + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList}) +} + +func PostSambaConnectionsCreate(c *gin.Context) { + connection := model.Connections{} + err := c.ShouldBindJSON(&connection) + fmt.Println(err) + if connection.Port == "" { + connection.Port = "445" + } + if connection.Username == "" || connection.Directory == "" || connection.Host == "" || connection.MountPoint == "" { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)}) + return + } + // check is exists + + connections := service.MyService.Connections().GetConnectionByDirectory(connection.Directory) + if len(connections) > 0 { + for _, v := range connections { + if v.Host == connection.Host { + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.Record_ALREADY_EXIST, Message: common_err.GetMsg(common_err.Record_ALREADY_EXIST), Data: common_err.GetMsg(common_err.Record_ALREADY_EXIST)}) + return + } + } + } + // check connect is ok + if err := samba.ConnectSambaService(connection.Host, connection.Port, connection.Username, connection.Password, connection.Directory); err != nil { + fmt.Println("check", err) + c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()}) + return + } + + connectionDBModel := model2.ConnectionsDBModel{} + connectionDBModel.Username = connection.Username + connectionDBModel.Password = connection.Password + connectionDBModel.Directory = connection.Directory + connectionDBModel.Host = connection.Host + connectionDBModel.Port = connection.Port + connectionDBModel.MountPoint = connection.MountPoint + file.IsNotExistMkDir(connection.MountPoint) + service.MyService.Connections().CreateConnection(&connectionDBModel) + service.MyService.Connections().MountSmaba(&connectionDBModel) + connection.ID = connectionDBModel.ID + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection}) +} + +func DeleteSambaConnections(c *gin.Context) { + id := c.Param("id") + connection := service.MyService.Connections().GetConnectionByID(id) + if connection.Username == "" { + c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)}) + return + } + service.MyService.Connections().UnmountSmaba(connection.MountPoint) + service.MyService.Connections().DeleteConnection(id) + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id}) +} diff --git a/service/connections.go b/service/connections.go new file mode 100644 index 0000000..5136676 --- /dev/null +++ b/service/connections.go @@ -0,0 +1,65 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-07-26 18:13:22 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 13:44:12 + * @FilePath: /CasaOS/service/connections.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package service + +import ( + "github.com/IceWhaleTech/CasaOS/pkg/config" + command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" + "github.com/IceWhaleTech/CasaOS/service/model" + model2 "github.com/IceWhaleTech/CasaOS/service/model" + "gorm.io/gorm" +) + +type ConnectionsService interface { + GetConnectionsList() (connections []model2.ConnectionsDBModel) + GetConnectionByDirectory(directory string) (connections []model2.ConnectionsDBModel) + GetConnectionByID(id string) (connections model2.ConnectionsDBModel) + CreateConnection(connection *model2.ConnectionsDBModel) + DeleteConnection(id string) + MountSmaba(connection *model2.ConnectionsDBModel) string + UnmountSmaba(mountPoint string) string +} + +type connectionsStruct struct { + db *gorm.DB +} + +func (s *connectionsStruct) GetConnectionByDirectory(directory string) (connections []model2.ConnectionsDBModel) { + s.db.Select("username,host,directory,status,mount_point,id").Where("directory = ?", directory).Find(&connections) + return +} +func (s *connectionsStruct) GetConnectionByID(id string) (connections model2.ConnectionsDBModel) { + s.db.Select("username,password,host,directory,status,mount_point,id").Where("id = ?", id).First(&connections) + return +} +func (s *connectionsStruct) GetConnectionsList() (connections []model2.ConnectionsDBModel) { + s.db.Select("username,host,port,directory,status,mount_point,id").Find(&connections) + return +} +func (s *connectionsStruct) CreateConnection(connection *model2.ConnectionsDBModel) { + s.db.Create(connection) +} +func (s *connectionsStruct) DeleteConnection(id string) { + s.db.Where("id= ?", id).Delete(&model.ConnectionsDBModel{}) +} + +func (s *connectionsStruct) MountSmaba(connection *model2.ConnectionsDBModel) string { + str := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;MountCIFS " + connection.Username + " " + connection.Host + " " + connection.Directory + " " + connection.Port + " " + connection.MountPoint + " " + connection.Password) + return str +} +func (s *connectionsStruct) UnmountSmaba(mountPoint string) string { + str := command2.ExecResultStr("source " + config.AppInfo.ShellPath + "/helper.sh ;UMountPorintAndRemoveDir " + mountPoint) + return str +} + +func NewConnectionsService(db *gorm.DB) ConnectionsService { + return &connectionsStruct{db: db} +} diff --git a/service/model/o_connections.go b/service/model/o_connections.go new file mode 100644 index 0000000..9c79df3 --- /dev/null +++ b/service/model/o_connections.go @@ -0,0 +1,28 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-07-26 17:17:57 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 10:44:46 + * @FilePath: /CasaOS/service/model/o_connections.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package model + +type ConnectionsDBModel struct { + ID uint `gorm:"column:id;primary_key" json:"id"` + Updated int64 `gorm:"autoUpdateTime"` + Created int64 `gorm:"autoCreateTime"` + Username string `json:"username"` + Password string `json:"password"` + Host string `json:"host"` + Port string `json:"port"` + Directory string `json:"directory"` + MountPoint string `json:"mount_point"` + Status string `json:"status"` +} + +func (p *ConnectionsDBModel) TableName() string { + return "o_connections" +} diff --git a/service/model/o_shares.go b/service/model/o_shares.go new file mode 100644 index 0000000..a887522 --- /dev/null +++ b/service/model/o_shares.go @@ -0,0 +1,24 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-07-26 11:17:17 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 15:25:07 + * @FilePath: /CasaOS/service/model/o_shares.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package model + +type SharesDBModel struct { + ID uint `gorm:"column:id;primary_key" json:"id"` + Anonymous bool `json:"anonymous"` + Path string `json:"path"` + Name string `json:"name"` + Updated int64 `gorm:"autoUpdateTime"` + Created int64 `gorm:"autoCreateTime"` +} + +func (p *SharesDBModel) TableName() string { + return "o_shares" +} diff --git a/service/service.go b/service/service.go index 2f348fc..9eac558 100644 --- a/service/service.go +++ b/service/service.go @@ -2,7 +2,7 @@ * @Author: LinkLeong link@icewhale.com * @Date: 2022-07-12 09:48:56 * @LastEditors: LinkLeong - * @LastEditTime: 2022-07-15 10:58:54 + * @LastEditTime: 2022-07-27 10:28:48 * @FilePath: /CasaOS/service/service.go * @Description: * @Website: https://www.casaos.io @@ -33,31 +33,44 @@ type Repository interface { Notify() NotifyServer Rely() RelyService System() SystemService + Shares() SharesService + Connections() ConnectionsService } func NewService(db *gorm.DB) Repository { return &store{ - app: NewAppService(db), - user: NewUserService(db), - docker: NewDockerService(), - casa: NewCasaService(), - disk: NewDiskService(db), - notify: NewNotifyService(db), - rely: NewRelyService(db), - system: NewSystemService(), + app: NewAppService(db), + user: NewUserService(db), + docker: NewDockerService(), + casa: NewCasaService(), + disk: NewDiskService(db), + notify: NewNotifyService(db), + rely: NewRelyService(db), + system: NewSystemService(), + shares: NewSharesService(db), + connections: NewConnectionsService(db), } } type store struct { - db *gorm.DB - app AppService - user UserService - docker DockerService - casa CasaService - disk DiskService - notify NotifyServer - rely RelyService - system SystemService + db *gorm.DB + app AppService + user UserService + docker DockerService + casa CasaService + disk DiskService + notify NotifyServer + rely RelyService + system SystemService + shares SharesService + connections ConnectionsService +} + +func (s *store) Connections() ConnectionsService { + return s.connections +} +func (s *store) Shares() SharesService { + return s.shares } func (c *store) Rely() RelyService { diff --git a/service/shares.go b/service/shares.go new file mode 100644 index 0000000..f05c5b4 --- /dev/null +++ b/service/shares.go @@ -0,0 +1,84 @@ +/* + * @Author: LinkLeong link@icewhale.org + * @Date: 2022-07-26 11:21:14 + * @LastEditors: LinkLeong + * @LastEditTime: 2022-07-27 15:27:38 + * @FilePath: /CasaOS/service/shares.go + * @Description: + * @Website: https://www.casaos.io + * Copyright (c) 2022 by icewhale, All Rights Reserved. + */ +package service + +import ( + "path/filepath" + + "github.com/IceWhaleTech/CasaOS/pkg/config" + command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command" + "github.com/IceWhaleTech/CasaOS/pkg/utils/file" + "github.com/IceWhaleTech/CasaOS/service/model" + model2 "github.com/IceWhaleTech/CasaOS/service/model" + "gorm.io/gorm" +) + +type SharesService interface { + GetSharesList() (shares []model2.SharesDBModel) + GetSharesByPath(path string) (shares []model2.SharesDBModel) + GetSharesByName(name string) (shares []model2.SharesDBModel) + CreateShare(share model2.SharesDBModel) + DeleteShare(id string) + UpdateConfigFile() +} + +type sharesStruct struct { + db *gorm.DB +} + +func (s *sharesStruct) GetSharesByName(name string) (shares []model2.SharesDBModel) { + s.db.Select("title,anonymous,path,id").Where("name = ?", name).Find(&shares) + return +} +func (s *sharesStruct) GetSharesByPath(path string) (shares []model2.SharesDBModel) { + s.db.Select("title,anonymous,path,id").Where("path = ?", path).Find(&shares) + return +} +func (s *sharesStruct) GetSharesList() (shares []model2.SharesDBModel) { + s.db.Select("title,anonymous,path,id").Find(&shares) + return +} +func (s *sharesStruct) CreateShare(share model2.SharesDBModel) { + s.db.Create(&share) + s.UpdateConfigFile() +} +func (s *sharesStruct) DeleteShare(id string) { + s.db.Where("id= ?", id).Delete(&model.SharesDBModel{}) + s.UpdateConfigFile() +} + +func (s *sharesStruct) UpdateConfigFile() { + shares := []model2.SharesDBModel{} + s.db.Select("title,anonymous,path").Find(&shares) + //generated config file + var configStr = "" + for _, share := range shares { + dirName := filepath.Base(share.Path) + configStr += ` +[` + dirName + `] +public = Yes +path = ` + share.Path + ` +browseable = Yes +read only = No +guest ok = Yes +create mask = 0777 +directory mask = 0777 + +` + } + //write config file + file.WriteToPath([]byte(configStr), "/etc/samba", "smb.casa.conf") + //restart samba + command2.ExecResultStrArray("source " + config.AppInfo.ShellPath + "/helper.sh ;RestartSMBD") +} +func NewSharesService(db *gorm.DB) SharesService { + return &sharesStruct{db: db} +} diff --git a/shell/helper.sh b/shell/helper.sh index 8bd81bf..eabfa8a 100644 --- a/shell/helper.sh +++ b/shell/helper.sh @@ -363,4 +363,9 @@ AddSmabaUser(){ $2 $2 EOF -} \ No newline at end of file +} + +# $1:username $2:host $3:share $4:port $5:mountpoint $6:password +MountCIFS(){ + $sudo_cmd mount -t cifs -o username=$1,password=$6,port=$4 //$2/$3 $5 +}