|
@@ -18,7 +18,6 @@ import (
|
|
|
"path/filepath"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
- "sync"
|
|
|
"time"
|
|
|
|
|
|
"github.com/valyala/fasttemplate"
|
|
@@ -26,61 +25,29 @@ import (
|
|
|
uuid "github.com/satori/go.uuid"
|
|
|
"imuslab.com/arozos/mod/auth"
|
|
|
"imuslab.com/arozos/mod/common"
|
|
|
- "imuslab.com/arozos/mod/database"
|
|
|
filesystem "imuslab.com/arozos/mod/filesystem"
|
|
|
+ "imuslab.com/arozos/mod/share/shareEntry"
|
|
|
"imuslab.com/arozos/mod/user"
|
|
|
)
|
|
|
|
|
|
type Options struct {
|
|
|
- AuthAgent *auth.AuthAgent
|
|
|
- Database *database.Database
|
|
|
- UserHandler *user.UserHandler
|
|
|
- HostName string
|
|
|
- TmpFolder string
|
|
|
-}
|
|
|
-
|
|
|
-type ShareOption struct {
|
|
|
- UUID string
|
|
|
- FileRealPath string
|
|
|
- Owner string
|
|
|
- Accessibles []string //Use to store username or group names if permission is groups or users
|
|
|
- Permission string //Access permission, allow {anyone / signedin / samegroup / groups / users}
|
|
|
- AllowLivePreview bool
|
|
|
+ AuthAgent *auth.AuthAgent
|
|
|
+ UserHandler *user.UserHandler
|
|
|
+ ShareEntryTable *shareEntry.ShareEntryTable
|
|
|
+ HostName string
|
|
|
+ TmpFolder string
|
|
|
}
|
|
|
|
|
|
type Manager struct {
|
|
|
- fileToUrlMap *sync.Map
|
|
|
- urlToFileMap *sync.Map
|
|
|
- options Options
|
|
|
+ options Options
|
|
|
}
|
|
|
|
|
|
//Create a new Share Manager
|
|
|
func NewShareManager(options Options) *Manager {
|
|
|
- //Create the share table if not exists
|
|
|
- db := options.Database
|
|
|
- db.NewTable("share")
|
|
|
-
|
|
|
- fileToUrlMap := sync.Map{}
|
|
|
- urlToFileMap := sync.Map{}
|
|
|
-
|
|
|
- //Load the old share links
|
|
|
- entries, _ := db.ListTable("share")
|
|
|
- for _, keypairs := range entries {
|
|
|
- shareObject := new(ShareOption)
|
|
|
- json.Unmarshal(keypairs[1], &shareObject)
|
|
|
- if shareObject != nil {
|
|
|
- //Append this to the maps
|
|
|
- fileToUrlMap.Store(shareObject.FileRealPath, shareObject)
|
|
|
- urlToFileMap.Store(shareObject.UUID, shareObject)
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
|
|
|
//Return a new manager object
|
|
|
return &Manager{
|
|
|
- options: options,
|
|
|
- fileToUrlMap: &fileToUrlMap,
|
|
|
- urlToFileMap: &urlToFileMap,
|
|
|
+ options: options,
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -88,7 +55,6 @@ func NewShareManager(options Options) *Manager {
|
|
|
func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
|
|
|
//New download method variables
|
|
|
subpathElements := []string{}
|
|
|
-
|
|
|
directDownload := false
|
|
|
directServe := false
|
|
|
relpath := ""
|
|
@@ -184,10 +150,10 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
//Check if id exists
|
|
|
- val, ok := s.urlToFileMap.Load(id)
|
|
|
+ val, ok := s.options.ShareEntryTable.UrlToFileMap.Load(id)
|
|
|
if ok {
|
|
|
//Parse the option structure
|
|
|
- shareOption := val.(*ShareOption)
|
|
|
+ shareOption := val.(*shareEntry.ShareOption)
|
|
|
|
|
|
//Check for permission
|
|
|
if shareOption.Permission == "anyone" {
|
|
@@ -598,22 +564,22 @@ func (s *Manager) HandleShareCheck(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
type Result struct {
|
|
|
IsShared bool
|
|
|
- ShareUUID *ShareOption
|
|
|
+ ShareUUID *shareEntry.ShareOption
|
|
|
}
|
|
|
|
|
|
//Check if share exists
|
|
|
- shareExists := s.FileIsShared(rpath)
|
|
|
+ shareExists := s.options.ShareEntryTable.FileIsShared(rpath)
|
|
|
if !shareExists {
|
|
|
//Share not exists
|
|
|
js, _ := json.Marshal(Result{
|
|
|
IsShared: false,
|
|
|
- ShareUUID: &ShareOption{},
|
|
|
+ ShareUUID: &shareEntry.ShareOption{},
|
|
|
})
|
|
|
sendJSONResponse(w, string(js))
|
|
|
|
|
|
} else {
|
|
|
//Share exists
|
|
|
- thisSharedInfo := s.GetShareObjectFromRealPath(rpath)
|
|
|
+ thisSharedInfo := s.options.ShareEntryTable.GetShareObjectFromRealPath(rpath)
|
|
|
js, _ := json.Marshal(Result{
|
|
|
IsShared: true,
|
|
|
ShareUUID: thisSharedInfo,
|
|
@@ -677,7 +643,7 @@ func (s *Manager) HandleEditShare(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
//Check if share exists
|
|
|
- so := s.GetShareObjectFromUUID(uuid)
|
|
|
+ so := s.options.ShareEntryTable.GetShareObjectFromUUID(uuid)
|
|
|
if so == nil {
|
|
|
//This share url not exists
|
|
|
sendErrorResponse(w, "Share UUID not exists")
|
|
@@ -713,7 +679,7 @@ func (s *Manager) HandleEditShare(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
//Write changes to database
|
|
|
- s.options.Database.Write("share", uuid, so)
|
|
|
+ s.options.ShareEntryTable.Database.Write("share", uuid, so)
|
|
|
|
|
|
} else if sharetype == "groups" || sharetype == "users" {
|
|
|
//Username or group is listed = ok
|
|
@@ -721,7 +687,7 @@ func (s *Manager) HandleEditShare(w http.ResponseWriter, r *http.Request) {
|
|
|
so.Accessibles = settings
|
|
|
|
|
|
//Write changes to database
|
|
|
- s.options.Database.Write("share", uuid, so)
|
|
|
+ s.options.ShareEntryTable.Database.Write("share", uuid, so)
|
|
|
}
|
|
|
|
|
|
sendOK(w)
|
|
@@ -754,7 +720,7 @@ func (s *Manager) HandleDeleteShare(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
//Craete a new file or folder share
|
|
|
-func (s *Manager) CreateNewShare(userinfo *user.User, vpath string) (*ShareOption, error) {
|
|
|
+func (s *Manager) CreateNewShare(userinfo *user.User, vpath string) (*shareEntry.ShareOption, error) {
|
|
|
//Translate the vpath to realpath
|
|
|
rpath, err := userinfo.VirtualPathToRealPath(vpath)
|
|
|
if err != nil {
|
|
@@ -768,10 +734,10 @@ func (s *Manager) CreateNewShare(userinfo *user.User, vpath string) (*ShareOptio
|
|
|
}
|
|
|
|
|
|
//Check if the share already exists. If yes, use the previous link
|
|
|
- val, ok := s.fileToUrlMap.Load(rpath)
|
|
|
+ val, ok := s.options.ShareEntryTable.FileToUrlMap.Load(rpath)
|
|
|
if ok {
|
|
|
//Exists. Send back the old share url
|
|
|
- ShareOption := val.(*ShareOption)
|
|
|
+ ShareOption := val.(*shareEntry.ShareOption)
|
|
|
return ShareOption, nil
|
|
|
|
|
|
} else {
|
|
@@ -785,7 +751,7 @@ func (s *Manager) CreateNewShare(userinfo *user.User, vpath string) (*ShareOptio
|
|
|
}
|
|
|
|
|
|
//Create a share object
|
|
|
- shareOption := ShareOption{
|
|
|
+ shareOption := shareEntry.ShareOption{
|
|
|
UUID: shareUUID,
|
|
|
FileRealPath: rpath,
|
|
|
Owner: userinfo.Username,
|
|
@@ -795,95 +761,16 @@ func (s *Manager) CreateNewShare(userinfo *user.User, vpath string) (*ShareOptio
|
|
|
}
|
|
|
|
|
|
//Store results on two map to make sure O(1) Lookup time
|
|
|
- s.fileToUrlMap.Store(rpath, &shareOption)
|
|
|
- s.urlToFileMap.Store(shareUUID, &shareOption)
|
|
|
+ s.options.ShareEntryTable.FileToUrlMap.Store(rpath, &shareOption)
|
|
|
+ s.options.ShareEntryTable.UrlToFileMap.Store(shareUUID, &shareOption)
|
|
|
|
|
|
//Write object to database
|
|
|
- s.options.Database.Write("share", shareUUID, shareOption)
|
|
|
+ s.options.ShareEntryTable.Database.Write("share", shareUUID, shareOption)
|
|
|
|
|
|
return &shareOption, nil
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//Delete the share on this vpath
|
|
|
-func (s *Manager) DeleteShare(userinfo *user.User, vpath string) error {
|
|
|
- //Translate the vpath to realpath
|
|
|
- rpath, err := userinfo.VirtualPathToRealPath(vpath)
|
|
|
- if err != nil {
|
|
|
- return errors.New("Unable to find the file on disk")
|
|
|
- }
|
|
|
-
|
|
|
- //Check if the share already exists. If yes, use the previous link
|
|
|
- val, ok := s.fileToUrlMap.Load(rpath)
|
|
|
- if ok {
|
|
|
- //Exists. Send back the old share url
|
|
|
- uuid := val.(*ShareOption).UUID
|
|
|
-
|
|
|
- //Remove this from the database
|
|
|
- err = s.options.Database.Delete("share", uuid)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- //Remove this form the current sync map
|
|
|
- s.urlToFileMap.Delete(uuid)
|
|
|
- s.fileToUrlMap.Delete(rpath)
|
|
|
-
|
|
|
- return nil
|
|
|
-
|
|
|
- } else {
|
|
|
- //Already deleted from buffered record.
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-func (s *Manager) GetShareUUIDFromPath(rpath string) string {
|
|
|
- targetShareObject := s.GetShareObjectFromRealPath(rpath)
|
|
|
- if (targetShareObject) != nil {
|
|
|
- return targetShareObject.UUID
|
|
|
- }
|
|
|
- return ""
|
|
|
-}
|
|
|
-
|
|
|
-func (s *Manager) GetShareObjectFromRealPath(rpath string) *ShareOption {
|
|
|
- rpath = filepath.ToSlash(filepath.Clean(rpath))
|
|
|
- var targetShareOption *ShareOption
|
|
|
- s.fileToUrlMap.Range(func(k, v interface{}) bool {
|
|
|
- filePath := k.(string)
|
|
|
- shareObject := v.(*ShareOption)
|
|
|
-
|
|
|
- if filepath.ToSlash(filepath.Clean(filePath)) == rpath {
|
|
|
- targetShareOption = shareObject
|
|
|
- }
|
|
|
-
|
|
|
- return true
|
|
|
- })
|
|
|
-
|
|
|
- return targetShareOption
|
|
|
-}
|
|
|
-
|
|
|
-func (s *Manager) GetShareObjectFromUUID(uuid string) *ShareOption {
|
|
|
- var targetShareOption *ShareOption
|
|
|
- s.urlToFileMap.Range(func(k, v interface{}) bool {
|
|
|
- thisUuid := k.(string)
|
|
|
- shareObject := v.(*ShareOption)
|
|
|
-
|
|
|
- if thisUuid == uuid {
|
|
|
- targetShareOption = shareObject
|
|
|
- }
|
|
|
-
|
|
|
- return true
|
|
|
- })
|
|
|
-
|
|
|
- return targetShareOption
|
|
|
-}
|
|
|
-
|
|
|
-func (s *Manager) FileIsShared(rpath string) bool {
|
|
|
- shareUUID := s.GetShareUUIDFromPath(rpath)
|
|
|
- return shareUUID != ""
|
|
|
-}
|
|
|
-
|
|
|
func ServePermissionDeniedPage(w http.ResponseWriter) {
|
|
|
w.WriteHeader(http.StatusForbidden)
|
|
|
pageContent := []byte("Permissioned Denied")
|
|
@@ -935,42 +822,51 @@ func validateShareModes(mode string) (bool, string, []string) {
|
|
|
return false, "", []string{}
|
|
|
}
|
|
|
|
|
|
-func (s *Manager) RemoveShareByRealpath(rpath string) error {
|
|
|
- so, ok := s.fileToUrlMap.Load(rpath)
|
|
|
- if ok {
|
|
|
- shareUUID := so.(*ShareOption).UUID
|
|
|
- s.urlToFileMap.Delete(shareUUID)
|
|
|
- s.fileToUrlMap.Delete(rpath)
|
|
|
- s.options.Database.Delete("share", shareUUID)
|
|
|
- } else {
|
|
|
- return errors.New("Share with given realpath not exists")
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (s *Manager) RemoveShareByUUID(uuid string) error {
|
|
|
- so, ok := s.urlToFileMap.Load(uuid)
|
|
|
- if ok {
|
|
|
- s.fileToUrlMap.Delete(so.(*ShareOption).FileRealPath)
|
|
|
- s.urlToFileMap.Delete(uuid)
|
|
|
- s.options.Database.Delete("share", uuid)
|
|
|
- } else {
|
|
|
- return errors.New("Share with given uuid not exists")
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
//Check and clear shares that its pointinf files no longe exists
|
|
|
func (s *Manager) ValidateAndClearShares() {
|
|
|
//Iterate through all shares within the system
|
|
|
- s.fileToUrlMap.Range(func(k, v interface{}) bool {
|
|
|
+ s.options.ShareEntryTable.FileToUrlMap.Range(func(k, v interface{}) bool {
|
|
|
thisRealPath := k.(string)
|
|
|
if !fileExists(thisRealPath) {
|
|
|
//This share source file don't exists anymore. Remove it
|
|
|
- s.RemoveShareByRealpath(thisRealPath)
|
|
|
+ s.options.ShareEntryTable.RemoveShareByRealpath(thisRealPath)
|
|
|
log.Println("*Share* Removing share to file: " + thisRealPath + " as it no longer exists")
|
|
|
}
|
|
|
return true
|
|
|
})
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+func (s *Manager) DeleteShare(userinfo *user.User, vpath string) error {
|
|
|
+ //Translate the vpath to realpath
|
|
|
+ rpath, err := userinfo.VirtualPathToRealPath(vpath)
|
|
|
+ if err != nil {
|
|
|
+ return errors.New("Unable to find the file on disk")
|
|
|
+ }
|
|
|
+
|
|
|
+ return s.options.ShareEntryTable.DeleteShare(rpath)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Manager) GetShareUUIDFromPath(rpath string) string {
|
|
|
+ return s.options.ShareEntryTable.GetShareUUIDFromPath(rpath)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Manager) GetShareObjectFromRealPath(rpath string) *shareEntry.ShareOption {
|
|
|
+ return s.options.ShareEntryTable.GetShareObjectFromRealPath(rpath)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Manager) GetShareObjectFromUUID(uuid string) *shareEntry.ShareOption {
|
|
|
+ return s.options.ShareEntryTable.GetShareObjectFromUUID(uuid)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Manager) FileIsShared(rpath string) bool {
|
|
|
+ return s.options.ShareEntryTable.FileIsShared(rpath)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Manager) RemoveShareByRealpath(rpath string) error {
|
|
|
+ return s.RemoveShareByRealpath(rpath)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *Manager) RemoveShareByUUID(uuid string) error {
|
|
|
+ return s.options.ShareEntryTable.RemoveShareByUUID(uuid)
|
|
|
+}
|