|
@@ -24,9 +24,9 @@ import (
|
|
|
|
|
|
"imuslab.com/arozos/mod/common"
|
|
|
"imuslab.com/arozos/mod/compatibility"
|
|
|
- "imuslab.com/arozos/mod/disk/hybridBackup"
|
|
|
"imuslab.com/arozos/mod/filesystem"
|
|
|
fs "imuslab.com/arozos/mod/filesystem"
|
|
|
+ "imuslab.com/arozos/mod/filesystem/fsdef"
|
|
|
fsp "imuslab.com/arozos/mod/filesystem/fspermission"
|
|
|
"imuslab.com/arozos/mod/filesystem/fuzzy"
|
|
|
hidden "imuslab.com/arozos/mod/filesystem/hidden"
|
|
@@ -88,7 +88,6 @@ func FileSystemInit() {
|
|
|
router.HandleFunc("/system/file_system/restoreTrash", system_fs_restoreFile)
|
|
|
router.HandleFunc("/system/file_system/zipHandler", system_fs_zipHandler)
|
|
|
router.HandleFunc("/system/file_system/getProperties", system_fs_getFileProperties)
|
|
|
- router.HandleFunc("/system/file_system/pathTranslate", system_fs_handlePathTranslate)
|
|
|
router.HandleFunc("/system/file_system/versionHistory", system_fs_FileVersionHistory)
|
|
|
|
|
|
router.HandleFunc("/system/file_system/handleFilePermission", system_fs_handleFilePermission)
|
|
@@ -394,10 +393,10 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- targetFs := fsh.FileSystemAbstraction
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
|
|
|
//Translate the upload target directory
|
|
|
- realUploadPath, err := targetFs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
|
+ realUploadPath, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
|
if err != nil {
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
w.Write([]byte("500 - Path translation failed"))
|
|
@@ -413,8 +412,8 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
targetUploadLocation := filepath.Join(realUploadPath, filename)
|
|
|
- if !targetFs.FileExists(realUploadPath) {
|
|
|
- targetFs.MkdirAll(realUploadPath, 0755)
|
|
|
+ if !fshAbs.FileExists(realUploadPath) {
|
|
|
+ fshAbs.MkdirAll(realUploadPath, 0755)
|
|
|
}
|
|
|
|
|
|
//Generate an UUID for this upload
|
|
@@ -423,7 +422,7 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
if isHugeFile {
|
|
|
//Upload to the same directory as the target location. This option do not allow buffered fs
|
|
|
uploadFolder = filepath.Join(realUploadPath, ".metadata/.upload", uploadUUID)
|
|
|
- targetFs.MkdirAll(uploadFolder, 0700)
|
|
|
+ fshAbs.MkdirAll(uploadFolder, 0700)
|
|
|
} else {
|
|
|
//Buffer to local tmp folder
|
|
|
os.MkdirAll(uploadFolder, 0700)
|
|
@@ -475,7 +474,11 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
log.Println("Upload terminated by client. Cleaning tmp folder.")
|
|
|
//Clear the tmp folder
|
|
|
time.Sleep(1 * time.Second)
|
|
|
- os.RemoveAll(uploadFolder)
|
|
|
+ if isHugeFile {
|
|
|
+ fshAbs.RemoveAll(uploadFolder)
|
|
|
+ } else {
|
|
|
+ os.RemoveAll(uploadFolder)
|
|
|
+ }
|
|
|
return
|
|
|
}
|
|
|
//The mt should be 2 = binary for file upload and 1 for control syntax
|
|
@@ -505,7 +508,11 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
c.Close()
|
|
|
|
|
|
//Clear the tmp files
|
|
|
- os.RemoveAll(uploadFolder)
|
|
|
+ if isHugeFile {
|
|
|
+ fshAbs.RemoveAll(uploadFolder)
|
|
|
+ } else {
|
|
|
+ os.RemoveAll(uploadFolder)
|
|
|
+ }
|
|
|
return
|
|
|
}
|
|
|
|
|
@@ -524,7 +531,11 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
c.Close()
|
|
|
|
|
|
//Clear the tmp files
|
|
|
- os.RemoveAll(uploadFolder)
|
|
|
+ if isHugeFile {
|
|
|
+ fshAbs.RemoveAll(uploadFolder)
|
|
|
+ } else {
|
|
|
+ os.RemoveAll(uploadFolder)
|
|
|
+ }
|
|
|
|
|
|
return
|
|
|
} else if !userinfo.StorageQuota.HaveSpace(totalFileSize) {
|
|
@@ -537,7 +548,11 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
c.Close()
|
|
|
|
|
|
//Clear the tmp files
|
|
|
- os.RemoveAll(uploadFolder)
|
|
|
+ if isHugeFile {
|
|
|
+ fshAbs.RemoveAll(uploadFolder)
|
|
|
+ } else {
|
|
|
+ os.RemoveAll(uploadFolder)
|
|
|
+ }
|
|
|
}
|
|
|
blockCounter++
|
|
|
|
|
@@ -589,6 +604,21 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
out.Close()
|
|
|
|
|
|
+ //Check if the size fit in user quota
|
|
|
+ fi, err := os.Stat(mergeFileLocation)
|
|
|
+ if err != nil {
|
|
|
+ // Could not obtain stat, handle error
|
|
|
+ log.Println("Failed to validate uploaded file: ", mergeFileLocation, ". Error Message: ", err.Error())
|
|
|
+ c.WriteMessage(1, []byte(`{\"error\":\"Failed to validate uploaded file\"}`))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if !userinfo.StorageQuota.HaveSpace(fi.Size()) {
|
|
|
+ c.WriteMessage(1, []byte(`{\"error\":\"User Storage Quota Exceeded\"}`))
|
|
|
+ os.RemoveAll(mergeFileLocation)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //Upload it to remote side if it fits the user quota && is buffer file
|
|
|
if fsh.RequireBuffer && !isHugeFile {
|
|
|
//This is buffer file. Upload to dest fsh
|
|
|
f, err := os.Open(mergeFileLocation)
|
|
@@ -612,26 +642,11 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
os.Remove(mergeFileLocation)
|
|
|
}
|
|
|
|
|
|
- //Check if the size fit in user quota
|
|
|
- fi, err := targetFs.Stat(decodedUploadLocation)
|
|
|
- if err != nil {
|
|
|
- // Could not obtain stat, handle error
|
|
|
- log.Println("Failed to validate uploaded file: ", decodedUploadLocation, ". Error Message: ", err.Error())
|
|
|
- c.WriteMessage(1, []byte(`{\"error\":\"Failed to validate uploaded file\"}`))
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if !userinfo.StorageQuota.HaveSpace(fi.Size()) {
|
|
|
- c.WriteMessage(1, []byte(`{\"error\":\"User Storage Quota Exceeded\"}`))
|
|
|
- os.RemoveAll(decodedUploadLocation)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
//Log the upload filename
|
|
|
log.Println(userinfo.Username + " uploaded a file: " + filepath.Base(decodedUploadLocation))
|
|
|
|
|
|
//Set owner of the new uploaded file
|
|
|
- userinfo.SetOwnerOfFile(decodedUploadLocation)
|
|
|
+ userinfo.SetOwnerOfFile(fsh, unescapedPath)
|
|
|
|
|
|
//Return complete signal
|
|
|
c.WriteMessage(1, []byte("OK"))
|
|
@@ -642,7 +657,7 @@ func system_fs_handleLowMemoryUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
//Clear the tmp folder
|
|
|
time.Sleep(300 * time.Millisecond)
|
|
|
if isHugeFile {
|
|
|
- targetFs.RemoveAll(uploadFolder)
|
|
|
+ fshAbs.RemoveAll(uploadFolder)
|
|
|
} else {
|
|
|
os.RemoveAll(uploadFolder)
|
|
|
}
|
|
@@ -745,10 +760,10 @@ func system_fs_handleUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
//Check if the upload target is read only.
|
|
|
accmode := userinfo.GetPathAccessPermission(uploadTarget)
|
|
|
- if accmode == "readonly" {
|
|
|
+ if accmode == fsdef.FsReadOnly {
|
|
|
common.SendErrorResponse(w, "The upload target is Read Only.")
|
|
|
return
|
|
|
- } else if accmode == "denied" {
|
|
|
+ } else if accmode == fsdef.FsDenied {
|
|
|
common.SendErrorResponse(w, "Access Denied")
|
|
|
return
|
|
|
}
|
|
@@ -779,7 +794,7 @@ func system_fs_handleUpload(w http.ResponseWriter, r *http.Request) {
|
|
|
r.MultipartForm.RemoveAll()
|
|
|
|
|
|
//Set the ownership of file
|
|
|
- userinfo.SetOwnerOfFile(destFilepath)
|
|
|
+ userinfo.SetOwnerOfFile(fsh, uploadTarget)
|
|
|
|
|
|
//Finish up the upload
|
|
|
/*
|
|
@@ -1057,10 +1072,11 @@ func system_fs_clearTrashBin(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
//Get list success. Remove each of them.
|
|
|
for c, file := range fileList {
|
|
|
- isOwner := u.IsOwnerOfFile(file)
|
|
|
+ fileVpath, _ := fshs[c].FileSystemAbstraction.RealPathToVirtualPath(file, u.Username)
|
|
|
+ isOwner := u.IsOwnerOfFile(fshs[c], fileVpath)
|
|
|
if isOwner {
|
|
|
//This user own this system. Remove this file from his quota
|
|
|
- u.RemoveOwnershipFromFile(file)
|
|
|
+ u.RemoveOwnershipFromFile(fshs[c], fileVpath)
|
|
|
}
|
|
|
fshAbs := fshs[c].FileSystemAbstraction
|
|
|
fshAbs.RemoveAll(file)
|
|
@@ -1187,10 +1203,10 @@ func system_fs_handleNewObjects(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
//Check if directory is readonly
|
|
|
accmode := userinfo.GetPathAccessPermission(vsrc)
|
|
|
- if accmode == "readonly" {
|
|
|
+ if accmode == fsdef.FsReadOnly {
|
|
|
common.SendErrorResponse(w, "This directory is Read Only")
|
|
|
return
|
|
|
- } else if accmode == "denied" {
|
|
|
+ } else if accmode == fsdef.FsDenied {
|
|
|
common.SendErrorResponse(w, "Access Denied")
|
|
|
return
|
|
|
}
|
|
@@ -1782,10 +1798,10 @@ func system_fs_handleOpr(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
//Check if the target dir is not readonly
|
|
|
accmode := userinfo.GetPathAccessPermission(string(vsrcFile))
|
|
|
- if accmode == "readonly" {
|
|
|
+ if accmode == fsdef.FsReadOnly {
|
|
|
common.SendErrorResponse(w, "This directory is Read Only")
|
|
|
return
|
|
|
- } else if accmode == "denied" {
|
|
|
+ } else if accmode == fsdef.FsDenied {
|
|
|
common.SendErrorResponse(w, "Access Denied")
|
|
|
return
|
|
|
}
|
|
@@ -1834,10 +1850,10 @@ func system_fs_handleOpr(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
//Check if the source file is read only.
|
|
|
accmode := userinfo.GetPathAccessPermission(string(vsrcFile))
|
|
|
- if accmode == "readonly" {
|
|
|
+ if accmode == fsdef.FsReadOnly {
|
|
|
common.SendErrorResponse(w, "This source file is Read Only")
|
|
|
return
|
|
|
- } else if accmode == "denied" {
|
|
|
+ } else if accmode == fsdef.FsDenied {
|
|
|
common.SendErrorResponse(w, "Access Denied")
|
|
|
return
|
|
|
}
|
|
@@ -1860,18 +1876,20 @@ func system_fs_handleOpr(w http.ResponseWriter, r *http.Request) {
|
|
|
//underSameRoot, _ := fs.UnderTheSameRoot(srcAbs, destAbs)
|
|
|
|
|
|
//Updates 19-10-2020: Added ownership management to file move and copy
|
|
|
- userinfo.RemoveOwnershipFromFile(rsrcFile)
|
|
|
+ userinfo.RemoveOwnershipFromFile(srcFsh, vsrcFile)
|
|
|
|
|
|
err = fs.FileMove(srcFsh, rsrcFile, destFsh, rdestFile, existsOpr, true, nil)
|
|
|
if err != nil {
|
|
|
common.SendErrorResponse(w, err.Error())
|
|
|
//Restore the ownership if remove failed
|
|
|
- userinfo.SetOwnerOfFile(rsrcFile)
|
|
|
+ userinfo.SetOwnerOfFile(srcFsh, vsrcFile)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
//Set user to own the new file
|
|
|
- userinfo.SetOwnerOfFile(filepath.ToSlash(filepath.Clean(rdestFile)) + "/" + filepath.Base(rsrcFile))
|
|
|
+ newfileRpath := filepath.ToSlash(filepath.Clean(rdestFile)) + "/" + filepath.Base(rsrcFile)
|
|
|
+ newfileVpath, _ := destFsh.FileSystemAbstraction.RealPathToVirtualPath(newfileRpath, userinfo.Username)
|
|
|
+ userinfo.SetOwnerOfFile(destFsh, newfileVpath)
|
|
|
|
|
|
//Remove cache for the original file
|
|
|
metadata.RemoveCache(srcFsh, rsrcFile)
|
|
@@ -1913,7 +1931,9 @@ func system_fs_handleOpr(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
//Set user to own this file
|
|
|
- userinfo.SetOwnerOfFile(filepath.ToSlash(filepath.Clean(rdestFile)) + "/" + filepath.Base(rsrcFile))
|
|
|
+ newfileRpath := filepath.ToSlash(filepath.Clean(rdestFile)) + "/" + filepath.Base(rsrcFile)
|
|
|
+ newfileVpath, _ := destFsh.FileSystemAbstraction.RealPathToVirtualPath(newfileRpath, userinfo.Username)
|
|
|
+ userinfo.SetOwnerOfFile(destFsh, newfileVpath)
|
|
|
|
|
|
} else if operation == "delete" {
|
|
|
//Delete the file permanently
|
|
@@ -1930,10 +1950,10 @@ func system_fs_handleOpr(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
//Check if the user own this file
|
|
|
- isOwner := userinfo.IsOwnerOfFile(rsrcFile)
|
|
|
+ isOwner := userinfo.IsOwnerOfFile(srcFsh, vsrcFile)
|
|
|
if isOwner {
|
|
|
//This user own this system. Remove this file from his quota
|
|
|
- userinfo.RemoveOwnershipFromFile(rsrcFile)
|
|
|
+ userinfo.RemoveOwnershipFromFile(srcFsh, vsrcFile)
|
|
|
}
|
|
|
|
|
|
//Check if this file has any cached files. If yes, remove it
|
|
@@ -2174,8 +2194,10 @@ func system_fs_listRoot(w http.ResponseWriter, r *http.Request) {
|
|
|
IsDir bool
|
|
|
}
|
|
|
//List the root media folders under user:/
|
|
|
+ fsh, _ := userinfo.GetFileSystemHandlerFromVirtualPath("user:/")
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
filesInUserRoot := []fileObject{}
|
|
|
- filesInRoot, _ := filepath.Glob(filepath.ToSlash(filepath.Clean(*root_directory)) + "/users/" + username + "/*")
|
|
|
+ filesInRoot, _ := fshAbs.Glob(filepath.ToSlash(filepath.Clean(*root_directory)) + "/users/" + username + "/*")
|
|
|
for _, file := range filesInRoot {
|
|
|
//Check if this is a hidden file
|
|
|
if len(filepath.Base(file)) > 0 && filepath.Base(file)[:1] == "." {
|
|
@@ -2183,8 +2205,8 @@ func system_fs_listRoot(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
thisFile := new(fileObject)
|
|
|
thisFile.Filename = filepath.Base(file)
|
|
|
- thisFile.Filepath, _ = userinfo.RealPathToVirtualPath(file)
|
|
|
- thisFile.IsDir = fs.IsDir(file)
|
|
|
+ thisFile.Filepath, _ = fshAbs.RealPathToVirtualPath(file, userinfo.Username)
|
|
|
+ thisFile.IsDir = fshAbs.IsDir(file)
|
|
|
filesInUserRoot = append(filesInUserRoot, *thisFile)
|
|
|
}
|
|
|
jsonString, _ := json.Marshal(filesInUserRoot)
|
|
@@ -2200,17 +2222,11 @@ func system_fs_listRoot(w http.ResponseWriter, r *http.Request) {
|
|
|
roots := []*rootObject{}
|
|
|
backupRoots := []string{}
|
|
|
for _, store := range userinfo.GetAllFileSystemHandler() {
|
|
|
- if store.Hierarchy == "user" || store.Hierarchy == "public" {
|
|
|
- //Normal drives
|
|
|
- var thisDevice = new(rootObject)
|
|
|
- thisDevice.RootName = store.Name
|
|
|
- thisDevice.RootPath = store.UUID + ":/"
|
|
|
- thisDevice.rootID = store.UUID
|
|
|
- roots = append(roots, thisDevice)
|
|
|
- } else if store.Hierarchy == "backup" {
|
|
|
- //Backup drive.
|
|
|
- backupRoots = append(backupRoots, store.HierarchyConfig.(hybridBackup.BackupTask).ParentUID)
|
|
|
- }
|
|
|
+ var thisDevice = new(rootObject)
|
|
|
+ thisDevice.RootName = store.Name
|
|
|
+ thisDevice.RootPath = store.UUID + ":/"
|
|
|
+ thisDevice.rootID = store.UUID
|
|
|
+ roots = append(roots, thisDevice)
|
|
|
}
|
|
|
|
|
|
//Update root configs for backup roots
|
|
@@ -2355,7 +2371,7 @@ func system_fs_getFileProperties(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
//Get file owner
|
|
|
- owner := userinfo.GetFileOwner(rpath)
|
|
|
+ owner := userinfo.GetFileOwner(fsh, vpath)
|
|
|
|
|
|
if owner == "" {
|
|
|
//Handle special virtual roots
|
|
@@ -2814,37 +2830,6 @@ func system_fs_clearVersionHistories() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//Translate path from and to virtual and realpath
|
|
|
-func system_fs_handlePathTranslate(w http.ResponseWriter, r *http.Request) {
|
|
|
- userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
|
|
|
- if err != nil {
|
|
|
- common.SendErrorResponse(w, err.Error())
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- path, err := common.Mv(r, "path", false)
|
|
|
- if err != nil {
|
|
|
- common.SendErrorResponse(w, "Invalid path given")
|
|
|
- return
|
|
|
- }
|
|
|
- rpath, err := userinfo.VirtualPathToRealPath(path)
|
|
|
- if err != nil {
|
|
|
- //Try to convert it to virtualPath
|
|
|
- vpath, err := userinfo.RealPathToVirtualPath(path)
|
|
|
- if err != nil {
|
|
|
- common.SendErrorResponse(w, "Unknown path given")
|
|
|
- } else {
|
|
|
- jsonstring, _ := json.Marshal(vpath)
|
|
|
- common.SendJSONResponse(w, string(jsonstring))
|
|
|
- }
|
|
|
- } else {
|
|
|
- abrpath, _ := filepath.Abs(rpath)
|
|
|
- jsonstring, _ := json.Marshal([]string{rpath, filepath.ToSlash(abrpath)})
|
|
|
- common.SendJSONResponse(w, string(jsonstring))
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
//Handle cache rendering with websocket pipeline
|
|
|
func system_fs_handleCacheRender(w http.ResponseWriter, r *http.Request) {
|
|
|
userinfo, _ := userHandler.GetUserInfoFromRequest(w, r)
|
|
@@ -2995,7 +2980,10 @@ func system_fs_handleFilePermission(w http.ResponseWriter, r *http.Request) {
|
|
|
common.SendErrorResponse(w, "User not logged in")
|
|
|
return
|
|
|
}
|
|
|
- rpath, err := userinfo.VirtualPathToRealPath(file)
|
|
|
+
|
|
|
+ fsh, subpath, err := GetFSHandlerSubpathFromVpath(file)
|
|
|
+ fshAbs := fsh.FileSystemAbstraction
|
|
|
+ rpath, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
|
if err != nil {
|
|
|
common.SendErrorResponse(w, err.Error())
|
|
|
return
|
|
@@ -3005,13 +2993,13 @@ func system_fs_handleFilePermission(w http.ResponseWriter, r *http.Request) {
|
|
|
//Read the file mode
|
|
|
|
|
|
//Check if the file exists
|
|
|
- if !fs.FileExists(rpath) {
|
|
|
+ if !fshAbs.FileExists(rpath) {
|
|
|
common.SendErrorResponse(w, "File not exists!")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
//Read the file permission
|
|
|
- filePermission, err := fsp.GetFilePermissions(rpath)
|
|
|
+ filePermission, err := fsp.GetFilePermissions(fsh, rpath)
|
|
|
if err != nil {
|
|
|
common.SendErrorResponse(w, err.Error())
|
|
|
return
|
|
@@ -3056,7 +3044,7 @@ func system_fs_handleFilePermission(w http.ResponseWriter, r *http.Request) {
|
|
|
//Be noted that if the system is not running in sudo mode,
|
|
|
//File permission change might not works.
|
|
|
|
|
|
- err := fsp.SetFilePermisson(rpath, newMode)
|
|
|
+ err := fsp.SetFilePermisson(fsh, rpath, newMode)
|
|
|
if err != nil {
|
|
|
common.SendErrorResponse(w, err.Error())
|
|
|
return
|