feat: Changes based on integration issues

This commit is contained in:
PapaTutuWawa 2023-06-18 20:44:05 +02:00
parent 499817313d
commit 8b91c07fb8
4 changed files with 66 additions and 65 deletions

View File

@ -52,19 +52,6 @@ class ListDiff<T> {
final List<T> removed; final List<T> removed;
} }
extension BeforeAfterListDiff<T> on List<T> {
/// Compute the set-based changes between this list and [newList].
ListDiff<T> diff(List<T> newList) {
final oldSet = Set<T>.from(this);
final newSet = Set<T>.from(newList);
return ListDiff(
newSet.difference(oldSet).toList(),
oldSet.difference(newSet).toList(),
);
}
}
extension AppendToListOrCreateExtension<K, V> on Map<K, List<V>> { extension AppendToListOrCreateExtension<K, V> on Map<K, List<V>> {
/// Create or append [value] to the list identified with key [key]. /// Create or append [value] to the list identified with key [key].
void appendOrCreate(K key, V value, {bool checkExistence = false}) { void appendOrCreate(K key, V value, {bool checkExistence = false}) {

View File

@ -60,19 +60,16 @@ typedef DeviceListSubscribeFunction = Future<void> Function(String jid);
/// Publishes the device bundle on our own PEP node. /// Publishes the device bundle on our own PEP node.
typedef PublishDeviceBundleFunction = Future<void> Function(OmemoDevice device); typedef PublishDeviceBundleFunction = Future<void> Function(OmemoDevice device);
/// Commits the device list for [jid] to persistent storage. [added] will be the list of /// Commits the device list [devices] for [jid] to persistent storage.
/// devices added and [removed] will be the list of removed devices.
typedef CommitDeviceListCallback = Future<void> Function( typedef CommitDeviceListCallback = Future<void> Function(
String jid, String jid,
List<int> added, List<int> devices,
List<int> removed,
); );
/// A stub implementation of [CommitDeviceListCallback]. /// A stub implementation of [CommitDeviceListCallback].
Future<void> commitDeviceListStub( Future<void> commitDeviceListStub(
String _, String _,
List<int> __, List<int> __,
List<int> ___,
) async {} ) async {}
/// Commits the mapping of the (new) ratchets in [ratchets] to persistent storage. /// Commits the mapping of the (new) ratchets in [ratchets] to persistent storage.
@ -262,7 +259,6 @@ class OmemoManager {
await commitDeviceList( await commitDeviceList(
jid, jid,
newDeviceList, newDeviceList,
[],
); );
} }
} }
@ -866,7 +862,6 @@ class OmemoManager {
await commitDeviceList( await commitDeviceList(
jid, jid,
[], [],
_deviceList[jid]!,
); );
_deviceList.remove(jid); _deviceList.remove(jid);
_deviceListRequested.remove(jid); _deviceListRequested.remove(jid);
@ -880,20 +875,12 @@ class OmemoManager {
await _ratchetQueue.synchronized( await _ratchetQueue.synchronized(
[jid], [jid],
() async { () async {
// Compute the delta
ListDiff<int> delta;
if (_deviceList.containsKey(jid)) {
delta = _deviceList[jid]!.diff(devices);
} else {
delta = ListDiff(devices, []);
}
// Update our state // Update our state
_deviceList[jid] = devices; _deviceList[jid] = devices;
_deviceListRequested[jid] = true; _deviceListRequested[jid] = true;
// Commit the device list // Commit the device list
await commitDeviceList(jid, delta.added, delta.removed); await commitDeviceList(jid, devices);
}, },
); );
} }
@ -1013,6 +1000,31 @@ class OmemoManager {
}); });
} }
/// Generates a completely new device to use.
Future<OmemoDevice> regenerateDevice() async {
// Generate the new device
final oldDevice = await getDevice();
final newDevice = await OmemoDevice.generateNewDevice(
oldDevice.jid,
opkAmount: oldDevice.opks.length,
);
await _deviceLock.synchronized(() async {
// Replace the old device
_device = newDevice;
// Commit
await commitDevice(newDevice);
// Publish
unawaited(
publishDeviceBundle(newDevice),
);
});
return newDevice;
}
/// Acquire a lock for interacting with the trust manager for modifying the trust /// Acquire a lock for interacting with the trust manager for modifying the trust
/// state of [jid]. [callback] is called from within the critical section with the /// state of [jid]. [callback] is called from within the critical section with the
/// trust manager as its parameter. /// trust manager as its parameter.

