nc-photos/app/lib/account.dart

166 lines
4.3 KiB
Dart
Raw Normal View History

2021-12-05 13:02:22 +01:00
import 'dart:math';
2021-04-10 06:28:12 +02:00
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
2021-11-12 22:13:02 +01:00
import 'package:nc_photos/ci_string.dart';
2022-12-08 16:39:13 +01:00
import 'package:nc_photos/iterable_extension.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/string_extension.dart';
2021-08-06 19:11:00 +02:00
import 'package:nc_photos/type.dart';
2022-12-16 16:01:04 +01:00
import 'package:np_codegen/np_codegen.dart';
2022-12-08 16:39:13 +01:00
import 'package:to_string/to_string.dart';
part 'account.g.dart';
2021-04-10 06:28:12 +02:00
/// Details of a remote Nextcloud server account
2022-12-16 16:01:04 +01:00
@npLog
2022-12-08 16:39:13 +01:00
@toString
2021-04-10 06:28:12 +02:00
class Account with EquatableMixin {
Account(
2021-12-05 13:02:22 +01:00
this.id,
2021-04-10 06:28:12 +02:00
this.scheme,
String address,
this.userId,
this.username2,
2021-04-10 06:28:12 +02:00
this.password,
List<String> roots,
2021-09-15 08:58:06 +02:00
) : address = address.trimRightAny("/"),
2021-04-10 06:28:12 +02:00
_roots = roots.map((e) => e.trimRightAny("/")).toList() {
if (scheme != "http" && scheme != "https") {
2021-09-15 08:58:06 +02:00
throw const FormatException("scheme is neither http or https");
2021-04-10 06:28:12 +02:00
}
}
Account copyWith({
2021-12-05 13:02:22 +01:00
String? id,
2021-07-23 22:05:57 +02:00
String? scheme,
String? address,
CiString? userId,
String? username2,
2021-07-23 22:05:57 +02:00
String? password,
List<String>? roots,
2021-04-10 06:28:12 +02:00
}) {
return Account(
2021-12-05 13:02:22 +01:00
id ?? this.id,
2021-04-10 06:28:12 +02:00
scheme ?? this.scheme,
address ?? this.address,
userId ?? this.userId,
username2 ?? this.username2,
2021-04-10 06:28:12 +02:00
password ?? this.password,
roots ?? List.of(_roots),
2021-04-10 06:28:12 +02:00
);
}
2021-12-05 13:02:22 +01:00
static String newId() {
final timestamp = DateTime.now().millisecondsSinceEpoch;
final random = Random().nextInt(0xFFFFFF);
return "${timestamp.toRadixString(16)}-${random.toRadixString(16).padLeft(6, '0')}";
}
2021-04-10 06:28:12 +02:00
@override
2022-12-08 16:39:13 +01:00
String toString() => _$toString();
2021-04-10 06:28:12 +02:00
static Account? fromJson(
JsonObj json, {
required AccountUpgraderV1? upgraderV1,
}) {
final jsonVersion = json["version"] ?? 1;
JsonObj? result = json;
if (jsonVersion < 2) {
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>(),
);
}
2021-04-10 06:28:12 +02:00
2021-08-06 19:11:00 +02:00
JsonObj toJson() => {
"version": version,
2021-12-05 13:02:22 +01:00
"id": id,
2021-04-10 06:28:12 +02:00
"scheme": scheme,
"address": address,
"userId": userId.toString(),
"username2": username2,
2021-04-10 06:28:12 +02:00
"password": password,
"roots": _roots,
};
@override
get props => [id, scheme, address, userId, username2, password, _roots];
2021-04-10 06:28:12 +02:00
List<String> get roots => _roots;
2021-12-05 13:02:22 +01:00
final String id;
2021-04-10 06:28:12 +02:00
final String scheme;
2022-12-08 16:39:13 +01:00
@Format(r"${kDebugMode ? $? : '***'}")
2021-04-10 06:28:12 +02:00
final String address;
// For non LDAP users, this is the username used to sign in
2022-12-08 16:39:13 +01:00
@Format(r"${kDebugMode ? $? : '***'}")
final CiString userId;
// Username used to sign in. For non-LDAP users, this is identical to userId
2022-12-08 16:39:13 +01:00
@Format(r"${kDebugMode ? $? : '***'}")
final String username2;
2022-12-08 16:39:13 +01:00
@Format(r"${$?.isNotEmpty ? (kDebugMode ? $? : '***') : null}")
2021-04-10 06:28:12 +02:00
final String password;
2022-12-08 16:39:13 +01:00
@Format(r"${$?.toReadableString()}")
2021-04-10 06:28:12 +02:00
final List<String> _roots;
/// versioning of this class, use to upgrade old persisted accounts
static const version = 2;
2022-12-20 17:49:14 +01:00
static final _log = _$AccountNpLog.log;
2021-04-10 06:28:12 +02:00
}
extension AccountExtension on Account {
String get url => "$scheme://$address";
/// Compare the server identity of two Accounts
///
/// Return true if two Accounts point to the same user on server. Be careful
/// that this does NOT mean that the two Accounts are identical (e.g., they
/// can have difference password)
bool compareServerIdentity(Account other) {
return scheme == other.scheme &&
address == other.address &&
userId == other.userId;
}
2021-04-10 06:28:12 +02:00
}
abstract class AccountUpgrader {
JsonObj? call(JsonObj json);
}
2022-12-16 16:01:04 +01:00
@npLog
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;
}