Fix user ID and display name mixed up in logic

This commit is contained in:
Ming Ming 2022-07-12 02:14:42 +08:00
parent 413c185290
commit 478c25b5d0
47 changed files with 340 additions and 128 deletions

View file

@ -2,9 +2,8 @@ import 'dart:math';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/ci_string.dart'; import 'package:nc_photos/ci_string.dart';
import 'package:nc_photos/object_extension.dart';
import 'package:nc_photos/or_null.dart';
import 'package:nc_photos/string_extension.dart'; import 'package:nc_photos/string_extension.dart';
import 'package:nc_photos/type.dart'; import 'package:nc_photos/type.dart';
@ -14,9 +13,9 @@ class Account with EquatableMixin {
this.id, this.id,
this.scheme, this.scheme,
String address, String address,
this.username, this.userId,
this.username2,
this.password, this.password,
this.altHomeDir,
List<String> roots, List<String> roots,
) : address = address.trimRightAny("/"), ) : address = address.trimRightAny("/"),
_roots = roots.map((e) => e.trimRightAny("/")).toList() { _roots = roots.map((e) => e.trimRightAny("/")).toList() {
@ -29,18 +28,18 @@ class Account with EquatableMixin {
String? id, String? id,
String? scheme, String? scheme,
String? address, String? address,
CiString? username, CiString? userId,
String? username2,
String? password, String? password,
OrNull<CiString>? altHomeDir,
List<String>? roots, List<String>? roots,
}) { }) {
return Account( return Account(
id ?? this.id, id ?? this.id,
scheme ?? this.scheme, scheme ?? this.scheme,
address ?? this.address, address ?? this.address,
username ?? this.username, userId ?? this.userId,
username2 ?? this.username2,
password ?? this.password, password ?? this.password,
altHomeDir == null ? this.altHomeDir : altHomeDir.obj,
roots ?? List.of(_roots), roots ?? List.of(_roots),
); );
} }
@ -57,49 +56,68 @@ class Account with EquatableMixin {
"id: '$id', " "id: '$id', "
"scheme: '$scheme', " "scheme: '$scheme', "
"address: '${kDebugMode ? address : "***"}', " "address: '${kDebugMode ? address : "***"}', "
"username: '${kDebugMode ? username : "***"}', " "userId: '${kDebugMode ? userId : "***"}', "
"username2: '${kDebugMode ? username2 : "***"}', "
"password: '${password.isNotEmpty == true ? (kDebugMode ? password : '***') : null}', " "password: '${password.isNotEmpty == true ? (kDebugMode ? password : '***') : null}', "
"altHomeDir: '${altHomeDir == null || kDebugMode ? altHomeDir : "***"}', "
"roots: List {'${roots.join('\', \'')}'}, " "roots: List {'${roots.join('\', \'')}'}, "
"}"; "}";
} }
Account.fromJson(JsonObj json) static Account? fromJson(
: id = json["id"], JsonObj json, {
scheme = json["scheme"], required AccountUpgraderV1? upgraderV1,
address = json["address"], }) {
username = CiString(json["username"]), final jsonVersion = json["version"] ?? 1;
password = json["password"], JsonObj? result = json;
altHomeDir = (json["altHomeDir"] as String?)?.run((v) => CiString(v)), if (jsonVersion < 2) {
_roots = json["roots"].cast<String>(); result = upgraderV1?.call(result);
if (result == null) {
_log.info("[fromJson] Version $jsonVersion not compatible");
return null;
}
}
return Account(
result["id"],
result["scheme"],
result["address"],
CiString(result["userId"]),
result["username2"],
result["password"],
result["roots"].cast<String>(),
);
}
JsonObj toJson() => { JsonObj toJson() => {
"version": version,
"id": id, "id": id,
"scheme": scheme, "scheme": scheme,
"address": address, "address": address,
"username": username.toString(), "userId": userId.toString(),
"username2": username2,
"password": password, "password": password,
"altHomeDir": altHomeDir?.toString(),
"roots": _roots, "roots": _roots,
}; };
@override @override
get props => [id, scheme, address, username, password, altHomeDir, _roots]; get props => [id, scheme, address, userId, username2, password, _roots];
List<String> get roots => _roots; List<String> get roots => _roots;
CiString get homeDir => altHomeDir ?? username;
final String id; final String id;
final String scheme; final String scheme;
final String address; final String address;
final CiString username; // For non LDAP users, this is the username used to sign in
final CiString userId;
// Username used to sign in. For non-LDAP users, this is identical to userId
final String username2;
final String password; final String password;
/// Name of the user home dir. Normally [username] is used as the home dir
/// name, but for LDAP users, their home dir might be named differently
final CiString? altHomeDir;
final List<String> _roots; final List<String> _roots;
/// versioning of this class, use to upgrade old persisted accounts
static const version = 2;
static final _log = Logger("account.Account");
} }
extension AccountExtension on Account { extension AccountExtension on Account {
@ -113,6 +131,34 @@ extension AccountExtension on Account {
bool compareServerIdentity(Account other) { bool compareServerIdentity(Account other) {
return scheme == other.scheme && return scheme == other.scheme &&
address == other.address && address == other.address &&
username == other.username; userId == other.userId;
} }
} }
abstract class AccountUpgrader {
JsonObj? call(JsonObj json);
}
class AccountUpgraderV1 implements AccountUpgrader {
const AccountUpgraderV1({
this.logAccountId,
});
@override
call(JsonObj json) {
// clarify user id and display name v1
_log.fine("[call] Upgrade v1 Account: $logAccountId");
final result = JsonObj.of(json);
result["userId"] = json["altHomeDir"] ?? json["username"];
result["username2"] = json["username"];
result
..remove("username")
..remove("altHomeDir");
return result;
}
/// Account ID for logging only
final String? logAccountId;
static final _log = Logger("account.AccountUpgraderV1");
}

View file

@ -38,7 +38,7 @@ class Api {
static String getAuthorizationHeaderValue(Account account) { static String getAuthorizationHeaderValue(Account account) {
final auth = final auth =
base64.encode(utf8.encode("${account.username}:${account.password}")); base64.encode(utf8.encode("${account.username2}:${account.password}"));
return "Basic $auth"; return "Basic $auth";
} }

View file

@ -65,10 +65,10 @@ String getFileUrlRelative(File file) {
} }
String getWebdavRootUrlRelative(Account account) => String getWebdavRootUrlRelative(Account account) =>
"remote.php/dav/files/${account.homeDir}"; "remote.php/dav/files/${account.userId}";
String getTrashbinPath(Account account) => String getTrashbinPath(Account account) =>
"remote.php/dav/trashbin/${account.homeDir}/trash"; "remote.php/dav/trashbin/${account.userId}/trash";
/// Return the face image URL. See [getFacePreviewUrlRelative] /// Return the face image URL. See [getFacePreviewUrlRelative]
String getFacePreviewUrl( String getFacePreviewUrl(

View file

@ -1,7 +1,7 @@
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
String getInstNameForAccount(String className, Account account) => String getInstNameForAccount(String className, Account account) =>
"$className(${account.scheme}://${account.username.toCaseInsensitiveString()}@${account.address})"; "$className(${account.scheme}://${account.userId.toCaseInsensitiveString()}@${account.address})";
String getInstNameForRootAwareAccount(String className, Account account) => String getInstNameForRootAwareAccount(String className, Account account) =>
"$className(${account.scheme}://${account.username.toCaseInsensitiveString()}@${account.address}?${account.roots.join('&')})"; "$className(${account.scheme}://${account.userId.toCaseInsensitiveString()}@${account.address}?${account.roots.join('&')})";

View file

@ -202,9 +202,9 @@ class ListAlbumShareOutlierBloc extends Bloc<ListAlbumShareOutlierBlocEvent,
final albumShares = await () async { final albumShares = await () async {
var temp = (ev.album.shares ?? []) var temp = (ev.album.shares ?? [])
.where((s) => s.userId != ev.account.username) .where((s) => s.userId != ev.account.userId)
.toList(); .toList();
if (ev.album.albumFile!.ownerId != ev.account.username) { if (ev.album.albumFile!.ownerId != ev.account.userId) {
// add owner if the album is not owned by this account // add owner if the album is not owned by this account
final ownerSharee = (await ListSharee(_c.shareeRepo)(ev.account)) final ownerSharee = (await ListSharee(_c.shareeRepo)(ev.account))
.firstWhere((s) => s.shareWith == ev.album.albumFile!.ownerId); .firstWhere((s) => s.shareWith == ev.album.albumFile!.ownerId);
@ -241,7 +241,7 @@ class ListAlbumShareOutlierBloc extends Bloc<ListAlbumShareOutlierBlocEvent,
Map<CiString, AlbumShare> albumShares, Map<CiString, AlbumShare> albumShares,
List<Object> errors, List<Object> errors,
) async { ) async {
if (!album.albumFile!.isOwned(account.username)) { if (!album.albumFile!.isOwned(account.userId)) {
// album file is always managed by the owner // album file is always managed by the owner
return []; return [];
} }
@ -335,7 +335,7 @@ class ListAlbumShareOutlierBloc extends Bloc<ListAlbumShareOutlierBlocEvent,
var missings = managedAlbumSharees var missings = managedAlbumSharees
.difference(allSharees) .difference(allSharees)
// Can't share to ourselves or the file owner // Can't share to ourselves or the file owner
.where((s) => s != account.username && s != fileItem.file.ownerId) .where((s) => s != account.userId && s != fileItem.file.ownerId)
.toList(); .toList();
_log.info( _log.info(
"[_processSingleFileItem] Missing shares: ${missings.toReadableString()} for file: ${logFilename(fileItem.file.path)}"); "[_processSingleFileItem] Missing shares: ${missings.toReadableString()} for file: ${logFilename(fileItem.file.path)}");
@ -348,7 +348,7 @@ class ListAlbumShareOutlierBloc extends Bloc<ListAlbumShareOutlierBlocEvent,
// check owned shares against all album sharees. Use all album sharees such // check owned shares against all album sharees. Use all album sharees such
// that non-managed sharees will not be listed // that non-managed sharees will not be listed
final ownedSharees = shares final ownedSharees = shares
.where((s) => s.uidOwner == account.username) .where((s) => s.uidOwner == account.userId)
.map((s) => s.shareWith!) .map((s) => s.shareWith!)
.toSet(); .toSet();
final extras = ownedSharees.difference(albumSharees); final extras = ownedSharees.difference(albumSharees);
@ -375,13 +375,13 @@ class ListAlbumShareOutlierBloc extends Bloc<ListAlbumShareOutlierBlocEvent,
bool _isItemSharePairOfInterest( bool _isItemSharePairOfInterest(
Account account, Album album, AlbumItem item, AlbumShare share) { Account account, Album album, AlbumItem item, AlbumShare share) {
if (album.albumFile!.isOwned(account.username)) { if (album.albumFile!.isOwned(account.userId)) {
// album owner // album owner
return item.addedBy == account.username || return item.addedBy == account.userId ||
item.addedAt.isBefore(share.sharedAt); item.addedAt.isBefore(share.sharedAt);
} else { } else {
// non album owner // non album owner
if (item.addedBy != account.username) { if (item.addedBy != account.userId) {
return false; return false;
} else { } else {
return share.userId == album.albumFile!.ownerId || return share.userId == album.albumFile!.ownerId ||

View file

@ -469,7 +469,7 @@ class ScanAccountDirBloc
); );
yield files yield files
.where((f) => .where((f) =>
file_util.isSupportedFormat(f) && !f.isOwned(account.username)) file_util.isSupportedFormat(f) && !f.isOwned(account.userId))
.toList(); .toList();
} catch (e, stackTrace) { } catch (e, stackTrace) {
yield ExceptionEvent(e, stackTrace); yield ExceptionEvent(e, stackTrace);

View file

@ -166,7 +166,7 @@ class AlbumSqliteDbDataSource implements AlbumDataSource {
} else { } else {
try { try {
final f = SqliteFileConverter.fromSql( final f = SqliteFileConverter.fromSql(
account.homeDir.toString(), item["file"]); account.userId.toString(), item["file"]);
yield SqliteAlbumConverter.fromSql( yield SqliteAlbumConverter.fromSql(
item["album"], f, item["shares"] ?? []); item["album"], f, item["shares"] ?? []);
} catch (e, stackTrace) { } catch (e, stackTrace) {

View file

@ -181,10 +181,10 @@ class AlbumUpgraderV5 implements AlbumUpgrader {
final CiString addedBy; final CiString addedBy;
if (result.containsKey("albumFile")) { if (result.containsKey("albumFile")) {
addedBy = result["albumFile"]["ownerId"] == null addedBy = result["albumFile"]["ownerId"] == null
? account.username ? account.userId
: CiString(result["albumFile"]["ownerId"]); : CiString(result["albumFile"]["ownerId"]);
} else { } else {
addedBy = albumFile?.ownerId ?? account.username; addedBy = albumFile?.ownerId ?? account.userId;
} }
item["addedBy"] = addedBy.toString(); item["addedBy"] = addedBy.toString();
item["addedAt"] = result["lastUpdated"]; item["addedAt"] = result["lastUpdated"];

View file

@ -465,7 +465,7 @@ extension FileExtension on File {
lastModified ?? lastModified ??
DateTime.now().toUtc(); DateTime.now().toUtc();
bool isOwned(CiString username) => ownerId == null || ownerId == username; bool isOwned(CiString userId) => ownerId == null || ownerId == userId;
/// Return the path of this file with the DAV part stripped /// Return the path of this file with the DAV part stripped
/// ///

View file

@ -72,7 +72,7 @@ class SqliteAlbumConverter {
} }
class SqliteFileConverter { class SqliteFileConverter {
static File fromSql(String homeDir, sql.CompleteFile f) { static File fromSql(String userId, sql.CompleteFile f) {
final metadata = f.image?.run((obj) => Metadata( final metadata = f.image?.run((obj) => Metadata(
lastUpdated: obj.lastUpdated, lastUpdated: obj.lastUpdated,
fileEtag: obj.fileEtag, fileEtag: obj.fileEtag,
@ -81,7 +81,7 @@ class SqliteFileConverter {
exif: obj.exifRaw?.run((e) => Exif.fromJson(jsonDecode(e))), exif: obj.exifRaw?.run((e) => Exif.fromJson(jsonDecode(e))),
)); ));
return File( return File(
path: "remote.php/dav/files/$homeDir/${f.accountFile.relativePath}", path: "remote.php/dav/files/$userId/${f.accountFile.relativePath}",
contentLength: f.file.contentLength, contentLength: f.file.contentLength,
contentType: f.file.contentType, contentType: f.file.contentType,
etag: f.file.etag, etag: f.file.etag,

View file

@ -35,7 +35,7 @@ class CompleteFileCompanion {
extension CompleteFileListExtension on List<CompleteFile> { extension CompleteFileListExtension on List<CompleteFile> {
Future<List<app.File>> convertToAppFile(app.Account account) { Future<List<app.File>> convertToAppFile(app.Account account) {
return map((f) => { return map((f) => {
"homeDir": account.homeDir.toString(), "userId": account.userId.toString(),
"completeFile": f, "completeFile": f,
}).computeAll(_covertSqliteDbFile); }).computeAll(_covertSqliteDbFile);
} }
@ -141,7 +141,7 @@ extension SqliteDbExtension on SqliteDb {
await into(accounts).insert( await into(accounts).insert(
AccountsCompanion.insert( AccountsCompanion.insert(
server: dbServer.rowId, server: dbServer.rowId,
userId: account.username.toCaseInsensitiveString(), userId: account.userId.toCaseInsensitiveString(),
), ),
mode: InsertMode.insertOrIgnore, mode: InsertMode.insertOrIgnore,
); );
@ -153,8 +153,7 @@ extension SqliteDbExtension on SqliteDb {
useColumns: false) useColumns: false)
]) ])
..where(servers.address.equals(account.url)) ..where(servers.address.equals(account.url))
..where( ..where(accounts.userId.equals(account.userId.toCaseInsensitiveString()))
accounts.userId.equals(account.username.toCaseInsensitiveString()))
..limit(1); ..limit(1);
return query.map((r) => r.readTable(accounts)).getSingle(); return query.map((r) => r.readTable(accounts)).getSingle();
} }
@ -522,7 +521,7 @@ class FilesQueryBuilder {
query query
..where(db.servers.address.equals(_appAccount!.url)) ..where(db.servers.address.equals(_appAccount!.url))
..where(db.accounts.userId ..where(db.accounts.userId
.equals(_appAccount!.username.toCaseInsensitiveString())); .equals(_appAccount!.userId.toCaseInsensitiveString()));
} }
if (_byRowId != null) { if (_byRowId != null) {
@ -585,9 +584,9 @@ class FilesQueryBuilder {
} }
app.File _covertSqliteDbFile(Map map) { app.File _covertSqliteDbFile(Map map) {
final homeDir = map["homeDir"] as String; final userId = map["userId"] as String;
final file = map["completeFile"] as CompleteFile; final file = map["completeFile"] as CompleteFile;
return SqliteFileConverter.fromSql(homeDir, file); return SqliteFileConverter.fromSql(userId, file);
} }
CompleteFileCompanion _convertAppFile(Map map) { CompleteFileCompanion _convertAppFile(Map map) {

View file

@ -49,7 +49,7 @@ class MetadataTask {
account, account,
shareFolder, shareFolder,
isRecursive: false, isRecursive: false,
filter: (f) => f.ownerId != account.username, filter: (f) => f.ownerId != account.userId,
)) { )) {
if (!Pref().isEnableExifOr()) { if (!Pref().isEnableExifOr()) {
_log.info("[call] EXIF disabled, task ending immaturely"); _log.info("[call] EXIF disabled, task ending immaturely");

View file

@ -1,8 +1,10 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:collection/collection.dart';
import 'package:event_bus/event_bus.dart'; import 'package:event_bus/event_bus.dart';
import 'package:kiwi/kiwi.dart'; import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart'; import 'package:nc_photos/account.dart';
import 'package:nc_photos/event/event.dart'; import 'package:nc_photos/event/event.dart';
import 'package:nc_photos/mobile/platform.dart' import 'package:nc_photos/mobile/platform.dart'
@ -26,7 +28,19 @@ class Pref {
List<Account>? getAccounts3() { List<Account>? getAccounts3() {
final jsonObjs = provider.getStringList(PrefKey.accounts3); final jsonObjs = provider.getStringList(PrefKey.accounts3);
return jsonObjs?.map((e) => Account.fromJson(jsonDecode(e))).toList(); return jsonObjs
?.map((e) => Account.fromJson(
jsonDecode(e),
upgraderV1: const AccountUpgraderV1(),
))
.where((e) {
if (e == null) {
_log.shout("[getAccounts3] Failed upgrading account");
}
return true;
})
.whereNotNull()
.toList();
} }
List<Account> getAccounts3Or(List<Account> def) => getAccounts3() ?? def; List<Account> getAccounts3Or(List<Account> def) => getAccounts3() ?? def;
@ -235,6 +249,8 @@ class Pref {
final PrefProvider provider; final PrefProvider provider;
static Pref? _inst; static Pref? _inst;
static final _log = Logger("pref.Pref");
} }
class AccountPref { class AccountPref {

View file

@ -277,7 +277,7 @@ class _MetadataTask {
account, account,
shareFolder, shareFolder,
isRecursive: false, isRecursive: false,
filter: (f) => f.ownerId != account.username, filter: (f) => f.ownerId != account.userId,
)) { )) {
if (ev is File) { if (ev is File) {
_onFileProcessed(ev); _onFileProcessed(ev);

View file

@ -108,9 +108,9 @@ class TouchTokenManager {
String _getLocalStorageName(Account account, File file) { String _getLocalStorageName(Account account, File file) {
final strippedPath = file.strippedPath; final strippedPath = file.strippedPath;
if (strippedPath == ".") { if (strippedPath == ".") {
return "touch/${account.url.replaceFirst('://', '_')}/${account.username}/token"; return "touch/${account.url.replaceFirst('://', '_')}/${account.userId}/token";
} else { } else {
return "touch/${account.url.replaceFirst('://', '_')}/${account.username}/${file.strippedPath}/token"; return "touch/${account.url.replaceFirst('://', '_')}/${account.userId}/${file.strippedPath}/token";
} }
} }

View file

@ -72,8 +72,8 @@ class AddToAlbum {
Future<void> _shareFiles( Future<void> _shareFiles(
Account account, Album album, List<File> files) async { Account account, Album album, List<File> files) async {
final albumShares = (album.shares!.map((e) => e.userId).toList() final albumShares = (album.shares!.map((e) => e.userId).toList()
..add(album.albumFile!.ownerId ?? account.username)) ..add(album.albumFile!.ownerId ?? account.userId))
.where((element) => element != account.username) .where((element) => element != account.userId)
.toSet(); .toSet();
if (albumShares.isEmpty) { if (albumShares.isEmpty) {
return; return;

View file

@ -28,7 +28,7 @@ class ListPotentialSharedAlbum {
return results; return results;
} }
bool _checkOwner(Account account, File f) => !f.isOwned(account.username); bool _checkOwner(Account account, File f) => !f.isOwned(account.userId);
bool _checkFileName(File f) { bool _checkFileName(File f) {
try { try {

View file

@ -21,7 +21,7 @@ class ListShare {
bool? isIncludeReshare, bool? isIncludeReshare,
}) async { }) async {
try { try {
if (file_util.getUserDirName(file) != account.homeDir) { if (file_util.getUserDirName(file) != account.userId) {
file = (await FindFile(_c)(account, [file.fileId!])).first; file = (await FindFile(_c)(account, [file.fileId!])).first;
} }
} catch (_) { } catch (_) {

View file

@ -51,7 +51,7 @@ class PopulateAlbum {
continue; continue;
} }
products.addAll((result as List).cast<File>().map((f) => AlbumFileItem( products.addAll((result as List).cast<File>().map((f) => AlbumFileItem(
addedBy: account.username, addedBy: account.userId,
addedAt: DateTime.now(), addedAt: DateTime.now(),
file: f, file: f,
))); )));
@ -68,7 +68,7 @@ class PopulateAlbum {
final c = KiwiContainer().resolve<DiContainer>(); final c = KiwiContainer().resolve<DiContainer>();
final files = await ListTaggedFile(c)(account, provider.tags); final files = await ListTaggedFile(c)(account, provider.tags);
products.addAll(files.map((f) => AlbumFileItem( products.addAll(files.map((f) => AlbumFileItem(
addedBy: account.username, addedBy: account.userId,
addedAt: DateTime.now(), addedAt: DateTime.now(),
file: f, file: f,
))); )));
@ -87,7 +87,7 @@ class PopulateAlbum {
return files return files
.where((f) => file_util.isSupportedFormat(f)) .where((f) => file_util.isSupportedFormat(f))
.map((f) => AlbumFileItem( .map((f) => AlbumFileItem(
addedBy: account.username, addedBy: account.userId,
addedAt: DateTime.now(), addedAt: DateTime.now(),
file: f, file: f,
)) ))

View file

@ -65,8 +65,8 @@ class Remove {
final itemsToRemove = provider.items final itemsToRemove = provider.items
.whereType<AlbumFileItem>() .whereType<AlbumFileItem>()
.where((i) => .where((i) =>
(i.file.isOwned(account.username) || (i.file.isOwned(account.userId) ||
i.addedBy == account.username) && i.addedBy == account.userId) &&
removes.any((r) => r.compareServerIdentity(i.file))) removes.any((r) => r.compareServerIdentity(i.file)))
.toList(); .toList();
if (itemsToRemove.isEmpty) { if (itemsToRemove.isEmpty) {
@ -76,7 +76,7 @@ class Remove {
final key = FileServerIdentityComparator(i.file); final key = FileServerIdentityComparator(i.file);
final value = (a.shares?.map((s) => s.userId).toList() ?? []) final value = (a.shares?.map((s) => s.userId).toList() ?? [])
..add(a.albumFile!.ownerId!) ..add(a.albumFile!.ownerId!)
..remove(account.username); ..remove(account.userId);
(unshares[key] ??= <CiString>{}).addAll(value); (unshares[key] ??= <CiString>{}).addAll(value);
} }
_log.fine( _log.fine(

View file

@ -51,8 +51,8 @@ class RemoveAlbum {
return; return;
} }
final albumShares = (album.shares!.map((e) => e.userId).toList() final albumShares = (album.shares!.map((e) => e.userId).toList()
..add(album.albumFile!.ownerId ?? account.username)) ..add(album.albumFile!.ownerId ?? account.userId))
.where((element) => element != account.username) .where((element) => element != account.userId)
.toList(); .toList();
if (albumShares.isEmpty) { if (albumShares.isEmpty) {
return; return;

View file

@ -103,8 +103,8 @@ class RemoveFromAlbum {
Future<void> _unshareFiles( Future<void> _unshareFiles(
Account account, Album album, List<File> files) async { Account account, Album album, List<File> files) async {
final albumShares = (album.shares!.map((e) => e.userId).toList() final albumShares = (album.shares!.map((e) => e.userId).toList()
..add(album.albumFile!.ownerId ?? account.username)) ..add(album.albumFile!.ownerId ?? account.userId))
.where((element) => element != account.username) .where((element) => element != account.userId)
.toList(); .toList();
if (albumShares.isNotEmpty) { if (albumShares.isNotEmpty) {
await UnshareFileFromAlbum(_c)(account, album, files, albumShares); await UnshareFileFromAlbum(_c)(account, album, files, albumShares);

View file

@ -17,7 +17,7 @@ class RestoreTrashbin {
await Move(_c)( await Move(_c)(
account, account,
file, file,
"remote.php/dav/trashbin/${account.homeDir}/restore/${file.filename}", "remote.php/dav/trashbin/${account.userId}/restore/${file.filename}",
shouldOverwrite: true, shouldOverwrite: true,
); );
KiwiContainer() KiwiContainer()

View file

@ -50,8 +50,7 @@ class ScanDirOffline {
.get(); .get();
}); });
return dbFiles return dbFiles
.map( .map((f) => SqliteFileConverter.fromSql(account.userId.toString(), f))
(f) => SqliteFileConverter.fromSql(account.homeDir.toString(), f))
.toList(); .toList();
}); });
} }

View file

@ -45,7 +45,7 @@ class _AccountPickerDialogState extends State<AccountPickerDialog> {
child: ListTile( child: ListTile(
dense: true, dense: true,
title: Text(label ?? a.url), title: Text(label ?? a.url),
subtitle: label == null ? Text(a.username.toString()) : null, subtitle: label == null ? Text(a.username2) : null,
trailing: IconButton( trailing: IconButton(
icon: Icon( icon: Icon(
Icons.close, Icons.close,
@ -87,7 +87,7 @@ class _AccountPickerDialogState extends State<AccountPickerDialog> {
), ),
subtitle: accountLabel == null subtitle: accountLabel == null
? Text( ? Text(
widget.account.username.toString(), widget.account.username2,
style: const TextStyle(fontWeight: FontWeight.bold), style: const TextStyle(fontWeight: FontWeight.bold),
) )
: null, : null,

View file

@ -133,7 +133,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
@override @override
@protected @protected
get canEdit => _album?.albumFile?.isOwned(widget.account.username) == true; get canEdit => _album?.albumFile?.isOwned(widget.account.userId) == true;
@override @override
enterEditMode() { enterEditMode() {
@ -274,7 +274,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
widget.account, widget.account,
_album!, _album!,
actions: [ actions: [
if (_album!.albumFile!.isOwned(widget.account.username) && if (_album!.albumFile!.isOwned(widget.account.userId) &&
Pref().isLabEnableSharedAlbumOr(false)) Pref().isLabEnableSharedAlbumOr(false))
IconButton( IconButton(
onPressed: () => _onSharePressed(context), onPressed: () => _onSharePressed(context),
@ -462,8 +462,8 @@ class _AlbumBrowserState extends State<AlbumBrowser>
.takeIndex(selectedIndexes) .takeIndex(selectedIndexes)
// can only remove owned files // can only remove owned files
.where((element) => .where((element) =>
_album!.albumFile!.isOwned(widget.account.username) == true || _album!.albumFile!.isOwned(widget.account.userId) == true ||
element.addedBy == widget.account.username) element.addedBy == widget.account.userId)
.toList(); .toList();
setState(() { setState(() {
clearSelectedItems(); clearSelectedItems();
@ -668,7 +668,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
provider: AlbumStaticProvider.of(_editAlbum!).copyWith( provider: AlbumStaticProvider.of(_editAlbum!).copyWith(
items: [ items: [
AlbumLabelItem( AlbumLabelItem(
addedBy: widget.account.username, addedBy: widget.account.userId,
addedAt: DateTime.now(), addedAt: DateTime.now(),
text: value, text: value,
), ),
@ -822,7 +822,7 @@ class _AlbumBrowserState extends State<AlbumBrowser>
Future<void> _setAlbum(Album album) async { Future<void> _setAlbum(Album album) async {
assert(album.provider is AlbumStaticProvider); assert(album.provider is AlbumStaticProvider);
final items = await PreProcessAlbum(_c)(widget.account, album); final items = await PreProcessAlbum(_c)(widget.account, album);
if (album.albumFile!.isOwned(widget.account.username)) { if (album.albumFile!.isOwned(widget.account.userId)) {
album = await _updateAlbumPostResync(album, items); album = await _updateAlbumPostResync(album, items);
} }
album = album.copyWith( album = album.copyWith(
@ -858,14 +858,13 @@ class _AlbumBrowserState extends State<AlbumBrowser>
} }
bool get _canRemoveSelection { bool get _canRemoveSelection {
if (_album!.albumFile!.isOwned(widget.account.username) == true) { if (_album!.albumFile!.isOwned(widget.account.userId) == true) {
return true; return true;
} }
final selectedIndexes = final selectedIndexes =
selectedListItems.whereType<_ListItem>().map((e) => e.index).toList(); selectedListItems.whereType<_ListItem>().map((e) => e.index).toList();
final selectedItemsIt = _sortedItems.takeIndex(selectedIndexes); final selectedItemsIt = _sortedItems.takeIndex(selectedIndexes);
return selectedItemsIt return selectedItemsIt.any((item) => item.addedBy == widget.account.userId);
.any((item) => item.addedBy == widget.account.username);
} }
static List<AlbumItem> _getAlbumItemsOf(Album a) => static List<AlbumItem> _getAlbumItemsOf(Album a) =>

View file

@ -198,10 +198,10 @@ class _ConnectState extends State<Connect> {
Future<void> _onCheckWebDavUrlFailed( Future<void> _onCheckWebDavUrlFailed(
BuildContext context, Account account) async { BuildContext context, Account account) async {
final altHomeDir = await _askWebDavUrl(context, account); final userId = await _askWebDavUrl(context, account);
if (altHomeDir != null) { if (userId != null) {
final newAccount = account.copyWith( final newAccount = account.copyWith(
altHomeDir: OrNull(altHomeDir.toCi()), userId: userId.toCi(),
); );
return _checkWebDavUrl(context, newAccount); return _checkWebDavUrl(context, newAccount);
} }
@ -286,9 +286,9 @@ class _WebDavUrlDialogState extends State<_WebDavUrlDialog> {
return L10n.global().homeFolderInputInvalidEmpty; return L10n.global().homeFolderInputInvalidEmpty;
}, },
onSaved: (value) { onSaved: (value) {
_formValue.altHomeDir = value!.trimAny("/"); _formValue.userId = value!.trimAny("/");
}, },
initialValue: widget.account.homeDir.toString(), initialValue: widget.account.userId.toString(),
), ),
], ],
), ),
@ -309,7 +309,7 @@ class _WebDavUrlDialogState extends State<_WebDavUrlDialog> {
void _onOkPressed() { void _onOkPressed() {
if (_formKey.currentState?.validate() == true) { if (_formKey.currentState?.validate() == true) {
_formKey.currentState!.save(); _formKey.currentState!.save();
Navigator.of(context).pop(_formValue.altHomeDir); Navigator.of(context).pop(_formValue.userId);
} }
} }
@ -322,5 +322,5 @@ class _WebDavUrlDialogState extends State<_WebDavUrlDialog> {
} }
class _FormValue { class _FormValue {
late String altHomeDir; late String userId;
} }

View file

@ -127,7 +127,7 @@ class _DynamicAlbumBrowserState extends State<DynamicAlbumBrowser>
@override @override
@protected @protected
get canEdit => _album?.albumFile?.isOwned(widget.account.username) == true; get canEdit => _album?.albumFile?.isOwned(widget.account.userId) == true;
@override @override
enterEditMode() { enterEditMode() {

View file

@ -34,7 +34,7 @@ class AddSelectionToAlbumHandler {
assert(value.provider is AlbumStaticProvider); assert(value.provider is AlbumStaticProvider);
final selected = selectedFiles final selected = selectedFiles
.map((f) => AlbumFileItem( .map((f) => AlbumFileItem(
addedBy: account.username, addedBy: account.userId,
addedAt: DateTime.now(), addedAt: DateTime.now(),
file: f, file: f,
)) ))

View file

@ -462,7 +462,7 @@ class _HomeAlbumsState extends State<HomeAlbums>
final failures = <Album>[]; final failures = <Album>[];
for (final a in selected) { for (final a in selected) {
try { try {
if (a.albumFile?.isOwned(widget.account.username) == true) { if (a.albumFile?.isOwned(widget.account.userId) == true) {
// delete owned albums // delete owned albums
await RemoveAlbum(KiwiContainer().resolve<DiContainer>())( await RemoveAlbum(KiwiContainer().resolve<DiContainer>())(
widget.account, a); widget.account, a);

View file

@ -63,7 +63,7 @@ class HomeSliverAppBar extends StatelessWidget {
), ),
if (accountLabel == null) if (accountLabel == null)
Text( Text(
account.username.toString(), account.username2,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: AppTheme.getSecondaryTextColor(context), color: AppTheme.getSecondaryTextColor(context),

View file

@ -225,7 +225,7 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
void _transformShareeItems(List<Sharee> sharees) { void _transformShareeItems(List<Sharee> sharees) {
final candidates = sharees final candidates = sharees
.where((s) => .where((s) =>
s.shareWith != widget.account.username && s.shareWith != widget.account.userId &&
// remove users already shared with // remove users already shared with
!_items.any((i) => i.shareWith == s.shareWith)) !_items.any((i) => i.shareWith == s.shareWith))
.toList(); .toList();

View file

@ -129,7 +129,7 @@ class _SharedFileViewerState extends State<SharedFileViewer> {
title: Text(widget.file.strippedPath), title: Text(widget.file.strippedPath),
), ),
), ),
if (widget.shares.first.uidOwner == widget.account.username) ...[ if (widget.shares.first.uidOwner == widget.account.userId) ...[
SliverToBoxAdapter( SliverToBoxAdapter(
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),

View file

@ -202,7 +202,7 @@ class _SharingBrowserState extends State<SharingBrowser> {
), ),
), ),
label: shares.first.share.filename, label: shares.first.share.filename,
description: shares.first.share.uidOwner == widget.account.username description: shares.first.share.uidOwner == widget.account.userId
? L10n.global().fileLastSharedDescription(dateStr) ? L10n.global().fileLastSharedDescription(dateStr)
: L10n.global().fileLastSharedByOthersDescription( : L10n.global().fileLastSharedByOthersDescription(
shares.first.share.displaynameOwner, dateStr), shares.first.share.displaynameOwner, dateStr),
@ -260,7 +260,7 @@ class _SharingBrowserState extends State<SharingBrowser> {
), ),
), ),
label: firstItem.album.name, label: firstItem.album.name,
description: shares.first.share.uidOwner == widget.account.username description: shares.first.share.uidOwner == widget.account.userId
? L10n.global().fileLastSharedDescription(dateStr) ? L10n.global().fileLastSharedDescription(dateStr)
: L10n.global().albumLastSharedByOthersDescription( : L10n.global().albumLastSharedByOthersDescription(
shares.first.share.displaynameOwner, dateStr), shares.first.share.displaynameOwner, dateStr),
@ -307,7 +307,7 @@ class _SharingBrowserState extends State<SharingBrowser> {
// group shares of the same file // group shares of the same file
final map = <String, List<ListSharingItem>>{}; final map = <String, List<ListSharingItem>>{};
for (final i in items) { for (final i in items) {
final isSharedByMe = (i.share.uidOwner == widget.account.username); final isSharedByMe = (i.share.uidOwner == widget.account.userId);
final groupKey = "${i.share.path}?$isSharedByMe"; final groupKey = "${i.share.path}?$isSharedByMe";
map[groupKey] ??= <ListSharingItem>[]; map[groupKey] ??= <ListSharingItem>[];
map[groupKey]!.add(i); map[groupKey]!.add(i);

View file

@ -238,8 +238,8 @@ class _SignInState extends State<SignIn> {
_formValue.scheme, _formValue.scheme,
_formValue.address, _formValue.address,
_formValue.username.toCi(), _formValue.username.toCi(),
_formValue.username,
_formValue.password, _formValue.password,
null,
[""], [""],
); );
_log.info("[_connect] Try connecting with account: $account"); _log.info("[_connect] Try connecting with account: $account");

View file

@ -149,7 +149,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
onPressed: () => _onRemoveFromAlbumPressed(context), onPressed: () => _onRemoveFromAlbumPressed(context),
), ),
if (widget.album != null && if (widget.album != null &&
widget.album!.albumFile?.isOwned(widget.account.username) == widget.album!.albumFile?.isOwned(widget.account.userId) ==
true) true)
_DetailPaneButton( _DetailPaneButton(
icon: Icons.photo_album_outlined, icon: Icons.photo_album_outlined,
@ -195,7 +195,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
title: Text(path_lib.basenameWithoutExtension(widget.file.path)), title: Text(path_lib.basenameWithoutExtension(widget.file.path)),
subtitle: Text(widget.file.strippedPath), subtitle: Text(widget.file.strippedPath),
), ),
if (!widget.file.isOwned(widget.account.username)) if (!widget.file.isOwned(widget.account.userId))
ListTile( ListTile(
leading: ListTileCenterLeading( leading: ListTileCenterLeading(
child: Icon( child: Icon(
@ -509,7 +509,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
widget.album!.provider is! AlbumStaticProvider) { widget.album!.provider is! AlbumStaticProvider) {
return false; return false;
} }
if (widget.album!.albumFile?.isOwned(widget.account.username) == true) { if (widget.album!.albumFile?.isOwned(widget.account.userId) == true) {
return true; return true;
} }
try { try {
@ -518,7 +518,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
.whereType<AlbumFileItem>() .whereType<AlbumFileItem>()
.firstWhere( .firstWhere(
(element) => element.file.compareServerIdentity(widget.file)); (element) => element.file.compareServerIdentity(widget.file));
if (thisItem.addedBy == widget.account.username) { if (thisItem.addedBy == widget.account.userId) {
return true; return true;
} }
} catch (_) {} } catch (_) {}

152
app/test/account_test.dart Normal file
View file

@ -0,0 +1,152 @@
import 'package:nc_photos/account.dart';
import 'package:nc_photos/ci_string.dart';
import 'package:test/test.dart';
void main() {
group("Account", () {
group("constructor", () {
test("trim address", _constructTrimAddress);
test("invalid scheme", _constructInvalidScheme);
});
test("fromJson", _fromJson);
});
group("AccountUpgraderV1", () {
test("normal", _upgraderV1);
test("ldap", _upgraderV1Ldap);
});
}
/// Convert json obj to Account
///
/// Expect: Account constructed
void _fromJson() {
final json = <String, dynamic>{
"version": Account.version,
"id": "123456",
"scheme": "https",
"address": "example.com",
"userId": "00000000-1111-aaaa-bbbb-223344ccddee",
"username2": "admin",
"password": "123456",
"roots": ["test1", "test2"],
};
expect(
Account.fromJson(
json,
upgraderV1: null,
),
Account(
"123456",
"https",
"example.com",
"00000000-1111-aaaa-bbbb-223344ccddee".toCi(),
"admin",
"123456",
["test1", "test2"],
),
);
}
/// Upgrade v1 Account json to v2 Account json
///
/// Expect: v2.userId = v1.username;
/// v2.username2 = v1.username
void _upgraderV1() {
final json = <String, dynamic>{
"version": 1,
"id": "123456",
"scheme": "https",
"address": "example.com",
"username": "admin",
"password": "123456",
"roots": ["test1", "test2"],
};
expect(
const AccountUpgraderV1()(json),
<String, dynamic>{
"version": 1,
"id": "123456",
"scheme": "https",
"address": "example.com",
"userId": "admin",
"username2": "admin",
"password": "123456",
"roots": ["test1", "test2"],
},
);
}
/// Upgrade v1 Account json to v2 Account json for a LDAP account
///
/// Expect: v2.userId = v1.altHomeDir;
/// v2.username2 = v1.username
void _upgraderV1Ldap() {
final json = <String, dynamic>{
"version": 1,
"id": "123456",
"scheme": "https",
"address": "example.com",
"username": "admin",
"altHomeDir": "00000000-1111-aaaa-bbbb-223344ccddee",
"password": "123456",
"roots": ["test1", "test2"],
};
expect(
const AccountUpgraderV1()(json),
<String, dynamic>{
"version": 1,
"id": "123456",
"scheme": "https",
"address": "example.com",
"userId": "00000000-1111-aaaa-bbbb-223344ccddee",
"username2": "admin",
"password": "123456",
"roots": ["test1", "test2"],
},
);
}
/// Construct a new Account, with address ending with /
///
/// Expect: Account constructed;
/// Trailing / in address removed
void _constructTrimAddress() {
expect(
Account(
"123456",
"https",
"example.com/",
"00000000-1111-aaaa-bbbb-223344ccddee".toCi(),
"admin",
"123456",
["test1", "test2"],
),
Account(
"123456",
"https",
"example.com",
"00000000-1111-aaaa-bbbb-223344ccddee".toCi(),
"admin",
"123456",
["test1", "test2"],
),
);
}
/// Construct a new Account, with scheme != http/https
///
/// Expect: FormatException
void _constructInvalidScheme() {
expect(
() => Account(
"123456",
"ssh",
"example.com/",
"00000000-1111-aaaa-bbbb-223344ccddee".toCi(),
"admin",
"123456",
["test1", "test2"],
),
throwsFormatException,
);
}

View file

@ -254,7 +254,7 @@ void _testQuerySharedAlbumMissingManagedShareOtherAdded(String description) {
/// Expect: emit empty list /// Expect: emit empty list
void _testQuerySharedAlbumMissingManagedShareOtherReshared(String description) { void _testQuerySharedAlbumMissingManagedShareOtherReshared(String description) {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build(); (util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final user1Files = [ final user1Files = [
@ -450,7 +450,7 @@ void _testQuerySharedAlbumExtraShare(String description) {
/// Expect: emit the file with extra share (admin -> user2) /// Expect: emit the file with extra share (admin -> user2)
void _testQuerySharedAlbumExtraShareOtherAdded(String description) { void _testQuerySharedAlbumExtraShareOtherAdded(String description) {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder(initialFileId: 1) final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("admin/test1.jpg", ownerId: "user1")) ..addJpeg("admin/test1.jpg", ownerId: "user1"))
.build(); .build();
@ -510,7 +510,7 @@ void _testQuerySharedAlbumExtraShareOtherAdded(String description) {
/// Expect: emit empty list /// Expect: emit empty list
void _testQuerySharedAlbumExtraUnmanagedShare(String description) { void _testQuerySharedAlbumExtraUnmanagedShare(String description) {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder(initialFileId: 1) final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("admin/test1.jpg", ownerId: "user1")) ..addJpeg("admin/test1.jpg", ownerId: "user1"))
.build(); .build();

View file

@ -1484,7 +1484,7 @@ void main() {
}); });
group("AlbumUpgraderV5", () { group("AlbumUpgraderV5", () {
final account = util.buildAccount(username: "user1"); final account = util.buildAccount(userId: "user1");
test("w/ ownerId", () { test("w/ ownerId", () {
final json = <String, dynamic>{ final json = <String, dynamic>{

View file

@ -347,7 +347,7 @@ Future<void> _updaterUpdateFile() async {
/// Expect: file added to AccountFiles table /// Expect: file added to AccountFiles table
Future<void> _updaterNewSharedFile() async { Future<void> _updaterNewSharedFile() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder() final files = (util.FilesBuilder()
..addDir("admin") ..addDir("admin")
..addJpeg("admin/test1.jpg") ..addJpeg("admin/test1.jpg")
@ -385,7 +385,7 @@ Future<void> _updaterNewSharedFile() async {
/// Expect: file added to AccountFiles table /// Expect: file added to AccountFiles table
Future<void> _updaterNewSharedDir() async { Future<void> _updaterNewSharedDir() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder() final files = (util.FilesBuilder()
..addDir("admin") ..addDir("admin")
..addJpeg("admin/test1.jpg", ownerId: "user1") ..addJpeg("admin/test1.jpg", ownerId: "user1")
@ -423,7 +423,7 @@ Future<void> _updaterNewSharedDir() async {
/// file remained in Files table /// file remained in Files table
Future<void> _updaterDeleteSharedFile() async { Future<void> _updaterDeleteSharedFile() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder() final files = (util.FilesBuilder()
..addDir("admin") ..addDir("admin")
..addJpeg("admin/test1.jpg") ..addJpeg("admin/test1.jpg")
@ -465,7 +465,7 @@ Future<void> _updaterDeleteSharedFile() async {
/// file remained in Files table /// file remained in Files table
Future<void> _updaterDeleteSharedDir() async { Future<void> _updaterDeleteSharedDir() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder() final files = (util.FilesBuilder()
..addDir("admin") ..addDir("admin")
..addJpeg("admin/test1.jpg") ..addJpeg("admin/test1.jpg")

View file

@ -328,7 +328,7 @@ class MockShareMemoryRepo extends MockShareRepo {
return shares.where((s) { return shares.where((s) {
if (s.itemSource != file.fileId) { if (s.itemSource != file.fileId) {
return false; return false;
} else if (isIncludeReshare == true || s.uidOwner == account.username) { } else if (isIncludeReshare == true || s.uidOwner == account.userId) {
return true; return true;
} else { } else {
return false; return false;
@ -342,8 +342,8 @@ class MockShareMemoryRepo extends MockShareRepo {
id: (_id++).toString(), id: (_id++).toString(),
shareType: ShareType.user, shareType: ShareType.user,
stime: DateTime.utc(2020, 1, 2, 3, 4, 5), stime: DateTime.utc(2020, 1, 2, 3, 4, 5),
uidOwner: account.username, uidOwner: account.userId,
displaynameOwner: account.username.toString(), displaynameOwner: account.username2,
uidFileOwner: file.ownerId!, uidFileOwner: file.ownerId!,
path: file.strippedPath, path: file.strippedPath,
itemType: ShareItemType.file, itemType: ShareItemType.file,
@ -383,7 +383,7 @@ class MockShareeMemoryRepo extends MockShareeRepo {
@override @override
list(Account account) async { list(Account account) async {
return sharees.where((s) => s.shareWith != account.username).toList(); return sharees.where((s) => s.shareWith != account.userId).toList();
} }
final List<Sharee> sharees; final List<Sharee> sharees;

View file

@ -286,11 +286,12 @@ Account buildAccount({
String id = "123456-000000", String id = "123456-000000",
String scheme = "http", String scheme = "http",
String address = "example.com", String address = "example.com",
String username = "admin", String userId = "admin",
String username2 = "admin",
String password = "pass", String password = "pass",
List<String> roots = const [""], List<String> roots = const [""],
}) => }) =>
Account(id, scheme, address, username.toCi(), password, null, roots); Account(id, scheme, address, userId.toCi(), username2, password, roots);
/// Build a mock [File] pointing to a album JSON file /// Build a mock [File] pointing to a album JSON file
/// ///

View file

@ -187,7 +187,7 @@ Future<void> _addExistingFile() async {
/// Expect: file not added to album /// Expect: file not added to album
Future<void> _addExistingSharedFile() async { Future<void> _addExistingSharedFile() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build(); (util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final user1Files = [ final user1Files = [

View file

@ -131,7 +131,7 @@ Future<void> _removeSharedAlbumFileInOtherAlbum() async {
/// share (admin -> user1) for the file delete /// share (admin -> user1) for the file delete
Future<void> _removeSharedAlbumResyncedFile() async { Future<void> _removeSharedAlbumResyncedFile() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = final files =
(util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build(); (util.FilesBuilder(initialFileId: 1)..addJpeg("admin/test1.jpg")).build();
final user1Files = [ final user1Files = [

View file

@ -291,7 +291,7 @@ Future<void> _removeFromSharedAlbumOwned() async {
/// unchanged /// unchanged
Future<void> _removeFromSharedAlbumOwnedWithOtherShare() async { Future<void> _removeFromSharedAlbumOwnedWithOtherShare() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder(initialFileId: 1) final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("user1/test1.jpg", ownerId: "user1")) ..addJpeg("user1/test1.jpg", ownerId: "user1"))
.build(); .build();

View file

@ -238,7 +238,7 @@ Future<void> _removeSharedAlbumFile() async {
/// file share (admin -> user2) deleted /// file share (admin -> user2) deleted
Future<void> _removeSharedAlbumSharedFile() async { Future<void> _removeSharedAlbumSharedFile() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder(initialFileId: 1) final files = (util.FilesBuilder(initialFileId: 1)
..addJpeg("admin/test1.jpg", ownerId: "user1")) ..addJpeg("admin/test1.jpg", ownerId: "user1"))
.build(); .build();

View file

@ -116,7 +116,7 @@ Future<void> _unsupportedFile() async {
/// Expect: user1/test1.jpg, user1/test/test2.jpg /// Expect: user1/test1.jpg, user1/test/test2.jpg
Future<void> _multiAccountRoot() async { Future<void> _multiAccountRoot() async {
final account = util.buildAccount(); final account = util.buildAccount();
final user1Account = util.buildAccount(username: "user1"); final user1Account = util.buildAccount(userId: "user1");
final files = (util.FilesBuilder() final files = (util.FilesBuilder()
..addJpeg("admin/test1.jpg") ..addJpeg("admin/test1.jpg")
..addJpeg("admin/test/test2.jpg")) ..addJpeg("admin/test/test2.jpg"))