network.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net/http"
  6. "strconv"
  7. "strings"
  8. "imuslab.com/arozos/mod/fileservers"
  9. "imuslab.com/arozos/mod/fileservers/servers/dirserv"
  10. "imuslab.com/arozos/mod/fileservers/servers/ftpserv"
  11. "imuslab.com/arozos/mod/fileservers/servers/nfsserv"
  12. "imuslab.com/arozos/mod/fileservers/servers/samba"
  13. "imuslab.com/arozos/mod/fileservers/servers/sftpserv"
  14. "imuslab.com/arozos/mod/fileservers/servers/webdavserv"
  15. network "imuslab.com/arozos/mod/network"
  16. mdns "imuslab.com/arozos/mod/network/mdns"
  17. "imuslab.com/arozos/mod/network/netstat"
  18. ssdp "imuslab.com/arozos/mod/network/ssdp"
  19. upnp "imuslab.com/arozos/mod/network/upnp"
  20. "imuslab.com/arozos/mod/network/websocket"
  21. prout "imuslab.com/arozos/mod/prouter"
  22. "imuslab.com/arozos/mod/utils"
  23. "imuslab.com/arozos/mod/www"
  24. )
  25. var (
  26. //Network Services Managers
  27. MDNS *mdns.MDNSHost
  28. UPNP *upnp.UPnPClient
  29. SSDP *ssdp.SSDPHost
  30. WebSocketRouter *websocket.Router
  31. //File Server Managers
  32. FTPManager *ftpserv.Manager
  33. WebDAVManager *webdavserv.Manager
  34. SFTPManager *sftpserv.Manager
  35. NFSManager *nfsserv.Manager
  36. SambaShareManager *samba.ShareManager
  37. DirListManager *dirserv.Manager
  38. )
  39. func NetworkServiceInit() {
  40. systemWideLogger.PrintAndLog("Network", "Starting ArOZ Network Services", nil)
  41. //Create a router that allow users with System Setting access to access these api endpoints
  42. router := prout.NewModuleRouter(prout.RouterOption{
  43. ModuleName: "System Setting",
  44. AdminOnly: false,
  45. UserHandler: userHandler,
  46. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  47. utils.SendErrorResponse(w, "Permission Denied")
  48. },
  49. })
  50. /*
  51. Standard Network Utilties
  52. */
  53. //Register handler endpoints
  54. if *allow_hardware_management {
  55. router.HandleFunc("/system/network/getNICinfo", network.GetNICInfo)
  56. router.HandleFunc("/system/network/getPing", network.GetPing)
  57. //Register as a system setting
  58. registerSetting(settingModule{
  59. Name: "Network Info",
  60. Desc: "Network Information",
  61. IconPath: "SystemAO/network/img/ethernet.png",
  62. Group: "Network",
  63. StartDir: "SystemAO/network/hardware.html",
  64. })
  65. }
  66. router.HandleFunc("/system/network/getNICUsage", netstat.HandleGetNetworkInterfaceStats)
  67. //Start the services that depends on network interface
  68. StartNetworkServices()
  69. //Start the port forward configuration interface
  70. portForwardInit()
  71. //Start userhomepage if enabled
  72. //Handle user webroot routings if homepage is enabled
  73. if *allow_homepage {
  74. userWwwHandler = www.NewWebRootHandler(www.Options{
  75. UserHandler: userHandler,
  76. Database: sysdb,
  77. AgiGateway: AGIGateway,
  78. })
  79. router.HandleFunc("/system/network/www/toggle", userWwwHandler.HandleToggleHomepage)
  80. router.HandleFunc("/system/network/www/webRoot", userWwwHandler.HandleSetWebRoot)
  81. //Register as a system setting
  82. registerSetting(settingModule{
  83. Name: "Personal Page",
  84. Desc: "Personal Web Page",
  85. IconPath: "SystemAO/www/img/homepage.png",
  86. Group: "Network",
  87. StartDir: "SystemAO/www/config.html",
  88. })
  89. }
  90. userRouter := prout.NewModuleRouter(prout.RouterOption{
  91. AdminOnly: false,
  92. UserHandler: userHandler,
  93. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  94. utils.SendErrorResponse(w, "Permission Denied")
  95. },
  96. })
  97. WebSocketRouter = websocket.NewRouter()
  98. userRouter.HandleFunc("/system/ws", WebSocketRouter.HandleWebSocketRouting)
  99. }
  100. func StartNetworkServices() {
  101. /*
  102. MDNS Services
  103. */
  104. if *allow_mdns {
  105. m, err := mdns.NewMDNS(mdns.NetworkHost{
  106. HostName: *host_name + "_" + deviceUUID, //To handle more than one identical model within the same network, this must be unique
  107. Port: *listen_port,
  108. Domain: "arozos.com",
  109. Model: deviceModel,
  110. UUID: deviceUUID,
  111. Vendor: deviceVendor,
  112. BuildVersion: build_version,
  113. MinorVersion: internal_version,
  114. }, *force_mac)
  115. if err != nil {
  116. systemWideLogger.PrintAndLog("Network", "MDNS Startup Failed. Running in Offline Mode.", err)
  117. } else {
  118. MDNS = m
  119. }
  120. }
  121. /*
  122. SSDP Discovery Services
  123. */
  124. if *allow_ssdp {
  125. //Get outbound ip
  126. obip, err := network.GetOutboundIP()
  127. if err != nil {
  128. systemWideLogger.PrintAndLog("Network", "SSDP Startup Failed. Running in Offline Mode.", err)
  129. } else {
  130. thisIp := obip.String()
  131. adv, err := ssdp.NewSSDPHost(thisIp, *listen_port, "system/ssdp.xml", ssdp.SSDPOption{
  132. URLBase: "http://" + thisIp + ":" + strconv.Itoa(*listen_port), //This must be http if used as local hosting devices
  133. Hostname: *host_name,
  134. Vendor: deviceVendor,
  135. VendorURL: deviceVendorURL,
  136. ModelName: deviceModel,
  137. ModelDesc: deviceModelDesc,
  138. UUID: deviceUUID,
  139. Serial: "generic",
  140. })
  141. if err != nil {
  142. systemWideLogger.PrintAndLog("Network", "SSDP Startup Failed. Running in Offline Mode.", err)
  143. } else {
  144. //OK! Start SSDP Service
  145. SSDP = adv
  146. SSDP.Start()
  147. }
  148. }
  149. }
  150. /*
  151. UPNP / Setup automatic port forwarding
  152. */
  153. if *allow_upnp {
  154. var u *upnp.UPnPClient
  155. var err error = nil
  156. if *use_tls {
  157. u, err = upnp.NewUPNPClient(*tls_listen_port, *host_name+"-https")
  158. } else {
  159. u, err = upnp.NewUPNPClient(*listen_port, *host_name+"-http")
  160. }
  161. if err != nil {
  162. systemWideLogger.PrintAndLog("Network", "UPnP Startup Failed: "+err.Error(), err)
  163. } else {
  164. //Bind the http port if running in https and http server is not disabled
  165. if *use_tls && !*disable_http {
  166. u.ForwardPort(*listen_port, *host_name+"-http")
  167. }
  168. UPNP = u
  169. //Register nightly listener for upnp renew
  170. nightlyManager.RegisterNightlyTask(func() {
  171. UPNP.RenewForwardRules()
  172. })
  173. //Show a tip for success port forward
  174. connectionEndpoint := UPNP.ExternalIP + ":" + strconv.Itoa(*listen_port)
  175. obip, err := network.GetOutboundIP()
  176. obipstring := "[Outbound IP]"
  177. if err != nil {
  178. } else {
  179. obipstring = obip.String()
  180. }
  181. localEndpoint := obipstring + ":" + strconv.Itoa(*listen_port)
  182. systemWideLogger.PrintAndLog("Network", "Automatic Port Forwarding Completed. Forwarding all request from "+connectionEndpoint+" to "+localEndpoint, nil)
  183. }
  184. }
  185. }
  186. func StopNetworkServices() {
  187. //systemWideLogger.PrintAndLog("Shutting Down Network Services...",nil)
  188. //Shutdown uPNP service if enabled
  189. if *allow_upnp {
  190. systemWideLogger.PrintAndLog("System", "<!> Shutting down uPNP service", nil)
  191. UPNP.Close()
  192. }
  193. //Shutdown SSDP service if enabled
  194. if *allow_ssdp {
  195. systemWideLogger.PrintAndLog("System", "<!> Shutting down SSDP service", nil)
  196. SSDP.Close()
  197. }
  198. //Shutdown MDNS if enabled
  199. if *allow_mdns {
  200. systemWideLogger.PrintAndLog("System", "<!> Shutting down MDNS service", nil)
  201. MDNS.Close()
  202. }
  203. }
  204. /*
  205. File Server Services
  206. */
  207. var networkFileServerDaemon []*fileservers.Server = []*fileservers.Server{}
  208. // Initiate all File Server services
  209. func FileServerInit() {
  210. //Register System Setting
  211. registerSetting(settingModule{
  212. Name: "File Servers",
  213. Desc: "Network File Transfer Servers",
  214. IconPath: "SystemAO/disk/smart/img/small_icon.png",
  215. Group: "Network",
  216. StartDir: "SystemAO/disk/services.html",
  217. RequireAdmin: false,
  218. })
  219. //Create request routers
  220. adminRouter := prout.NewModuleRouter(prout.RouterOption{
  221. ModuleName: "System Setting",
  222. AdminOnly: true,
  223. UserHandler: userHandler,
  224. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  225. errorHandlePermissionDenied(w, r)
  226. },
  227. })
  228. router := prout.NewModuleRouter(prout.RouterOption{
  229. ModuleName: "System Setting",
  230. AdminOnly: false,
  231. UserHandler: userHandler,
  232. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  233. utils.SendErrorResponse(w, "Permission Denied")
  234. },
  235. })
  236. /* Create File Server Managers */
  237. //WebDAV
  238. webdavPort := *listen_port
  239. if *use_tls {
  240. webdavPort = *tls_listen_port
  241. }
  242. WebDAVManager = webdavserv.NewWebDAVManager(&webdavserv.ManagerOption{
  243. Sysdb: sysdb,
  244. Hostname: *host_name,
  245. TmpDir: *tmp_directory,
  246. Port: webdavPort,
  247. UseTls: *use_tls,
  248. UserHandler: userHandler,
  249. })
  250. //FTP
  251. FTPManager = ftpserv.NewFTPManager(&ftpserv.ManagerOption{
  252. Hostname: *host_name,
  253. TmpFolder: *tmp_directory,
  254. Logger: systemWideLogger,
  255. UserManager: userHandler,
  256. FtpServer: nil,
  257. Sysdb: sysdb,
  258. Upnp: UPNP,
  259. AllowUpnp: *allow_upnp,
  260. })
  261. //SFTP
  262. SFTPManager = sftpserv.NewSFTPServer(&sftpserv.ManagerOption{
  263. Hostname: *host_name,
  264. Upnp: UPNP,
  265. UserManager: userHandler,
  266. KeyFile: "system/auth/id_rsa.key",
  267. Logger: systemWideLogger,
  268. Sysdb: sysdb,
  269. })
  270. listeningPort := *listen_port
  271. if *use_tls {
  272. listeningPort = *tls_listen_port
  273. }
  274. DirListManager = dirserv.NewDirectoryServer(&dirserv.Option{
  275. Sysdb: sysdb,
  276. ServerPort: listeningPort,
  277. UserManager: userHandler,
  278. ServerUUID: deviceUUID,
  279. })
  280. //NFS
  281. /*
  282. NFSManager = nfsserv.NewNfsServer(nfsserv.Option{
  283. UserManager: userHandler,
  284. ListeningPort: 2049,
  285. AllowAccessGroup: []*permission.PermissionGroup{},
  286. Logger: nil,
  287. })
  288. err := NFSManager.Start()
  289. if err != nil {
  290. fmt.Println(err.Error())
  291. }
  292. */
  293. //Samba
  294. var err error
  295. SambaShareManager, err = samba.NewSambaShareManager(userHandler)
  296. if err != nil {
  297. //Disable samba if not installed or platform not supported
  298. log.Println("[INFO] Samba Share Manager Disabled: " + err.Error())
  299. }
  300. //Register Endpoints
  301. //WebDAV
  302. http.HandleFunc("/system/network/webdav/list", WebDAVManager.HandleConnectionList)
  303. router.HandleFunc("/system/network/webdav/edit", WebDAVManager.HandlePermissionEdit)
  304. router.HandleFunc("/system/network/webdav/clear", WebDAVManager.HandleClearAllPending)
  305. router.HandleFunc("/system/network/webdav/status", WebDAVManager.HandleStatusChange)
  306. //SFTP
  307. adminRouter.HandleFunc("/system/storage/sftp/port", SFTPManager.HandleListeningPort)
  308. adminRouter.HandleFunc("/system/storage/sftp/upnp", SFTPManager.HandleToogleUPnP)
  309. adminRouter.HandleFunc("/system/storage/sftp/users", SFTPManager.HandleGetConnectedClients)
  310. //FTP
  311. //adminRouter.HandleFunc("/system/storage/ftp/start", FTPManager.HandleFTPServerStart)
  312. //adminRouter.HandleFunc("/system/storage/ftp/stop", FTPManager.HandleFTPServerStop)
  313. adminRouter.HandleFunc("/system/storage/ftp/upnp", FTPManager.HandleFTPUPnP)
  314. adminRouter.HandleFunc("/system/storage/ftp/status", FTPManager.HandleFTPServerStatus)
  315. adminRouter.HandleFunc("/system/storage/ftp/updateGroups", FTPManager.HandleFTPAccessUpdate)
  316. adminRouter.HandleFunc("/system/storage/ftp/setPort", FTPManager.HandleFTPSetPort)
  317. adminRouter.HandleFunc("/system/storage/ftp/passivemode", FTPManager.HandleFTPPassiveModeSettings)
  318. //Samba Shares (Optional)
  319. if SambaShareManager != nil {
  320. //Activate and Deactivate are functions all users can use if admin enabled smbd service
  321. router.HandleFunc("/system/storage/samba/activate", func(w http.ResponseWriter, r *http.Request) {
  322. if !AuthValidateSecureRequest(w, r, false) {
  323. return
  324. }
  325. if !SambaShareManager.IsEnabled() {
  326. utils.SendErrorResponse(w, "smbd is not enabled on this server")
  327. return
  328. }
  329. password, _ := utils.PostPara(r, "password")
  330. SambaShareManager.ActivateUserAccount(w, r, password)
  331. })
  332. adminRouter.HandleFunc("/system/storage/samba/deactivate", SambaShareManager.DeactiveUserAccount)
  333. adminRouter.HandleFunc("/system/storage/samba/myshare", SambaShareManager.HandleUserSmbStatusList)
  334. //adminRouter.HandleFunc("/system/storage/samba/myshare/delete", SambaShareManager.DelUserSambaShare)
  335. adminRouter.HandleFunc("/system/storage/samba/status", SambaShareManager.SmbdStates)
  336. adminRouter.HandleFunc("/system/storage/samba/list", SambaShareManager.ListSambaShares)
  337. adminRouter.HandleFunc("/system/storage/samba/add", SambaShareManager.AddSambaShare)
  338. adminRouter.HandleFunc("/system/storage/samba/editPath", SambaShareManager.HandleSharePathChange)
  339. adminRouter.HandleFunc("/system/storage/samba/remove", SambaShareManager.DelSambaShare)
  340. adminRouter.HandleFunc("/system/storage/samba/addUser", SambaShareManager.NewSambaUser)
  341. adminRouter.HandleFunc("/system/storage/samba/delUser", SambaShareManager.DelSambaUser)
  342. adminRouter.HandleFunc("/system/storage/samba/listUsers", SambaShareManager.ListSambaUsers)
  343. adminRouter.HandleFunc("/system/storage/samba/updateShareUsers", SambaShareManager.HandleAccessUserUpdate)
  344. }
  345. networkFileServerDaemon = append(networkFileServerDaemon, &fileservers.Server{
  346. ID: "webdav",
  347. Name: "WebDAV",
  348. Desc: "WebDAV Server",
  349. IconPath: "img/system/network-folder-blue.svg",
  350. DefaultPorts: []int{},
  351. Ports: []int{},
  352. ForwardPortIfUpnp: false,
  353. ConnInstrPage: "SystemAO/disk/instr/webdav.html",
  354. ConfigPage: "SystemAO/disk/webdav.html",
  355. EnableCheck: WebDAVManager.GetWebDavEnabled,
  356. ToggleFunc: WebDAVManager.WebDavToogle,
  357. GetEndpoints: WebDAVManager.WebDavGetEndpoints,
  358. })
  359. networkFileServerDaemon = append(networkFileServerDaemon, &fileservers.Server{
  360. ID: "sftp",
  361. Name: "SFTP",
  362. Desc: "SSH File Transfer Protocol Server",
  363. IconPath: "img/system/network-folder-sftp.svg",
  364. DefaultPorts: []int{2022},
  365. Ports: []int{},
  366. ForwardPortIfUpnp: true,
  367. ConnInstrPage: "SystemAO/disk/instr/sftp.html",
  368. ConfigPage: "SystemAO/disk/sftp.html",
  369. EnableCheck: SFTPManager.IsEnabled,
  370. ToggleFunc: SFTPManager.ServerToggle,
  371. GetEndpoints: SFTPManager.GetEndpoints,
  372. })
  373. networkFileServerDaemon = append(networkFileServerDaemon, &fileservers.Server{
  374. ID: "ftp",
  375. Name: "FTP",
  376. Desc: "File Transfer Protocol Server",
  377. IconPath: "img/system/network-folder.svg",
  378. DefaultPorts: []int{21, 22, 23},
  379. Ports: []int{},
  380. ForwardPortIfUpnp: true,
  381. ConnInstrPage: "SystemAO/disk/instr/ftp.html",
  382. ConfigPage: "SystemAO/disk/ftp.html",
  383. EnableCheck: FTPManager.IsFtpServerEnabled,
  384. ToggleFunc: FTPManager.FTPServerToggle,
  385. GetEndpoints: FTPManager.FTPGetEndpoints,
  386. })
  387. networkFileServerDaemon = append(networkFileServerDaemon, &fileservers.Server{
  388. ID: "dirserv",
  389. Name: "Directory Server",
  390. Desc: "Web file viewer for legacy devices",
  391. IconPath: "img/system/network-dirserv.svg",
  392. DefaultPorts: []int{},
  393. Ports: []int{},
  394. ForwardPortIfUpnp: false,
  395. ConnInstrPage: "SystemAO/disk/instr/dirserv.html",
  396. ConfigPage: "SystemAO/disk/dirserv.html",
  397. EnableCheck: DirListManager.DirServerEnabled,
  398. ToggleFunc: DirListManager.Toggle,
  399. GetEndpoints: DirListManager.ListEndpoints,
  400. })
  401. if SambaShareManager != nil {
  402. //Samba is external and might not exists on this host
  403. networkFileServerDaemon = append(networkFileServerDaemon, &fileservers.Server{
  404. ID: "smbd",
  405. Name: "Samba Shares",
  406. Desc: "Share local files via SMB using Samba",
  407. IconPath: "img/system/network-samba.svg",
  408. DefaultPorts: []int{},
  409. Ports: []int{},
  410. ForwardPortIfUpnp: false,
  411. ConnInstrPage: "SystemAO/disk/instr/samba.html",
  412. ConfigPage: "SystemAO/disk/samba.html",
  413. EnableCheck: SambaShareManager.IsEnabled,
  414. ToggleFunc: SambaShareManager.ServerToggle,
  415. GetEndpoints: SambaShareManager.GetEndpoints,
  416. })
  417. }
  418. router.HandleFunc("/system/network/server/list", NetworkHandleGetFileServerServiceList)
  419. router.HandleFunc("/system/network/server/endpoints", NetworkHandleGetFileServerEndpoints)
  420. router.HandleFunc("/system/network/server/status", NetworkHandleGetFileServerStatus)
  421. adminRouter.HandleFunc("/system/network/server/toggle", NetworkHandleFileServerToggle)
  422. }
  423. // Toggle the target File Server Services
  424. func NetworkHandleFileServerToggle(w http.ResponseWriter, r *http.Request) {
  425. servid, err := utils.PostPara(r, "id")
  426. if err != nil {
  427. utils.SendErrorResponse(w, "invalid service id given")
  428. return
  429. }
  430. newState, err := utils.PostPara(r, "enable")
  431. if err != nil {
  432. utils.SendErrorResponse(w, "undefined enable state")
  433. return
  434. }
  435. targetfserv := fileservers.GetFileServerById(networkFileServerDaemon, servid)
  436. if targetfserv == nil {
  437. utils.SendErrorResponse(w, "target service not exists")
  438. return
  439. }
  440. if newState == "true" {
  441. //Start up the target service
  442. err = targetfserv.ToggleFunc(true)
  443. if err != nil {
  444. utils.SendErrorResponse(w, "startup failed: "+err.Error())
  445. return
  446. }
  447. } else if newState == "false" {
  448. err = targetfserv.ToggleFunc(false)
  449. if err != nil {
  450. utils.SendErrorResponse(w, "shutdown failed: "+err.Error())
  451. return
  452. }
  453. } else {
  454. utils.SendErrorResponse(w, "unknown state keyword")
  455. return
  456. }
  457. }
  458. // Return a list of supported File Server Services
  459. func NetworkHandleGetFileServerServiceList(w http.ResponseWriter, r *http.Request) {
  460. js, _ := json.Marshal(networkFileServerDaemon)
  461. utils.SendJSONResponse(w, string(js))
  462. }
  463. // Get the status of a file server type.
  464. func NetworkHandleGetFileServerStatus(w http.ResponseWriter, r *http.Request) {
  465. servid, _ := utils.GetPara(r, "id")
  466. if servid == "" {
  467. //List all state in map
  468. result := map[string]bool{}
  469. for _, fserv := range networkFileServerDaemon {
  470. result[fserv.ID] = fserv.EnableCheck()
  471. }
  472. js, _ := json.Marshal(result)
  473. utils.SendJSONResponse(w, string(js))
  474. } else {
  475. //ID is defined. Get the target server and return its status
  476. targetfserv := fileservers.GetFileServerById(networkFileServerDaemon, servid)
  477. if targetfserv == nil {
  478. utils.SendErrorResponse(w, "target file server type not found")
  479. return
  480. }
  481. js, _ := json.Marshal(targetfserv.EnableCheck())
  482. utils.SendJSONResponse(w, string(js))
  483. }
  484. }
  485. // Get a list of endpoint usable by this service
  486. func NetworkHandleGetFileServerEndpoints(w http.ResponseWriter, r *http.Request) {
  487. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  488. if err != nil {
  489. utils.SendErrorResponse(w, "user not logged in")
  490. return
  491. }
  492. targetServerTypeID, _ := utils.GetPara(r, "fserv")
  493. targetServerTypeID = strings.TrimSpace(targetServerTypeID)
  494. if targetServerTypeID == "" {
  495. //List all the endpoints
  496. results := map[string][]*fileservers.Endpoint{}
  497. for _, fser := range networkFileServerDaemon {
  498. if fser.GetEndpoints == nil {
  499. results[fser.ID] = []*fileservers.Endpoint{}
  500. continue
  501. }
  502. thisEndpoints := fser.GetEndpoints(userinfo)
  503. results[fser.ID] = thisEndpoints
  504. }
  505. js, _ := json.Marshal(results)
  506. utils.SendJSONResponse(w, string(js))
  507. } else {
  508. //List the target endpoint
  509. for _, fser := range networkFileServerDaemon {
  510. if targetServerTypeID == fser.ID {
  511. thisEndpoints := fser.GetEndpoints(userinfo)
  512. js, _ := json.Marshal(thisEndpoints)
  513. utils.SendJSONResponse(w, string(js))
  514. return
  515. }
  516. }
  517. utils.SendErrorResponse(w, "target service not found")
  518. }
  519. }