Fix listing shares for file with path belonging to others

This commit is contained in:
Ming Ming 2021-12-04 01:32:38 +08:00
parent e98f4611da
commit 224ab16bf0
3 changed files with 61 additions and 16 deletions

View file

@ -1,16 +1,32 @@
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/debug_util.dart';
import 'package:nc_photos/di_container.dart'; import 'package:nc_photos/di_container.dart';
import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file_util.dart' as file_util;
import 'package:nc_photos/entity/share.dart'; import 'package:nc_photos/entity/share.dart';
import 'package:nc_photos/use_case/find_file.dart';
/// List all shares from a given file /// List all shares from a given file
class ListShare { class ListShare {
ListShare(this._c) : assert(require(_c)); ListShare(this._c) : assert(require(_c));
static bool require(DiContainer c) => DiContainer.has(c, DiType.shareRepo); static bool require(DiContainer c) =>
DiContainer.has(c, DiType.shareRepo) && DiContainer.has(c, DiType.appDb);
Future<List<Share>> call(Account account, File file) => Future<List<Share>> call(Account account, File file) async {
_c.shareRepo.list(account, file); try {
if (file_util.getUserDirName(file) != account.username) {
file = await FindFile(_c.appDb)(account, file.fileId!);
}
} catch (_) {
// file not found
_log.warning("[call] File not found in db: ${logFilename(file.path)}");
}
return _c.shareRepo.list(account, file);
}
final DiContainer _c; final DiContainer _c;
static final _log = Logger("use_case.list_share.ListShare");
} }

View file

@ -9,10 +9,8 @@ import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/album/item.dart'; import 'package:nc_photos/entity/album/item.dart';
import 'package:nc_photos/entity/album/provider.dart'; import 'package:nc_photos/entity/album/provider.dart';
import 'package:nc_photos/entity/file.dart'; import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file_util.dart' as file_util;
import 'package:nc_photos/event/event.dart'; import 'package:nc_photos/event/event.dart';
import 'package:nc_photos/iterable_extension.dart'; import 'package:nc_photos/iterable_extension.dart';
import 'package:nc_photos/use_case/find_file.dart';
import 'package:nc_photos/use_case/list_album.dart'; import 'package:nc_photos/use_case/list_album.dart';
import 'package:nc_photos/use_case/list_share.dart'; import 'package:nc_photos/use_case/list_share.dart';
import 'package:nc_photos/use_case/remove_from_album.dart'; import 'package:nc_photos/use_case/remove_from_album.dart';
@ -98,17 +96,7 @@ class Remove {
for (final e in unshares.entries) { for (final e in unshares.entries) {
try { try {
var file = e.key.file; final shares = await ListShare(_c)(account, e.key.file);
if (file_util.getUserDirName(file) != account.username) {
try {
file = await FindFile(_c.appDb)(account, file.fileId!);
} catch (_) {
// file not found
_log.warning(
"[_cleanUpAlbums] File not found in db: ${logFilename(file.path)}");
}
}
final shares = await ListShare(_c)(account, file);
for (final s in shares.where((s) => e.value.contains(s.shareWith))) { for (final s in shares.where((s) => e.value.contains(s.shareWith))) {
try { try {
await RemoveShare(_c.shareRepo)(account, s); await RemoveShare(_c.shareRepo)(account, s);

View file

@ -17,6 +17,7 @@ void main() {
group("shared album", () { group("shared album", () {
test("file", _removeSharedAlbum); test("file", _removeSharedAlbum);
test("file w/ share in other album", _removeSharedAlbumFileInOtherAlbum); test("file w/ share in other album", _removeSharedAlbumFileInOtherAlbum);
test("file resynced by others", _removeSharedAlbumResyncedFile);
}); });
}); });
} }
@ -119,3 +120,43 @@ Future<void> _removeSharedAlbumFileInOtherAlbum() async {
util.buildShare(id: "2", file: albumFiles[1], shareWith: "user1"), util.buildShare(id: "2", file: albumFiles[1], shareWith: "user1"),
]); ]);
} }
/// Remove a shared album (admin -> user1) where the file is resynced by user1
///
/// Expect: album deleted;
/// share (admin -> user1) for the album json deleted;
/// share (admin -> user1) for the file delete
Future<void> _removeSharedAlbumResyncedFile() async {
final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1");
final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final user1Files = [
files[0].copyWith(path: "remote.php/dav/files/user1/share/test1.jpg"),
];
final album = (util.AlbumBuilder()
..addFileItem(user1Files[0])
..addShare("user1"))
.build();
final albumFile = album.albumFile!;
final c = DiContainer(
albumRepo: MockAlbumMemoryRepo([album]),
fileRepo: MockFileMemoryRepo([albumFile, ...files, ...user1Files]),
shareRepo: MockShareMemoryRepo([
util.buildShare(id: "0", file: albumFile, shareWith: "user1"),
util.buildShare(id: "1", file: files[0], shareWith: "user1"),
]),
appDb: await MockAppDb().applyFuture((obj) async {
await util.fillAppDb(obj, account, files);
await util.fillAppDb(obj, user1Account, user1Files);
}),
pref: Pref.scoped(PrefMemoryProvider({
"isLabEnableSharedAlbum": true,
})),
);
await RemoveAlbum(c)(
account, c.albumMemoryRepo.findAlbumByPath(albumFile.path));
expect(c.fileMemoryRepo.files, [...files, ...user1Files]);
expect(c.shareMemoryRepo.shares, []);
}