directoryHandler.go 8.3 KB

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