mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-13 18:58:53 +01:00
Disallow updating album with a newer version
This commit is contained in:
parent
3527e96f7a
commit
50599f2ba5
6 changed files with 65 additions and 7 deletions
|
@ -28,6 +28,13 @@ import 'package:tuple/tuple.dart';
|
|||
|
||||
/// Immutable object that represents an album
|
||||
class Album with EquatableMixin {
|
||||
/// Create a new album
|
||||
///
|
||||
/// If [lastUpdated] is null, the current time will be used.
|
||||
///
|
||||
/// [savedVersion] should be null when creating a new album, such that it'll
|
||||
/// be filled with the current version number automatically. You should only
|
||||
/// pass this argument when reading album from storage
|
||||
Album({
|
||||
DateTime? lastUpdated,
|
||||
required this.name,
|
||||
|
@ -36,7 +43,9 @@ class Album with EquatableMixin {
|
|||
required this.sortProvider,
|
||||
this.shares,
|
||||
this.albumFile,
|
||||
}) : lastUpdated = (lastUpdated ?? DateTime.now()).toUtc();
|
||||
int? savedVersion,
|
||||
}) : lastUpdated = (lastUpdated ?? DateTime.now()).toUtc(),
|
||||
savedVersion = savedVersion ?? version;
|
||||
|
||||
static Album? fromJson(
|
||||
JsonObj json, {
|
||||
|
@ -79,6 +88,17 @@ class Album with EquatableMixin {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
if (jsonVersion < 7) {
|
||||
result = upgraderFactory?.buildV6()?.call(result);
|
||||
if (result == null) {
|
||||
_log.info("[fromJson] Version $jsonVersion not compatible");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (jsonVersion > version) {
|
||||
_log.warning(
|
||||
"[fromJson] Reading album with newer version: $jsonVersion > $version");
|
||||
}
|
||||
return Album(
|
||||
lastUpdated: result["lastUpdated"] == null
|
||||
? null
|
||||
|
@ -96,6 +116,7 @@ class Album with EquatableMixin {
|
|||
albumFile: result["albumFile"] == null
|
||||
? null
|
||||
: File.fromJson(result["albumFile"].cast<String, dynamic>()),
|
||||
savedVersion: result["version"],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -135,6 +156,7 @@ class Album with EquatableMixin {
|
|||
sortProvider: sortProvider ?? this.sortProvider,
|
||||
shares: shares == null ? this.shares : shares.obj,
|
||||
albumFile: albumFile == null ? this.albumFile : albumFile.obj,
|
||||
savedVersion: savedVersion,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -173,6 +195,7 @@ class Album with EquatableMixin {
|
|||
sortProvider,
|
||||
shares,
|
||||
albumFile,
|
||||
savedVersion,
|
||||
];
|
||||
|
||||
final DateTime lastUpdated;
|
||||
|
@ -188,6 +211,11 @@ class Album with EquatableMixin {
|
|||
/// This field is typically only meaningful when returned by [AlbumRepo.get]
|
||||
final File? albumFile;
|
||||
|
||||
/// The original version of this class when saved
|
||||
///
|
||||
/// This field only exists in runtime and are not persisted
|
||||
final int savedVersion;
|
||||
|
||||
/// versioning of this class, use to upgrade old persisted album
|
||||
static const version = 7;
|
||||
}
|
||||
|
|
|
@ -89,3 +89,15 @@ class JobCanceledException implements Exception {
|
|||
|
||||
final dynamic message;
|
||||
}
|
||||
|
||||
/// Trying to downgrade an Album
|
||||
class AlbumDowngradeException implements Exception {
|
||||
const AlbumDowngradeException([this.message]);
|
||||
|
||||
@override
|
||||
toString() {
|
||||
return "AlbumDowngradeException: $message";
|
||||
}
|
||||
|
||||
final dynamic message;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ String toUserString(dynamic exception) {
|
|||
return L10n.global().errorDisconnected;
|
||||
} else if (exception is InvalidBaseUrlException) {
|
||||
return L10n.global().errorInvalidBaseUrl;
|
||||
} else if (exception is AlbumDowngradeException) {
|
||||
return L10n.global().errorAlbumDowngrade;
|
||||
}
|
||||
return exception.toString();
|
||||
}
|
||||
|
|
|
@ -1099,5 +1099,9 @@
|
|||
"errorServerError": "Server error. Please make sure the server is setup correctly",
|
||||
"@errorServerError": {
|
||||
"description": "HTTP 500"
|
||||
},
|
||||
"errorAlbumDowngrade": "Can't modify this album as it was created by a later version of this app. Please update the app and try again",
|
||||
"@errorAlbumDowngrade": {
|
||||
"description": "Album files are versioned. Overwriting a newer version is disallowed as it will lead to unexpected data loss"
|
||||
}
|
||||
}
|
|
@ -48,7 +48,8 @@
|
|||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription",
|
||||
"defaultButtonLabel"
|
||||
"defaultButtonLabel",
|
||||
"errorAlbumDowngrade"
|
||||
],
|
||||
|
||||
"de": [
|
||||
|
@ -114,7 +115,8 @@
|
|||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription",
|
||||
"defaultButtonLabel"
|
||||
"defaultButtonLabel",
|
||||
"errorAlbumDowngrade"
|
||||
],
|
||||
|
||||
"el": [
|
||||
|
@ -235,11 +237,13 @@
|
|||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription",
|
||||
"defaultButtonLabel"
|
||||
"defaultButtonLabel",
|
||||
"errorAlbumDowngrade"
|
||||
],
|
||||
|
||||
"es": [
|
||||
"settingsMapProviderTitle"
|
||||
"settingsMapProviderTitle",
|
||||
"errorAlbumDowngrade"
|
||||
],
|
||||
|
||||
"fr": [
|
||||
|
@ -340,7 +344,8 @@
|
|||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription",
|
||||
"defaultButtonLabel"
|
||||
"defaultButtonLabel",
|
||||
"errorAlbumDowngrade"
|
||||
],
|
||||
|
||||
"ru": [
|
||||
|
@ -414,6 +419,7 @@
|
|||
"fixAllTooltip",
|
||||
"missingShareDescription",
|
||||
"extraShareDescription",
|
||||
"defaultButtonLabel"
|
||||
"defaultButtonLabel",
|
||||
"errorAlbumDowngrade"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -5,11 +5,17 @@ import 'package:nc_photos/entity/album.dart';
|
|||
import 'package:nc_photos/entity/album/item.dart';
|
||||
import 'package:nc_photos/entity/album/provider.dart';
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/exception.dart';
|
||||
|
||||
class UpdateAlbum {
|
||||
UpdateAlbum(this.albumRepo);
|
||||
|
||||
Future<void> call(Account account, Album album) async {
|
||||
if (album.savedVersion > Album.version) {
|
||||
// the album is created by a newer version of this app
|
||||
throw AlbumDowngradeException(
|
||||
"Not allowed to downgrade album '${album.name}'");
|
||||
}
|
||||
final provider = album.provider;
|
||||
if (provider is AlbumStaticProvider) {
|
||||
await albumRepo.update(
|
||||
|
|
Loading…
Reference in a new issue