feat: Stop overriding the BTBV manager
This commit is contained in:
parent
28e7ad59b0
commit
4fb25a3ab7
@ -42,7 +42,7 @@ void main() async {
|
||||
// request it using PEP and then convert the device bundle into a OmemoBundle object.
|
||||
final bobManager = OmemoManager(
|
||||
await OmemoDevice.generateNewDevice(bobJid),
|
||||
MemoryBTBVTrustManager(),
|
||||
BlindTrustBeforeVerificationTrustManager(),
|
||||
(result, recipient) async => {},
|
||||
(jid) async => [],
|
||||
(jid, id) async => null,
|
||||
|
@ -20,7 +20,4 @@ class AlwaysTrustingTrustManager extends TrustManager {
|
||||
|
||||
@override
|
||||
Future<void> removeTrustDecisionsForJid(String jid) async {}
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> toJson() async => <String, dynamic>{};
|
||||
}
|
||||
|
@ -17,9 +17,6 @@ abstract class TrustManager {
|
||||
/// if [enabled] is false.
|
||||
Future<void> setEnabled(String jid, int deviceId, bool enabled);
|
||||
|
||||
/// Serialize the trust manager to JSON.
|
||||
Future<Map<String, dynamic>> toJson();
|
||||
|
||||
/// Removes all trust decisions for [jid].
|
||||
Future<void> removeTrustDecisionsForJid(String jid);
|
||||
}
|
||||
|
@ -3,47 +3,64 @@ import 'package:omemo_dart/src/omemo/ratchet_map_key.dart';
|
||||
import 'package:omemo_dart/src/trust/base.dart';
|
||||
import 'package:synchronized/synchronized.dart';
|
||||
|
||||
@immutable
|
||||
class BTBVTrustData {
|
||||
const BTBVTrustData(
|
||||
this.jid,
|
||||
this.device,
|
||||
this.state,
|
||||
this.enabled,
|
||||
);
|
||||
|
||||
/// The JID in question.
|
||||
final String jid;
|
||||
|
||||
/// The device (ratchet) in question.
|
||||
final int device;
|
||||
|
||||
/// The trust state of the ratchet.
|
||||
final BTBVTrustState state;
|
||||
|
||||
/// Flag indicating whether the ratchet is enabled (true) or not (false).
|
||||
final bool enabled;
|
||||
}
|
||||
|
||||
/// A callback for when a trust decision is to be commited to persistent storage.
|
||||
typedef BTBVTrustCommitCallback = Future<void> Function(BTBVTrustData data);
|
||||
|
||||
/// A stub-implementation of [BTBVTrustCommitCallback].
|
||||
Future<void> btbvCommitStub(BTBVTrustData _) async {}
|
||||
|
||||
/// A callback for when all trust decisions for a JID should be removed from persistent storage.
|
||||
typedef BTBVRemoveTrustForJidCallback = Future<void> Function(String jid);
|
||||
|
||||
/// A stub-implementation of [BTBVRemoveTrustForJidCallback].
|
||||
Future<void> btbvRemoveTrustStub(String _) async {}
|
||||
|
||||
/// Every device is in either of those two trust states:
|
||||
/// - notTrusted: The device is absolutely not trusted
|
||||
/// - blindTrust: The fingerprint is not verified using OOB means
|
||||
/// - verified: The fingerprint has been verified using OOB means
|
||||
enum BTBVTrustState {
|
||||
notTrusted, // = 1
|
||||
blindTrust, // = 2
|
||||
verified, // = 3
|
||||
}
|
||||
notTrusted(1),
|
||||
blindTrust(2),
|
||||
verified(3);
|
||||
|
||||
int _trustToInt(BTBVTrustState state) {
|
||||
switch (state) {
|
||||
case BTBVTrustState.notTrusted:
|
||||
return 1;
|
||||
case BTBVTrustState.blindTrust:
|
||||
return 2;
|
||||
case BTBVTrustState.verified:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
const BTBVTrustState(this.value);
|
||||
|
||||
BTBVTrustState _trustFromInt(int i) {
|
||||
switch (i) {
|
||||
case 1:
|
||||
return BTBVTrustState.notTrusted;
|
||||
case 2:
|
||||
return BTBVTrustState.blindTrust;
|
||||
case 3:
|
||||
return BTBVTrustState.verified;
|
||||
default:
|
||||
return BTBVTrustState.notTrusted;
|
||||
}
|
||||
/// The value backing the trust state.
|
||||
final int value;
|
||||
}
|
||||
|
||||
/// A TrustManager that implements the idea of Blind Trust Before Verification.
|
||||
/// See https://gultsch.de/trust.html for more details.
|
||||
abstract class BlindTrustBeforeVerificationTrustManager extends TrustManager {
|
||||
class BlindTrustBeforeVerificationTrustManager extends TrustManager {
|
||||
BlindTrustBeforeVerificationTrustManager({
|
||||
Map<RatchetMapKey, BTBVTrustState>? trustCache,
|
||||
Map<RatchetMapKey, bool>? enablementCache,
|
||||
Map<String, List<int>>? devices,
|
||||
this.commit = btbvCommitStub,
|
||||
this.removeTrust = btbvRemoveTrustStub,
|
||||
}) : trustCache = trustCache ?? {},
|
||||
enablementCache = enablementCache ?? {},
|
||||
devices = devices ?? {},
|
||||
@ -67,6 +84,12 @@ abstract class BlindTrustBeforeVerificationTrustManager extends TrustManager {
|
||||
/// The lock for devices and trustCache
|
||||
final Lock _lock;
|
||||
|
||||
/// Callback for commiting trust data to persistent storage.
|
||||
final BTBVTrustCommitCallback commit;
|
||||
|
||||
/// Callback for removing trust data for a JID.
|
||||
final BTBVRemoveTrustForJidCallback removeTrust;
|
||||
|
||||
/// Returns true if [jid] has at least one device that is verified. If not, returns false.
|
||||
/// Note that this function accesses devices and trustCache, which requires that the
|
||||
/// lock for those two maps (_lock) has been aquired before calling.
|
||||
@ -125,7 +148,14 @@ abstract class BlindTrustBeforeVerificationTrustManager extends TrustManager {
|
||||
}
|
||||
|
||||
// Commit the state
|
||||
await commitState();
|
||||
await commit(
|
||||
BTBVTrustData(
|
||||
jid,
|
||||
deviceId,
|
||||
trustCache[key]!,
|
||||
enablementCache[key]!,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -152,10 +182,18 @@ abstract class BlindTrustBeforeVerificationTrustManager extends TrustManager {
|
||||
BTBVTrustState state,
|
||||
) async {
|
||||
await _lock.synchronized(() async {
|
||||
trustCache[RatchetMapKey(jid, deviceId)] = state;
|
||||
final key = RatchetMapKey(jid, deviceId);
|
||||
trustCache[key] = state;
|
||||
|
||||
// Commit the state
|
||||
await commitState();
|
||||
await commit(
|
||||
BTBVTrustData(
|
||||
jid,
|
||||
deviceId,
|
||||
state,
|
||||
enablementCache[key]!,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@ -171,88 +209,39 @@ abstract class BlindTrustBeforeVerificationTrustManager extends TrustManager {
|
||||
|
||||
@override
|
||||
Future<void> setEnabled(String jid, int deviceId, bool enabled) async {
|
||||
final key = RatchetMapKey(jid, deviceId);
|
||||
await _lock.synchronized(() async {
|
||||
enablementCache[RatchetMapKey(jid, deviceId)] = enabled;
|
||||
});
|
||||
enablementCache[key] = enabled;
|
||||
|
||||
// Commit the state
|
||||
await commitState();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> toJson() async {
|
||||
return {
|
||||
'devices': devices,
|
||||
'trust': trustCache.map(
|
||||
(key, value) => MapEntry(
|
||||
key.toJsonKey(),
|
||||
_trustToInt(value),
|
||||
),
|
||||
),
|
||||
'enable':
|
||||
enablementCache.map((key, value) => MapEntry(key.toJsonKey(), value)),
|
||||
};
|
||||
}
|
||||
|
||||
/// From a serialized version of a BTBV trust manager, extract the device list.
|
||||
/// NOTE: This is needed as Dart cannot just cast a List<dynamic> to List<int> and so on.
|
||||
static Map<String, List<int>> deviceListFromJson(Map<String, dynamic> json) {
|
||||
return (json['devices']! as Map<String, dynamic>).map<String, List<int>>(
|
||||
(key, value) => MapEntry(
|
||||
key,
|
||||
(value as List<dynamic>).map<int>((i) => i as int).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// From a serialized version of a BTBV trust manager, extract the trust cache.
|
||||
/// NOTE: This is needed as Dart cannot just cast a List<dynamic> to List<int> and so on.
|
||||
static Map<RatchetMapKey, BTBVTrustState> trustCacheFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) {
|
||||
return (json['trust']! as Map<String, dynamic>)
|
||||
.map<RatchetMapKey, BTBVTrustState>(
|
||||
(key, value) => MapEntry(
|
||||
RatchetMapKey.fromJsonKey(key),
|
||||
_trustFromInt(value as int),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// From a serialized version of a BTBV trust manager, extract the enable cache.
|
||||
/// NOTE: This is needed as Dart cannot just cast a List<dynamic> to List<int> and so on.
|
||||
static Map<RatchetMapKey, bool> enableCacheFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) {
|
||||
return (json['enable']! as Map<String, dynamic>).map<RatchetMapKey, bool>(
|
||||
(key, value) => MapEntry(
|
||||
RatchetMapKey.fromJsonKey(key),
|
||||
value as bool,
|
||||
await commit(
|
||||
BTBVTrustData(
|
||||
jid,
|
||||
deviceId,
|
||||
trustCache[key]!,
|
||||
enabled,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> removeTrustDecisionsForJid(String jid) async {
|
||||
await _lock.synchronized(() async {
|
||||
// Clear the caches
|
||||
for (final device in devices[jid]!) {
|
||||
final key = RatchetMapKey(jid, device);
|
||||
trustCache.remove(key);
|
||||
enablementCache.remove(key);
|
||||
}
|
||||
devices.remove(jid);
|
||||
await commitState();
|
||||
|
||||
// Commit the state
|
||||
await removeTrust(jid);
|
||||
});
|
||||
}
|
||||
|
||||
/// Called when the state of the trust manager has been changed. Allows the user to
|
||||
/// commit the trust state to persistent storage.
|
||||
@visibleForOverriding
|
||||
Future<void> commitState();
|
||||
|
||||
@visibleForTesting
|
||||
BTBVTrustState getDeviceTrust(String jid, int deviceId) =>
|
||||
trustCache[RatchetMapKey(jid, deviceId)]!;
|
||||
}
|
||||
|
||||
/// A BTBV TrustManager that does not commit its state to persistent storage. Well suited
|
||||
/// for testing.
|
||||
class MemoryBTBVTrustManager extends BlindTrustBeforeVerificationTrustManager {
|
||||
@override
|
||||
Future<void> commitState() async {}
|
||||
}
|
||||
|
@ -20,7 +20,4 @@ class NeverTrustingTrustManager extends TrustManager {
|
||||
|
||||
@override
|
||||
Future<void> removeTrustDecisionsForJid(String jid) async {}
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> toJson() async => <String, dynamic>{};
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import 'package:test/test.dart';
|
||||
void main() {
|
||||
test('Test the Blind Trust Before Verification TrustManager', () async {
|
||||
// Caroline's BTBV manager
|
||||
final btbv = MemoryBTBVTrustManager();
|
||||
final btbv = BlindTrustBeforeVerificationTrustManager();
|
||||
// Example data
|
||||
const aliceJid = 'alice@some.server';
|
||||
const bobJid = 'bob@other.server';
|
||||
|
Loading…
Reference in New Issue
Block a user