style: Fix style issues

This commit is contained in:
PapaTutuWawa 2022-12-26 18:18:43 +01:00
parent 4dc3cfb2b1
commit e35f65aff9
4 changed files with 347 additions and 8 deletions

View File

@ -10,3 +10,7 @@ linter:
analyzer: analyzer:
exclude: exclude:
- "lib/protobuf/*.dart" - "lib/protobuf/*.dart"
# TODO: Remove once OmemoSessionManager is gone
- "test/omemo_test.dart"
- "example/omemo_dart_example.dart"
- "test/serialisation_test.dart"

View File

@ -41,13 +41,15 @@ class OmemoManager {
/// Functions for connecting with the OMEMO library /// Functions for connecting with the OMEMO library
/// Send an empty OMEMO:2 message using the encrypted payload [result] to [recipientJid]. /// Send an empty OMEMO:2 message using the encrypted payload @result to
/// @recipientJid.
final Future<void> Function(EncryptionResult result, String recipientJid) sendEmptyOmemoMessage; final Future<void> Function(EncryptionResult result, String recipientJid) sendEmptyOmemoMessage;
/// Fetch the list of device ids associated with [jid]. /// Fetch the list of device ids associated with @jid. If the device list cannot be
final Future<List<int>> Function(String jid) fetchDeviceList; /// fetched, return null.
final Future<List<int>?> Function(String jid) fetchDeviceList;
/// Fetch the device bundle for the device with id [id] of [jid]. If it cannot be fetched, return null. /// Fetch the device bundle for the device with id @id of jid. If it cannot be fetched, return null.
final Future<OmemoBundle?> Function(String jid, int id) fetchDeviceBundle; final Future<OmemoBundle?> Function(String jid, int id) fetchDeviceBundle;
/// Map bare JID to its known devices /// Map bare JID to its known devices
@ -316,10 +318,7 @@ class OmemoManager {
} }
final devices = _deviceList[senderJid]; final devices = _deviceList[senderJid];
if (devices == null) { if (devices?.contains(senderDeviceId) != true) {
throw NoDecryptionKeyException();
}
if (!devices.contains(senderDeviceId)) {
throw NoDecryptionKeyException(); throw NoDecryptionKeyException();
} }
@ -367,6 +366,8 @@ class OmemoManager {
if (!_deviceListRequested.containsKey(jid) || !_deviceList.containsKey(jid)) { if (!_deviceListRequested.containsKey(jid) || !_deviceList.containsKey(jid)) {
// We don't have an up-to-date version of the device list // We don't have an up-to-date version of the device list
final newDeviceList = await fetchDeviceList(jid); final newDeviceList = await fetchDeviceList(jid);
if (newDeviceList == null) return [];
_deviceList[jid] = newDeviceList; _deviceList[jid] = newDeviceList;
bundlesToFetch = newDeviceList bundlesToFetch = newDeviceList
.where((id) { .where((id) {
@ -383,6 +384,7 @@ class OmemoManager {
.toList(); .toList();
} }
_log.finest('Fetching bundles $bundlesToFetch for $jid');
final newBundles = List<OmemoBundle>.empty(growable: true); final newBundles = List<OmemoBundle>.empty(growable: true);
for (final id in bundlesToFetch) { for (final id in bundlesToFetch) {
final bundle = await fetchDeviceBundle(jid, id); final bundle = await fetchDeviceBundle(jid, id);

View File

@ -27,6 +27,7 @@ import 'package:synchronized/synchronized.dart';
@Deprecated('Use OmemoManager instead') @Deprecated('Use OmemoManager instead')
class OmemoSessionManager { class OmemoSessionManager {
@Deprecated('Use OmemoManager instead')
OmemoSessionManager(this._device, this._deviceMap, this._ratchetMap, this._trustManager) OmemoSessionManager(this._device, this._deviceMap, this._ratchetMap, this._trustManager)
: _lock = Lock(), : _lock = Lock(),
_deviceLock = Lock(), _deviceLock = Lock(),
@ -35,6 +36,7 @@ class OmemoSessionManager {
/// Deserialise the OmemoSessionManager from JSON data [data] that does not contain /// Deserialise the OmemoSessionManager from JSON data [data] that does not contain
/// the ratchet sessions. /// the ratchet sessions.
@Deprecated('Use OmemoManager instead')
factory OmemoSessionManager.fromJsonWithoutSessions( factory OmemoSessionManager.fromJsonWithoutSessions(
Map<String, dynamic> data, Map<String, dynamic> data,
Map<RatchetMapKey, OmemoDoubleRatchet> ratchetMap, Map<RatchetMapKey, OmemoDoubleRatchet> ratchetMap,

View File

@ -243,4 +243,335 @@ void main() {
42, 42,
); );
}); });
test('Test receiving a message encrypted for another device', () async {
const aliceJid = 'alice@server1';
const bobJid = 'bob@server2';
var oldDevice = true;
final aliceDevice = await Device.generateNewDevice(aliceJid, opkAmount: 1);
final bobOldDevice = await Device.generateNewDevice(bobJid, opkAmount: 1);
final bobCurrentDevice = await Device.generateNewDevice(bobJid, opkAmount: 1);
final aliceManager = omemo.OmemoManager(
aliceDevice,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async {
expect(jid, bobJid);
return oldDevice ?
[ bobOldDevice.id ] :
[ bobCurrentDevice.id ];
},
(jid, id) async {
expect(jid, bobJid);
return oldDevice ?
bobOldDevice.toBundle() :
bobCurrentDevice.toBundle();
},
);
final bobManager = omemo.OmemoManager(
bobCurrentDevice,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async => [],
(jid, id) async => null,
);
// Alice encrypts a message to Bob
final aliceResult1 = await aliceManager.onOutgoingStanza(
const OmemoOutgoingStanza(
[bobJid],
'Hello Bob',
),
);
// Bob's current device receives it
final bobResult1 = await bobManager.onIncomingStanza(
OmemoIncomingStanza(
aliceJid,
aliceDevice.id,
DateTime.now().millisecondsSinceEpoch,
aliceResult1!.encryptedKeys,
base64.encode(aliceResult1.ciphertext!),
),
);
expect(bobResult1.payload, null);
expect(bobResult1.error is NotEncryptedForDeviceException, true);
// Now Alice's client loses and regains the connection
aliceManager.onNewConnection();
oldDevice = false;
// And Alice sends a new message
final aliceResult2 = await aliceManager.onOutgoingStanza(
const OmemoOutgoingStanza(
[bobJid],
'Hello Bob x2',
),
);
final bobResult2 = await bobManager.onIncomingStanza(
OmemoIncomingStanza(
aliceJid,
aliceDevice.id,
DateTime.now().millisecondsSinceEpoch,
aliceResult2!.encryptedKeys,
base64.encode(aliceResult2.ciphertext!),
),
);
expect(aliceResult2.encryptedKeys.length, 1);
expect(bobResult2.payload, 'Hello Bob x2');
});
test('Test receiving a response from a new device', () async {
const aliceJid = 'alice@server1';
const bobJid = 'bob@server2';
var bothDevices = false;
final aliceDevice = await Device.generateNewDevice(aliceJid, opkAmount: 1);
final bobDevice1 = await Device.generateNewDevice(bobJid, opkAmount: 1);
final bobDevice2 = await Device.generateNewDevice(bobJid, opkAmount: 1);
final aliceManager = omemo.OmemoManager(
aliceDevice,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async {
expect(jid, bobJid);
return [
bobDevice1.id,
if (bothDevices)
bobDevice2.id,
];
},
(jid, id) async {
expect(jid, bobJid);
if (bothDevices) {
if (id == bobDevice1.id) {
return bobDevice1.toBundle();
} else if (id == bobDevice2.id) {
return bobDevice2.toBundle();
}
} else {
if (id == bobDevice1.id) return bobDevice1.toBundle();
}
return null;
},
);
final bobManager1 = omemo.OmemoManager(
bobDevice1,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async => [],
(jid, id) async => null,
);
final bobManager2 = omemo.OmemoManager(
bobDevice2,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async {
expect(jid, aliceJid);
return [aliceDevice.id];
},
(jid, id) async {
expect(jid, aliceJid);
return aliceDevice.toBundle();
},
);
// Alice sends a message to Bob
final aliceResult1 = await aliceManager.onOutgoingStanza(
const OmemoOutgoingStanza(
[bobJid],
'Hello Bob!',
),
);
// Bob decrypts it
final bobResult1 = await bobManager1.onIncomingStanza(
OmemoIncomingStanza(
aliceJid,
aliceDevice.id,
DateTime.now().millisecondsSinceEpoch,
aliceResult1!.encryptedKeys,
base64.encode(aliceResult1.ciphertext!),
),
);
expect(aliceResult1.encryptedKeys.length, 1);
expect(bobResult1.payload, 'Hello Bob!');
// Now Bob encrypts from his new device
bothDevices = true;
final bobResult2 = await bobManager2.onOutgoingStanza(
const OmemoOutgoingStanza(
[aliceJid],
'Hello from my new device',
),
);
// And Alice decrypts it
final aliceResult2 = await aliceManager.onIncomingStanza(
OmemoIncomingStanza(
bobJid,
bobDevice2.id,
DateTime.now().millisecondsSinceEpoch,
bobResult2!.encryptedKeys,
base64.encode(bobResult2.ciphertext!),
),
);
expect(aliceResult2.payload, 'Hello from my new device');
});
test('Test receiving a device list update', () async {
const aliceJid = 'alice@server1';
const bobJid = 'bob@server2';
var bothDevices = false;
final aliceDevice = await Device.generateNewDevice(aliceJid, opkAmount: 1);
final bobDevice1 = await Device.generateNewDevice(bobJid, opkAmount: 1);
final bobDevice2 = await Device.generateNewDevice(bobJid, opkAmount: 1);
final aliceManager = omemo.OmemoManager(
aliceDevice,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async {
expect(jid, bobJid);
return [
bobDevice1.id,
if (bothDevices)
bobDevice2.id,
];
},
(jid, id) async {
expect(jid, bobJid);
if (bothDevices) {
if (id == bobDevice1.id) {
return bobDevice1.toBundle();
} else if (id == bobDevice2.id) {
return bobDevice2.toBundle();
}
} else {
if (id == bobDevice1.id) return bobDevice1.toBundle();
}
return null;
},
);
final bobManager1 = omemo.OmemoManager(
bobDevice1,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async => null,
(jid, id) async => null,
);
final bobManager2 = omemo.OmemoManager(
bobDevice2,
AlwaysTrustingTrustManager(),
(result, recipientJid) async {},
(jid) async => null,
(jid, id) async => null,
);
// Alice sends a message to Bob
final aliceResult1 = await aliceManager.onOutgoingStanza(
const OmemoOutgoingStanza(
[bobJid],
'Hello Bob!',
),
);
// Bob decrypts it
final bobResult1 = await bobManager1.onIncomingStanza(
OmemoIncomingStanza(
aliceJid,
aliceDevice.id,
DateTime.now().millisecondsSinceEpoch,
aliceResult1!.encryptedKeys,
base64.encode(aliceResult1.ciphertext!),
),
);
expect(aliceResult1.encryptedKeys.length, 1);
expect(bobResult1.payload, 'Hello Bob!');
// Bob acks the ratchet session
await aliceManager.ratchetAcknowledged(bobJid, bobDevice1.id);
// Bob now publishes a new device
bothDevices = true;
aliceManager.onDeviceListUpdate(
bobJid,
[
bobDevice1.id,
bobDevice2.id,
],
);
// Now Alice encrypts another message
final aliceResult2 = await aliceManager.onOutgoingStanza(
const OmemoOutgoingStanza(
[bobJid],
'Hello Bob! x2',
),
);
expect(aliceResult2!.encryptedKeys.length, 2);
// And Bob decrypts it
final bobResult21 = await bobManager1.onIncomingStanza(
OmemoIncomingStanza(
aliceJid,
aliceDevice.id,
DateTime.now().millisecondsSinceEpoch,
aliceResult2.encryptedKeys,
base64.encode(aliceResult2.ciphertext!),
),
);
final bobResult22 = await bobManager2.onIncomingStanza(
OmemoIncomingStanza(
aliceJid,
aliceDevice.id,
DateTime.now().millisecondsSinceEpoch,
aliceResult2.encryptedKeys,
base64.encode(aliceResult2.ciphertext!),
),
);
expect(bobResult21.payload, 'Hello Bob! x2');
expect(bobResult22.payload, 'Hello Bob! x2');
// Bob2 now responds
final bobResult32 = await bobManager2.onOutgoingStanza(
const OmemoOutgoingStanza(
[aliceJid],
'Hello Alice!',
),
);
// And Alice responds
final aliceResult3 = await aliceManager.onIncomingStanza(
OmemoIncomingStanza(
bobJid,
bobDevice2.id,
DateTime.now().millisecondsSinceEpoch,
bobResult32!.encryptedKeys,
base64.encode(bobResult32.ciphertext!),
),
);
expect(aliceResult3.payload, 'Hello Alice!');
});
} }