directoryHandler.go 6.6 KB

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