View File

@ -10,6 +10,7 @@ class BTBVTrustData {
this.device, this.device,
this.state, this.state,
this.enabled, this.enabled,
this.trusted,
); );
/// The JID in question. /// The JID in question.
@ -23,6 +24,12 @@ class BTBVTrustData {
/// Flag indicating whether the ratchet is enabled (true) or not (false). /// Flag indicating whether the ratchet is enabled (true) or not (false).
final bool enabled; final bool enabled;
/// Flag indicating whether the ratchet is trusted. For loading and commiting a ratchet, this field
/// contains an arbitrary value.
/// When using [BlindTrustBeforeVerificationTrustManager.getDevicesTrust], this flag will be true if
/// the ratchet is trusted and false if not.
final bool trusted;
} }
/// A callback for when a trust decision is to be commited to persistent storage. /// A callback for when a trust decision is to be commited to persistent storage.
@ -54,6 +61,20 @@ enum BTBVTrustState {
const BTBVTrustState(this.value); const BTBVTrustState(this.value);
factory BTBVTrustState.fromInt(int value) {
switch (value) {
case 1:
return BTBVTrustState.notTrusted;
case 2:
return BTBVTrustState.blindTrust;
case 3:
return BTBVTrustState.verified;
// TODO(Unknown): Should we handle this better?
default:
return BTBVTrustState.notTrusted;
}
}
/// The value backing the trust state. /// The value backing the trust state.
final int value; final int value;
} }
@ -142,19 +163,31 @@ class BlindTrustBeforeVerificationTrustManager extends TrustManager {
deviceId, deviceId,
trustCache[key]!, trustCache[key]!,
enablementCache[key]!, enablementCache[key]!,
false,
), ),
); );
} }
/// Returns a mapping from the device identifiers of [jid] to their trust state. If /// Returns a mapping from the device identifiers of [jid] to their trust state. If
/// there are no devices known for [jid], then an empty map is returned. /// there are no devices known for [jid], then an empty map is returned.
Future<Map<int, BTBVTrustState>> getDevicesTrust(String jid) async { Future<Map<int, BTBVTrustData>> getDevicesTrust(String jid) async {
final map = <int, BTBVTrustState>{}; final map = <int, BTBVTrustData>{};
if (!devices.containsKey(jid)) return map; if (!devices.containsKey(jid)) return map;
for (final deviceId in devices[jid]!) { for (final deviceId in devices[jid]!) {
map[deviceId] = trustCache[RatchetMapKey(jid, deviceId)]!; final key = RatchetMapKey(jid, deviceId);
if (!trustCache.containsKey(key) || !enablementCache.containsKey(key)) {
continue;
}
map[deviceId] = BTBVTrustData(
jid,
deviceId,
trustCache[key]!,
enablementCache[key]!,
await isTrusted(jid, deviceId),
);
} }
return map; return map;
@ -176,6 +209,7 @@ class BlindTrustBeforeVerificationTrustManager extends TrustManager {
deviceId, deviceId,
state, state,
enablementCache[key]!, enablementCache[key]!,
false,
), ),
); );
} }
@ -200,6 +234,7 @@ class BlindTrustBeforeVerificationTrustManager extends TrustManager {
deviceId, deviceId,
trustCache[key]!, trustCache[key]!,
enabled, enabled,
false,
), ),
); );
} }

View File

@ -1,33 +0,0 @@
import 'package:omemo_dart/src/helpers.dart';
import 'package:omemo_dart/src/omemo/queue.dart';
import 'package:test/test.dart';
void main() {
group('List diff', () {
test('Empty list to full list', () {
final result = <int>[].diff([1, 2, 3, 4]);
expect(result.removed, isEmpty);
expect(
result.added.containsAll([1, 2, 3, 4]),
isTrue,
);
expect(result.added.length, 4);
});
test('Full list to empty list', () {
final result = [1, 2, 3, 4].diff([]);
expect(result.added, isEmpty);
expect(
result.removed.containsAll([1, 2, 3, 4]),
isTrue,
);
expect(result.removed.length, 4);
});
test('Full list to full list', () {
final result = [1, 2, 3, 4].diff([1, 2, 4, 5]);
expect(result.added, [5]);
expect(result.removed, [3]);
});
});
}