samba.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * @Author: LinkLeong link@icewhale.com
  3. * @Date: 2022-07-26 11:08:48
  4. * @LastEditors: LinkLeong
  5. * @LastEditTime: 2022-08-17 18:25:42
  6. * @FilePath: /CasaOS/route/v1/samba.go
  7. * @Description:
  8. * @Website: https://www.casaos.io
  9. * Copyright (c) 2022 by icewhale, All Rights Reserved.
  10. */
  11. package v1
  12. import (
  13. "fmt"
  14. "io/ioutil"
  15. "net/http"
  16. "os"
  17. "path/filepath"
  18. "strings"
  19. "github.com/IceWhaleTech/CasaOS-Common/utils/logger"
  20. "github.com/IceWhaleTech/CasaOS-Common/utils/systemctl"
  21. "go.uber.org/zap"
  22. "github.com/IceWhaleTech/CasaOS/model"
  23. "github.com/IceWhaleTech/CasaOS/pkg/samba"
  24. "github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
  25. "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
  26. "github.com/IceWhaleTech/CasaOS/service"
  27. model2 "github.com/IceWhaleTech/CasaOS/service/model"
  28. "github.com/gin-gonic/gin"
  29. )
  30. // service
  31. func GetSambaStatus(c *gin.Context) {
  32. if status, err := systemctl.IsServiceRunning("smbd"); err != nil || !status {
  33. c.JSON(http.StatusInternalServerError, model.Result{
  34. Success: common_err.SERVICE_NOT_RUNNING,
  35. Message: common_err.GetMsg(common_err.SERVICE_NOT_RUNNING),
  36. })
  37. return
  38. }
  39. needInit := true
  40. if file.Exists("/etc/samba/smb.conf") {
  41. str := file.ReadLine(1, "/etc/samba/smb.conf")
  42. if strings.Contains(str, "# Copyright (c) 2021-2022 CasaOS Inc. All rights reserved.") {
  43. needInit = false
  44. }
  45. }
  46. data := make(map[string]string, 1)
  47. data["need_init"] = fmt.Sprintf("%v", needInit)
  48. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: data})
  49. }
  50. func GetSambaSharesList(c *gin.Context) {
  51. shares := service.MyService.Shares().GetSharesList()
  52. shareList := []model.Shares{}
  53. for _, v := range shares {
  54. shareList = append(shareList, model.Shares{
  55. Anonymous: v.Anonymous,
  56. Path: v.Path,
  57. ID: v.ID,
  58. })
  59. }
  60. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shareList})
  61. }
  62. func PostSambaSharesCreate(c *gin.Context) {
  63. shares := []model.Shares{}
  64. c.ShouldBindJSON(&shares)
  65. for _, v := range shares {
  66. if v.Path == "" {
  67. c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
  68. return
  69. }
  70. if !file.Exists(v.Path) {
  71. c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.DIR_NOT_EXISTS, Message: common_err.GetMsg(common_err.DIR_NOT_EXISTS)})
  72. return
  73. }
  74. if len(service.MyService.Shares().GetSharesByPath(v.Path)) > 0 {
  75. c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.SHARE_ALREADY_EXISTS, Message: common_err.GetMsg(common_err.SHARE_ALREADY_EXISTS)})
  76. return
  77. }
  78. if len(service.MyService.Shares().GetSharesByPath(filepath.Base(v.Path))) > 0 {
  79. 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)})
  80. return
  81. }
  82. }
  83. for _, v := range shares {
  84. shareDBModel := model2.SharesDBModel{}
  85. shareDBModel.Anonymous = true
  86. shareDBModel.Path = v.Path
  87. shareDBModel.Name = filepath.Base(v.Path)
  88. os.Chmod(v.Path, 0o777)
  89. service.MyService.Shares().CreateShare(shareDBModel)
  90. }
  91. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: shares})
  92. }
  93. func DeleteSambaShares(c *gin.Context) {
  94. id := c.Param("id")
  95. if id == "" {
  96. c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INSUFFICIENT_PERMISSIONS, Message: common_err.GetMsg(common_err.INSUFFICIENT_PERMISSIONS)})
  97. return
  98. }
  99. service.MyService.Shares().DeleteShare(id)
  100. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
  101. }
  102. // client
  103. func GetSambaConnectionsList(c *gin.Context) {
  104. connections := service.MyService.Connections().GetConnectionsList()
  105. connectionList := []model.Connections{}
  106. for _, v := range connections {
  107. connectionList = append(connectionList, model.Connections{
  108. ID: v.ID,
  109. Username: v.Username,
  110. Port: v.Port,
  111. Host: v.Host,
  112. MountPoint: v.MountPoint,
  113. })
  114. }
  115. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connectionList})
  116. }
  117. func PostSambaConnectionsCreate(c *gin.Context) {
  118. connection := model.Connections{}
  119. c.ShouldBindJSON(&connection)
  120. if connection.Port == "" {
  121. connection.Port = "445"
  122. }
  123. if connection.Username == "" || connection.Host == "" {
  124. c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
  125. return
  126. }
  127. // if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Password); !ok {
  128. // c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.CHARACTER_LIMIT, Message: common_err.GetMsg(common_err.CHARACTER_LIMIT)})
  129. // return
  130. // }
  131. // if ok, _ := regexp.MatchString(`^[\w@#*.]{4,30}$`, connection.Username); !ok {
  132. // c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
  133. // return
  134. // }
  135. // if !ip_helper.IsIPv4(connection.Host) && !ip_helper.IsIPv6(connection.Host) {
  136. // c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
  137. // return
  138. // }
  139. // if ok, _ := regexp.MatchString("^[0-9]{1,6}$", connection.Port); !ok {
  140. // c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.INVALID_PARAMS, Message: common_err.GetMsg(common_err.INVALID_PARAMS)})
  141. // return
  142. // }
  143. connection.Host = strings.Split(connection.Host, "/")[0]
  144. // check is exists
  145. connections := service.MyService.Connections().GetConnectionByHost(connection.Host)
  146. if len(connections) > 0 {
  147. 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)})
  148. return
  149. }
  150. // check connect is ok
  151. directories, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
  152. if err != nil {
  153. c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
  154. return
  155. }
  156. connectionDBModel := model2.ConnectionsDBModel{}
  157. connectionDBModel.Username = connection.Username
  158. connectionDBModel.Password = connection.Password
  159. connectionDBModel.Host = connection.Host
  160. connectionDBModel.Port = connection.Port
  161. connectionDBModel.Directories = strings.Join(directories, ",")
  162. baseHostPath := "/mnt/" + connection.Host
  163. connectionDBModel.MountPoint = baseHostPath
  164. connection.MountPoint = baseHostPath
  165. file.IsNotExistMkDir(baseHostPath)
  166. for _, v := range directories {
  167. mountPoint := baseHostPath + "/" + v
  168. file.IsNotExistMkDir(mountPoint)
  169. service.MyService.Connections().MountSmaba(connectionDBModel.Username, connectionDBModel.Host, v, connectionDBModel.Port, mountPoint, connectionDBModel.Password)
  170. }
  171. service.MyService.Connections().CreateConnection(&connectionDBModel)
  172. connection.ID = connectionDBModel.ID
  173. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: connection})
  174. }
  175. func DeleteSambaConnections(c *gin.Context) {
  176. id := c.Param("id")
  177. connection := service.MyService.Connections().GetConnectionByID(id)
  178. if connection.Username == "" {
  179. c.JSON(common_err.CLIENT_ERROR, model.Result{Success: common_err.Record_NOT_EXIST, Message: common_err.GetMsg(common_err.Record_NOT_EXIST)})
  180. return
  181. }
  182. mountPointList, err := samba.GetSambaSharesList(connection.Host, connection.Port, connection.Username, connection.Password)
  183. //mountPointList, err := service.MyService.System().GetDirPath(connection.MountPoint)
  184. if err != nil {
  185. c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
  186. return
  187. }
  188. baseHostPath := "/mnt/" + connection.Host
  189. for _, v := range mountPointList {
  190. if service.IsMounted(baseHostPath + "/" + v) {
  191. err := service.MyService.Connections().UnmountSmaba(baseHostPath + "/" + v)
  192. if err != nil {
  193. logger.Error("unmount smaba error", zap.Error(err), zap.Any("path", baseHostPath+"/"+v))
  194. c.JSON(common_err.SERVICE_ERROR, model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR), Data: err.Error()})
  195. return
  196. }
  197. }
  198. }
  199. dir, _ := ioutil.ReadDir(connection.MountPoint)
  200. if len(dir) == 0 {
  201. os.RemoveAll(connection.MountPoint)
  202. }
  203. service.MyService.Connections().DeleteConnection(id)
  204. c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: id})
  205. }