directoryHandler.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package user
  2. import (
  3. "errors"
  4. "os"
  5. "path/filepath"
  6. fs "imuslab.com/arozos/mod/filesystem"
  7. )
  8. func (u *User) GetHomeDirectory() (string, error) {
  9. //Return the realpath of the user home directory
  10. for _, dir := range u.HomeDirectories.Storages {
  11. if dir.UUID == "user" {
  12. //This is the target user root
  13. root := filepath.ToSlash(filepath.Clean(dir.Path) + "/users/" + u.Username + "/")
  14. os.MkdirAll(root, 0755)
  15. return root, nil
  16. }
  17. }
  18. return "", errors.New("User root not found. Is this a permission group instead of a real user?")
  19. }
  20. //Get all user Acessible file system handlers (ignore special fsh like backups)
  21. func (u *User) GetAllAccessibleFileSystemHandler() []*fs.FileSystemHandler {
  22. results := []*fs.FileSystemHandler{}
  23. fshs := u.GetAllFileSystemHandler()
  24. for _, fsh := range fshs {
  25. if fsh.Hierarchy != "backup" {
  26. results = append(results, fsh)
  27. }
  28. }
  29. return results
  30. }
  31. func (u *User) GetAllFileSystemHandler() []*fs.FileSystemHandler {
  32. results := []*fs.FileSystemHandler{}
  33. uuids := []string{}
  34. //Get all FileSystem Handler from this user's Home Directory (aka base directory)
  35. for _, store := range u.HomeDirectories.Storages {
  36. if store.Closed == false {
  37. //Only return opened file system handlers
  38. results = append(results, store)
  39. uuids = append(uuids, store.UUID)
  40. }
  41. }
  42. //Get all the FileSystem handler that is accessable by this user
  43. for _, pg := range u.PermissionGroup {
  44. //For each permission group that this user is in
  45. for _, store := range pg.StoragePool.Storages {
  46. //Get each of the storage of this permission group is assigned to
  47. if !inSlice(uuids, store.UUID) {
  48. if store.Closed == false {
  49. //Only return opened file system handlers
  50. results = append(results, store)
  51. uuids = append(uuids, store.UUID)
  52. }
  53. }
  54. }
  55. }
  56. return results
  57. }
  58. func (u *User) VirtualPathToRealPath(vpath string) (string, error) {
  59. //Get all usable filesystem handler from the user's home directory and permission groups
  60. userFsHandlers := u.GetAllFileSystemHandler()
  61. //Clear the path
  62. virtualPath := filepath.ToSlash(filepath.Clean(vpath))
  63. //Check for path escape
  64. if len(virtualPath) > 2 && virtualPath[:2] == ".." {
  65. return "", errors.New("Request path out of storage root")
  66. }
  67. //Check for valid virtual device id
  68. vid, subpath, err := getIDFromVirtualPath(vpath)
  69. if err != nil {
  70. return "", err
  71. }
  72. //Look for the handler with the same virtualPath ID
  73. for _, storage := range userFsHandlers {
  74. if storage.UUID == vid {
  75. //This storage is the one we are looking at
  76. //Check if this has been closed
  77. if storage.Closed == true {
  78. return "", errors.New("Request Filesystem Handler has been closed by another process")
  79. }
  80. //Check if this is a backup drive
  81. if storage.Hierarchy == "backup" {
  82. return "", errors.New("Request Filesystem Handler do not allow direct access")
  83. }
  84. //Handle general cases
  85. if storage.Hierarchy == "user" {
  86. return filepath.ToSlash(filepath.Clean(storage.Path) + "/users/" + u.Username + subpath), nil
  87. } else if storage.Hierarchy == "public" {
  88. return filepath.ToSlash(filepath.Clean(storage.Path) + subpath), nil
  89. } else {
  90. return "", errors.New("Unknown Filesystem Handler Hierarchy")
  91. }
  92. }
  93. }
  94. return "", errors.New("Translation failed: Vitrual storage ID not found")
  95. }
  96. func (u *User) RealPathToVirtualPath(rpath string) (string, error) {
  97. //Get all usable filesystem handler
  98. userFsHandlers := u.GetAllFileSystemHandler()
  99. //Clear the path
  100. realPath := filepath.ToSlash(filepath.Clean(rpath))
  101. //Check for path escape
  102. if len(realPath) > 2 && realPath[:2] == ".." {
  103. //Fix: 20 May 2021: Allow using ../folder as virtual root directory
  104. //Check if there are vroots that actually use relative path as root directory.
  105. allowSpecialCasePassThrough := false
  106. for _, fsh := range userFsHandlers {
  107. thisVrootPath := fsh.Path
  108. if len(realPath) > len(thisVrootPath) && filepath.ToSlash(realPath[:len(thisVrootPath)]) == filepath.ToSlash(thisVrootPath) {
  109. allowSpecialCasePassThrough = true
  110. }
  111. }
  112. if !allowSpecialCasePassThrough {
  113. return "", errors.New("Request path out of storage root")
  114. }
  115. }
  116. //Look for a real path of a virtual device that the realpath is containing
  117. for _, storage := range userFsHandlers {
  118. thisStorageRoot := filepath.Clean(filepath.ToSlash(storage.Path))
  119. thisStorageRootAbs, err := filepath.Abs(thisStorageRoot)
  120. if err != nil {
  121. //Fail to abs this path. Maybe this is a emulated file system?
  122. thisStorageRootAbs = thisStorageRoot
  123. }
  124. thisStorageRootAbs = filepath.ToSlash(filepath.Clean(thisStorageRootAbs))
  125. pathContained := false
  126. subPath := ""
  127. if len(realPath) > len(thisStorageRoot) && filepath.ToSlash(realPath[:len(thisStorageRoot)]) == filepath.ToSlash(thisStorageRoot) {
  128. //This realpath is in contained inside this storage root
  129. pathContained = true
  130. subtractionPath := thisStorageRoot
  131. if storage.Hierarchy == "user" {
  132. //Check if this file is belongs to this user
  133. startOffset := len(filepath.Clean(thisStorageRoot) + "/users/")
  134. if len(realPath) < startOffset+len(u.Username) {
  135. //This file is not owned by this user
  136. return "", errors.New("File not owned by this user")
  137. } else {
  138. userNameMatch := realPath[startOffset : startOffset+len(u.Username)]
  139. if userNameMatch != u.Username {
  140. //This file is not owned by this user
  141. return "", errors.New("File not owned by this user")
  142. }
  143. }
  144. //Generate subtraction path
  145. subtractionPath = thisStorageRoot + "/users/" + u.Username + "/"
  146. }
  147. if len(subtractionPath) < len(realPath) {
  148. subPath = realPath[len(subtractionPath):]
  149. }
  150. } else if len(realPath) > len(thisStorageRootAbs) && filepath.ToSlash(realPath[:len(thisStorageRootAbs)]) == filepath.ToSlash(thisStorageRootAbs) {
  151. //The realpath contains the absolute path of this storage root
  152. pathContained = true
  153. subtractionPath := thisStorageRootAbs
  154. if storage.Hierarchy == "user" {
  155. subtractionPath = thisStorageRootAbs + "/users/" + u.Username + "/"
  156. }
  157. if len(subtractionPath) < len(realPath) {
  158. subPath = realPath[len(subtractionPath):]
  159. }
  160. } else if filepath.ToSlash(realPath) == filepath.ToSlash(thisStorageRoot) {
  161. //Storage Root's root
  162. pathContained = true
  163. subPath = ""
  164. }
  165. if len(subPath) > 1 && subPath[:1] == "/" {
  166. subPath = subPath[1:]
  167. }
  168. if pathContained == true {
  169. //This storage is one of the root of the given realpath. Translate it into this
  170. if storage.Closed == true {
  171. return "", errors.New("Request Filesystem Handler has been closed by another process")
  172. }
  173. return storage.UUID + ":/" + subPath, nil
  174. }
  175. }
  176. return "", errors.New("Unable to resolve realpath in virtual devices root path")
  177. }
  178. //Get a file system handler from a virtual path, this file system handler might not be the highest prioity one
  179. func (u *User) GetFileSystemHandlerFromVirtualPath(vpath string) (*fs.FileSystemHandler, error) {
  180. fsHandlers := u.GetAllFileSystemHandler()
  181. handler, err := getHandlerFromVirtualPath(fsHandlers, vpath)
  182. return handler, err
  183. }
  184. func (u *User) GetFileSystemHandlerFromRealPath(rpath string) (*fs.FileSystemHandler, error) {
  185. vpath, err := u.RealPathToVirtualPath(rpath)
  186. if err != nil {
  187. return &fs.FileSystemHandler{}, err
  188. }
  189. return u.GetFileSystemHandlerFromVirtualPath(vpath)
  190. }