From df5c820c68ba572e5f4e28f63d6430b64e119a8a Mon Sep 17 00:00:00 2001 From: hexxa Date: Wed, 7 Sep 2022 20:19:46 +0800 Subject: [PATCH] fix(files): add location to file info --- src/db/interface.go | 6 +-- src/db/rdb/sqlite/files.go | 36 +++++++++----- src/db/rdb/sqlite/files_sharings.go | 27 ++++++++--- src/db/rdb/sqlite/files_uploadings.go | 8 ++- src/db/rdb/sqlite/sqlite.go | 1 + src/db/tests/files_test.go | 11 +++-- src/handlers/fileshdr/handlers.go | 31 +++--------- src/server/server_files_test.go | 70 ++++++++++++++++++++++----- 8 files changed, 127 insertions(+), 63 deletions(-) diff --git a/src/db/interface.go b/src/db/interface.go index 8d51bbc..33033b0 100644 --- a/src/db/interface.go +++ b/src/db/interface.go @@ -73,7 +73,7 @@ type IFileDB interface { DelFileInfo(ctx context.Context, userId uint64, itemPath string) error GetFileInfo(ctx context.Context, itemPath string) (*FileInfo, error) SetSha1(ctx context.Context, itemPath, sign string) error - MoveFileInfos(ctx context.Context, userId uint64, oldPath, newPath string, isDir bool) error + MoveFileInfo(ctx context.Context, userId uint64, oldPath, newPath string, isDir bool) error ListFileInfos(ctx context.Context, itemPaths []string) (map[string]*FileInfo, error) } type IUploadDB interface { @@ -86,11 +86,11 @@ type IUploadDB interface { } type ISharingDB interface { - IsSharing(ctx context.Context, userId uint64, dirPath string) (bool, error) + IsSharing(ctx context.Context, dirPath string) (bool, error) GetSharingDir(ctx context.Context, hashID string) (string, error) AddSharing(ctx context.Context, userId uint64, dirPath string) error DelSharing(ctx context.Context, userId uint64, dirPath string) error - ListUserSharings(ctx context.Context, userId uint64) (map[string]string, error) + ListSharingsByLocation(ctx context.Context, location string) (map[string]string, error) } type IConfigDB interface { diff --git a/src/db/rdb/sqlite/files.go b/src/db/rdb/sqlite/files.go index 2502690..88ec81b 100644 --- a/src/db/rdb/sqlite/files.go +++ b/src/db/rdb/sqlite/files.go @@ -128,19 +128,24 @@ func (st *SQLiteStore) addFileInfo(ctx context.Context, userId uint64, itemPath return err } + location, err := getLocation(itemPath) + if err != nil { + return err + } + dirPath, itemName := path.Split(itemPath) _, err = st.db.ExecContext( ctx, - `insert into t_file_info - (path, user, parent, name, is_dir, size, share_id, info) values (?, ?, ?, ?, ?, ?, ?, ?)`, - itemPath, - userId, - dirPath, - itemName, - info.IsDir, - info.Size, - info.ShareID, - infoStr, + `insert into t_file_info ( + path, user, location, parent, name, + is_dir, size, share_id, info + ) + values ( + ?, ?, ?, ?, ?, + ?, ?, ?, ? + )`, + itemPath, userId, location, dirPath, itemName, + info.IsDir, info.Size, info.ShareID, infoStr, ) return err } @@ -248,7 +253,7 @@ func (st *SQLiteStore) DelFileInfo(ctx context.Context, userID uint64, itemPath return err } -func (st *SQLiteStore) MoveFileInfos(ctx context.Context, userId uint64, oldPath, newPath string, isDir bool) error { +func (st *SQLiteStore) MoveFileInfo(ctx context.Context, userId uint64, oldPath, newPath string, isDir bool) error { st.Lock() defer st.Unlock() @@ -268,3 +273,12 @@ func (st *SQLiteStore) MoveFileInfos(ctx context.Context, userId uint64, oldPath } return st.addFileInfo(ctx, userId, newPath, info) } + +func getLocation(itemPath string) (string, error) { + // location is taken from item path + itemPathParts := strings.Split(itemPath, "/") + if len(itemPathParts) == 0 { + return "", fmt.Errorf("invalid item path '%s'", itemPath) + } + return itemPathParts[0], nil +} diff --git a/src/db/rdb/sqlite/files_sharings.go b/src/db/rdb/sqlite/files_sharings.go index 3849b73..ecf30d7 100644 --- a/src/db/rdb/sqlite/files_sharings.go +++ b/src/db/rdb/sqlite/files_sharings.go @@ -29,11 +29,10 @@ func (st *SQLiteStore) generateShareID(payload string) (string, error) { return fmt.Sprintf("%x", h.Sum(nil))[:7], nil } -func (st *SQLiteStore) IsSharing(ctx context.Context, userId uint64, dirPath string) (bool, error) { +func (st *SQLiteStore) IsSharing(ctx context.Context, dirPath string) (bool, error) { st.RLock() defer st.RUnlock() - // TODO: userId is not used, becauser it is searcher's userId var shareId string err := st.db.QueryRowContext( ctx, @@ -88,6 +87,11 @@ func (st *SQLiteStore) AddSharing(ctx context.Context, userId uint64, dirPath st return err } + location, err := getLocation(dirPath) + if err != nil { + return err + } + _, err = st.getFileInfo(ctx, dirPath) if err != nil && !errors.Is(err, db.ErrFileInfoNotFound) { return err @@ -104,9 +108,16 @@ func (st *SQLiteStore) AddSharing(ctx context.Context, userId uint64, dirPath st _, err = st.db.ExecContext( ctx, - `insert into t_file_info - (path, user, parent, name, is_dir, size, share_id, info) values (?, ?, ?, ?, ?, ?, ?, ?)`, - dirPath, userId, parentPath, name, true, 0, shareID, infoStr, + `insert into t_file_info ( + path, user, location, parent, name, + is_dir, size, share_id, info + ) + values ( + ?, ?, ?, ?, ?, + ?, ?, ?, ? + )`, + dirPath, userId, location, parentPath, name, + true, 0, shareID, infoStr, ) return err } @@ -135,7 +146,7 @@ func (st *SQLiteStore) DelSharing(ctx context.Context, userId uint64, dirPath st return err } -func (st *SQLiteStore) ListUserSharings(ctx context.Context, userId uint64) (map[string]string, error) { +func (st *SQLiteStore) ListSharingsByLocation(ctx context.Context, location string) (map[string]string, error) { st.RLock() defer st.RUnlock() @@ -143,8 +154,8 @@ func (st *SQLiteStore) ListUserSharings(ctx context.Context, userId uint64) (map ctx, `select path, share_id from t_file_info - where user=? and share_id <> ''`, - userId, + where location=? and share_id<>''`, + location, ) if err != nil { return nil, err diff --git a/src/db/rdb/sqlite/files_uploadings.go b/src/db/rdb/sqlite/files_uploadings.go index b9aaa82..9439365 100644 --- a/src/db/rdb/sqlite/files_uploadings.go +++ b/src/db/rdb/sqlite/files_uploadings.go @@ -11,8 +11,12 @@ import ( func (st *SQLiteStore) addUploadInfoOnly(ctx context.Context, userId uint64, tmpPath, filePath string, fileSize int64) error { _, err := st.db.ExecContext( ctx, - `insert into t_file_uploading - (real_path, tmp_path, user, size, uploaded) values (?, ?, ?, ?, ?)`, + `insert into t_file_uploading ( + real_path, tmp_path, user, size, uploaded + ) + values ( + ?, ?, ?, ?, ? + )`, filePath, tmpPath, userId, fileSize, 0, ) return err diff --git a/src/db/rdb/sqlite/sqlite.go b/src/db/rdb/sqlite/sqlite.go index 6c033f1..88541df 100644 --- a/src/db/rdb/sqlite/sqlite.go +++ b/src/db/rdb/sqlite/sqlite.go @@ -129,6 +129,7 @@ func (st *SQLiteStore) InitFileTables(ctx context.Context) error { `create table if not exists t_file_info ( path varchar not null, user bigint not null, + location varchar not null, parent varchar not null, name varchar not null, is_dir boolean not null, diff --git a/src/db/tests/files_test.go b/src/db/tests/files_test.go index e38ddcf..0155935 100644 --- a/src/db/tests/files_test.go +++ b/src/db/tests/files_test.go @@ -18,6 +18,7 @@ func TestFileStore(t *testing.T) { testSharingMethods := func(t *testing.T, store db.IDBQuickshare) { dirPaths := []string{"admin/path1", "admin/path1/path2"} var err error + location := "admin" ctx := context.TODO() adminId := uint64(0) @@ -43,7 +44,7 @@ func TestFileStore(t *testing.T) { } // list sharings - dirToID, err := store.ListUserSharings(ctx, adminId) + dirToID, err := store.ListSharingsByLocation(ctx, location) if err != nil { t.Fatal(err) } else if len(dirToID) != len(dirPaths) { @@ -54,7 +55,7 @@ func TestFileStore(t *testing.T) { if _, ok := dirToID[sharingDir]; !ok { t.Fatalf("sharing(%s) not found", sharingDir) } - mustTrue, err := store.IsSharing(ctx, adminId, sharingDir) + mustTrue, err := store.IsSharing(ctx, sharingDir) if err != nil { t.Fatal(err) } else if !mustTrue { @@ -85,7 +86,7 @@ func TestFileStore(t *testing.T) { } // list sharings - dirToIDAfterDel, err := store.ListUserSharings(ctx, adminId) + dirToIDAfterDel, err := store.ListSharingsByLocation(ctx, location) if err != nil { t.Fatal(err) } else if len(dirToIDAfterDel) != 0 { @@ -96,7 +97,7 @@ func TestFileStore(t *testing.T) { if _, ok := dirToIDAfterDel[dirPath]; ok { t.Fatalf("sharing(%s) should not exist", dirPath) } - shared, err := store.IsSharing(ctx, adminId, dirPath) + shared, err := store.IsSharing(ctx, dirPath) if err != nil { t.Fatal(err) } else if shared { @@ -217,7 +218,7 @@ func TestFileStore(t *testing.T) { newPaths := []string{} for itemPath, info := range pathInfos { newItemPath := strings.ReplaceAll(itemPath, "origin", "new") - err = store.MoveFileInfos(ctx, adminId, itemPath, newItemPath, info.IsDir) + err = store.MoveFileInfo(ctx, adminId, itemPath, newItemPath, info.IsDir) if err != nil { t.Fatal(err) } diff --git a/src/handlers/fileshdr/handlers.go b/src/handlers/fileshdr/handlers.go index 84a6305..3d5da31 100644 --- a/src/handlers/fileshdr/handlers.go +++ b/src/handlers/fileshdr/handlers.go @@ -101,7 +101,7 @@ func (h *FileHandlers) canAccess(ctx context.Context, userId uint64, userName, r return false } - isSharing, err := h.deps.FileInfos().IsSharing(ctx, userId, sharedPath) + isSharing, err := h.deps.FileInfos().IsSharing(ctx, sharedPath) if err != nil { return false // TODO: return error } @@ -157,6 +157,7 @@ func (h *FileHandlers) Create(c *gin.Context) { } return } + err = h.deps.FileInfos().MoveUploadingInfos(c, userID, tmpFilePath, fsFilePath) if err != nil { c.JSON(q.ErrResp(c, 500, err)) @@ -422,7 +423,7 @@ func (h *FileHandlers) Move(c *gin.Context) { return } - err = h.deps.FileInfos().MoveFileInfos(c, userId, oldPath, newPath, itemInfo.IsDir()) + err = h.deps.FileInfos().MoveFileInfo(c, userId, oldPath, newPath, itemInfo.IsDir()) if err != nil { c.JSON(q.ErrResp(c, 500, err)) return @@ -1063,13 +1064,7 @@ func (h *FileHandlers) IsSharing(c *gin.Context) { return } - userId, err := q.GetUserId(c) - if err != nil { - c.JSON(q.ErrResp(c, 500, err)) - return - } - - exist, err := h.deps.FileInfos().IsSharing(c, userId, dirPath) + exist, err := h.deps.FileInfos().IsSharing(c, dirPath) if err != nil { if errors.Is(err, db.ErrFileInfoNotFound) { c.JSON(q.Resp(404)) @@ -1090,13 +1085,8 @@ type SharingResp struct { // Deprecated: use ListSharingIDs instead func (h *FileHandlers) ListSharings(c *gin.Context) { // TODO: move canAccess to authedFS - userId, err := q.GetUserId(c) - if err != nil { - c.JSON(q.ErrResp(c, 500, err)) - return - } - - sharingDirs, err := h.deps.FileInfos().ListUserSharings(c, userId) + userName := c.MustGet(q.UserParam).(string) + sharingDirs, err := h.deps.FileInfos().ListSharingsByLocation(c, userName) if err != nil { c.JSON(q.ErrResp(c, 500, err)) return @@ -1114,13 +1104,8 @@ type SharingIDsResp struct { } func (h *FileHandlers) ListSharingIDs(c *gin.Context) { - userId, err := q.GetUserId(c) - if err != nil { - c.JSON(q.ErrResp(c, 500, err)) - return - } - - dirToID, err := h.deps.FileInfos().ListUserSharings(c, userId) + userName := c.MustGet(q.UserParam).(string) + dirToID, err := h.deps.FileInfos().ListSharingsByLocation(c, userName) if err != nil { c.JSON(q.ErrResp(c, 500, err)) return diff --git a/src/server/server_files_test.go b/src/server/server_files_test.go index f577254..8cd039c 100644 --- a/src/server/server_files_test.go +++ b/src/server/server_files_test.go @@ -5,6 +5,7 @@ import ( "fmt" "math/rand" "os" + "path" "path/filepath" "sync" "testing" @@ -73,6 +74,16 @@ func TestFileHandlers(t *testing.T) { token := client.GetCookie(resp.Cookies(), q.TokenCookie) adminFilesClient := client.NewFilesClient(addr, token) + userUsersCl := client.NewUsersClient(addr) + resp, _, errs = userUsersCl.Login("demo", "Quicksh@re") + if len(errs) > 0 { + t.Fatal(errs) + } else if resp.StatusCode != 200 { + t.Fatal(resp.StatusCode) + } + userUsersToken := client.GetCookie(resp.Cookies(), q.TokenCookie) + userFilesCl := client.NewFilesClient(addr, userUsersToken) + var err error // TODO: remove all files under home folder before testing // or the count of files is incorrect @@ -406,16 +417,6 @@ func TestFileHandlers(t *testing.T) { } } - userUsersCl := client.NewUsersClient(addr) - resp, _, errs := userUsersCl.Login("demo", "Quicksh@re") - if len(errs) > 0 { - t.Fatal(errs) - } else if resp.StatusCode != 200 { - t.Fatal(resp.StatusCode) - } - userUsersToken := client.GetCookie(resp.Cookies(), q.TokenCookie) - userFilesCl := client.NewFilesClient(addr, userUsersToken) - for i := 0; i < 2; i++ { // add sharings sharedPaths := map[string]bool{} @@ -471,7 +472,6 @@ func TestFileHandlers(t *testing.T) { } } - fmt.Println("\n\n\n", shRes.IDs) // check isSharing for dirPath := range sharedPaths { res, _, errs := userFilesCl.IsSharing(dirPath) @@ -854,6 +854,54 @@ func TestFileHandlers(t *testing.T) { } }) + t.Run("test sharing for users: AddSharing(admin)-IsSharing(demo)-ListSharing(demo)", func(t *testing.T) { + files := map[string]string{ + "demo/files/share_for/f1.md": "111", + "demo/files/share_for/f2.md": "22222", + } + + for filePath, content := range files { + // uploaded by user + assertUploadOK(t, filePath, content, addr, userUsersToken) + + // shared by admin + fileDir := path.Dir(filePath) + res, _, errs := adminFilesClient.AddSharing(fileDir) + if len(errs) > 0 { + t.Fatal(errs) + } else if res.StatusCode != 200 { + t.Fatal(res.StatusCode) + } + + res, _, errs = userFilesCl.IsSharing(fileDir) + if len(errs) > 0 { + t.Fatal(errs) + } else if res.StatusCode != 200 { // should still be in sharing + t.Fatal(res.StatusCode) + } + + err = fs.Sync() + if err != nil { + t.Fatal(err) + } + + _, lResp, errs := userFilesCl.ListSharings() + if len(errs) > 0 { + t.Fatal(errs) + } + found := false + for _, gotPath := range lResp.SharingDirs { + if fileDir == gotPath { + found = true + break + } + } + if !found { + t.Fatalf("%s not found", filePath) + } + } + }) + compareSearchResults := func(expectedPaths map[string]bool, searchItemsResp []string) bool { if len(expectedPaths) != len(searchItemsResp) { return false