aofs.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package ftp
  2. //arozos virtual path translation handler
  3. //author: tobychui
  4. import (
  5. "errors"
  6. "fmt"
  7. "io/ioutil"
  8. "os"
  9. "path/filepath"
  10. "strings"
  11. "time"
  12. "github.com/spf13/afero"
  13. "imuslab.com/arozos/mod/filesystem"
  14. "imuslab.com/arozos/mod/user"
  15. )
  16. type aofs struct {
  17. userinfo *user.User
  18. tmpFolder string
  19. }
  20. func (a aofs) Create(name string) (afero.File, error) {
  21. /*
  22. rewritePath, _, err := a.pathRewrite(name)
  23. if err != nil {
  24. return nil, err
  25. }
  26. if !a.checkAllowAccess(rewritePath, "write") {
  27. return nil, errors.New("Permission Denied")
  28. }
  29. //log.Println("Create", rewritePath)
  30. fd, err := os.Create(rewritePath)
  31. if err != nil {
  32. return nil, err
  33. }
  34. return fd, nil
  35. */
  36. return nil, nil
  37. }
  38. func (a aofs) Chown(name string, uid, gid int) error {
  39. /*
  40. rewritePath, _, err := a.pathRewrite(name)
  41. if err != nil {
  42. return err
  43. }
  44. if !a.checkAllowAccess(rewritePath, "write") {
  45. return errors.New("Permission Denied")
  46. }
  47. return os.Chown(name, uid, gid)
  48. */
  49. return nil
  50. }
  51. func (a aofs) Mkdir(name string, perm os.FileMode) error {
  52. /*
  53. rewritePath, _, err := a.pathRewrite(name)
  54. if err != nil {
  55. return err
  56. }
  57. if !a.checkAllowAccess(rewritePath, "write") {
  58. return errors.New("Permission Denied")
  59. }
  60. os.Mkdir(rewritePath, perm)
  61. */
  62. return nil
  63. }
  64. func (a aofs) MkdirAll(path string, perm os.FileMode) error {
  65. /*
  66. rewritePath, _, err := a.pathRewrite(path)
  67. if err != nil {
  68. return err
  69. }
  70. if !a.checkAllowAccess(rewritePath, "write") {
  71. return errors.New("Permission Denied")
  72. }
  73. os.MkdirAll(rewritePath, perm)
  74. return nil
  75. */
  76. return nil
  77. }
  78. func (a aofs) Open(name string) (afero.File, error) {
  79. fmt.Println("FTP OPEN")
  80. /*
  81. rewritePath, _, err := a.pathRewrite(name)
  82. if err != nil {
  83. return nil, err
  84. }
  85. if !a.checkAllowAccess(rewritePath, "read") {
  86. return nil, errors.New("Permission Denied")
  87. }
  88. //log.Println("Open", name, rewritePath)
  89. fd, err := os.Open(rewritePath)
  90. if err != nil {
  91. return nil, err
  92. }
  93. return fd, nil
  94. */
  95. return nil, nil
  96. }
  97. func (a aofs) Stat(name string) (os.FileInfo, error) {
  98. fmt.Println("FTP STAT")
  99. /*
  100. rewritePath, _, err := a.pathRewrite(name)
  101. if err != nil {
  102. return nil, err
  103. }
  104. if !a.checkAllowAccess(rewritePath, "read") {
  105. return nil, errors.New("Permission Denied")
  106. }
  107. //log.Println("Stat", rewritePath)
  108. fileStat, err := os.Stat(rewritePath)
  109. return fileStat, err
  110. */
  111. return nil, nil
  112. }
  113. func (a aofs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) {
  114. fmt.Println("FTP OPEN FILE")
  115. /*
  116. rewritePath, _, err := a.pathRewrite(name)
  117. if err != nil {
  118. return nil, err
  119. }
  120. //log.Println("OpenFile", rewritePath)
  121. if !fileExists(rewritePath) {
  122. if !a.checkAllowAccess(rewritePath, "write") {
  123. return nil, errors.New("Directory is Read Only")
  124. }
  125. //Set ownership of this file to user.
  126. //Cannot use SetOwnership due to the filesize of the given file didn't exists yet
  127. fsh, _ := a.userinfo.GetFileSystemHandlerFromRealPath(rewritePath)
  128. fsh.CreateFileRecord(rewritePath, a.userinfo.Username)
  129. //Create the upload pending file
  130. fd, err := os.Create(rewritePath)
  131. if err != nil {
  132. return nil, err
  133. }
  134. return fd, nil
  135. } else {
  136. if !a.checkAllowAccess(rewritePath, "read") {
  137. return nil, errors.New("Permission Denied")
  138. }
  139. fd, err := os.Open(rewritePath)
  140. if err != nil {
  141. return nil, err
  142. }
  143. return fd, nil
  144. }
  145. */
  146. return nil, nil
  147. }
  148. func (a aofs) AllocateSpace(size int) error {
  149. if a.userinfo.StorageQuota.HaveSpace(int64(size)) {
  150. return nil
  151. }
  152. return errors.New("Storage Quota Fulled")
  153. }
  154. func (a aofs) Remove(name string) error {
  155. /*
  156. rewritePath, _, err := a.pathRewrite(name)
  157. if err != nil {
  158. return err
  159. }
  160. if !a.checkAllowAccess(rewritePath, "write") {
  161. return errors.New("Target is Read Only")
  162. }
  163. isHiddenFile, _ := hidden.IsHidden(rewritePath, true)
  164. if isHiddenFile {
  165. //Hidden files, include cache or trash
  166. return errors.New("Access denied for hidden files")
  167. }
  168. log.Println(a.userinfo.Username + " removed " + rewritePath + " via FTP endpoint")
  169. os.MkdirAll(filepath.Dir(rewritePath)+"/.metadata/.trash/", 0755)
  170. os.Rename(rewritePath, filepath.Dir(rewritePath)+"/.metadata/.trash/"+filepath.Base(rewritePath)+"."+strconv.Itoa(int(time.Now().Unix())))
  171. */
  172. return nil
  173. }
  174. func (a aofs) RemoveAll(path string) error {
  175. /*
  176. rewritePath, _, err := a.pathRewrite(path)
  177. if err != nil {
  178. return err
  179. }
  180. //log.Println("RemoveAll", rewritePath)
  181. isHiddenFile, _ := hidden.IsHidden(rewritePath, true)
  182. if isHiddenFile {
  183. //Hidden files, include cache or trash
  184. return errors.New("Target is Read Only")
  185. }
  186. if !a.checkAllowAccess(rewritePath, "write") {
  187. return errors.New("Permission Denied")
  188. }
  189. os.MkdirAll(filepath.Dir(rewritePath)+"/.metadata/.trash/", 0755)
  190. os.Rename(rewritePath, filepath.Dir(rewritePath)+"/.metadata/.trash/"+filepath.Base(rewritePath)+"."+strconv.Itoa(int(time.Now().Unix())))
  191. */
  192. return nil
  193. }
  194. func (a aofs) Rename(oldname, newname string) error {
  195. return nil
  196. }
  197. func (a aofs) Name() string {
  198. return "arozos virtualFS"
  199. }
  200. func (a aofs) Chmod(name string, mode os.FileMode) error {
  201. //log.Println("Chmod", name, mode)
  202. return nil
  203. }
  204. func (a aofs) Chtimes(name string, atime time.Time, mtime time.Time) error {
  205. //log.Println("Chtimes", name, atime, mtime)
  206. return nil
  207. }
  208. //arozos adaptive functions
  209. //This function rewrite the path from ftp representation to real filepath on disk
  210. func (a aofs) pathRewrite(path string) (*filesystem.FileSystemHandler, string, error) {
  211. path = filepath.ToSlash(filepath.Clean(path))
  212. //log.Println("Original path: ", path)
  213. if path == "/" {
  214. //Roots. Show ftpbuf root
  215. fsHandlers := a.userinfo.GetAllFileSystemHandler()
  216. for _, fsh := range fsHandlers {
  217. //Create a folder representation for this virtual directory
  218. if !(fsh.Hierarchy == "backup") {
  219. os.Mkdir(a.tmpFolder+fsh.UUID, 0755)
  220. }
  221. }
  222. readmeContent, err := ioutil.ReadFile("./system/ftp/README.txt")
  223. if err != nil {
  224. readmeContent = []byte("DO NOT UPLOAD FILES INTO THE ROOT DIRECTORY")
  225. }
  226. ioutil.WriteFile(a.tmpFolder+"README.txt", readmeContent, 0755)
  227. //Return the tmpFolder root
  228. tmpfs, _ := a.userinfo.GetFileSystemHandlerFromVirtualPath("tmp:/")
  229. return tmpfs, a.tmpFolder, nil
  230. } else if path == "/README.txt" {
  231. tmpfs, _ := a.userinfo.GetFileSystemHandlerFromVirtualPath("tmp:/")
  232. return tmpfs, a.tmpFolder + "README.txt", nil
  233. } else if len(path) > 0 {
  234. //Rewrite the path for any alternative filepath
  235. //Get the uuid of the filepath
  236. path := path[1:]
  237. subpaths := strings.Split(path, "/")
  238. fsHandlerUUID := subpaths[0]
  239. remainingPaths := subpaths[1:]
  240. //Look for the fsHandler with this UUID
  241. fsHandlers := a.userinfo.GetAllFileSystemHandler()
  242. for _, fsh := range fsHandlers {
  243. //Create a folder representation for this virtual directory
  244. if fsh.UUID == fsHandlerUUID {
  245. //This is the correct handler
  246. if fsh.Hierarchy == "user" {
  247. return fsh, filepath.ToSlash(filepath.Clean(fsh.Path)) + "/users/" + a.userinfo.Username + "/" + strings.Join(remainingPaths, "/"), nil
  248. } else if fsh.Hierarchy == "public" {
  249. return fsh, filepath.ToSlash(filepath.Clean(fsh.Path)) + "/" + strings.Join(remainingPaths, "/"), nil
  250. }
  251. }
  252. }
  253. //fsh not found.
  254. return nil, "", errors.New("Path is READ ONLY")
  255. } else {
  256. //fsh not found.
  257. return nil, "", errors.New("Invalid path")
  258. }
  259. }
  260. //Check if user has access to the given path, mode can be string {read / write}
  261. func (a aofs) checkAllowAccess(fsh *filesystem.FileSystemHandler, path string, mode string) bool {
  262. return true
  263. }