feat: Add fallback keys support

This commit is contained in:
Sorunome 2021-02-15 16:26:49 +01:00
parent 82f823f50e
commit 498c7825a5
No known key found for this signature in database
GPG Key ID: B19471D07FC9BE9C
18 changed files with 319 additions and 178 deletions

View File

@ -20,6 +20,7 @@ import 'dart:convert';
import 'dart:async'; import 'dart:async';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
import 'package:olm/olm.dart' as olm;
import '../famedlysdk.dart'; import '../famedlysdk.dart';
import '../src/utils/run_in_root.dart'; import '../src/utils/run_in_root.dart';
@ -68,13 +69,27 @@ class Encryption {
_backgroundTasks(); // start the background tasks _backgroundTasks(); // start the background tasks
} }
bool isMinOlmVersion(int major, int minor, int patch) {
try {
final version = olm.get_library_version();
return version[0] > major ||
(version[0] == major &&
(version[1] > minor ||
(version[1] == minor && version[2] >= patch)));
} catch (_) {
return false;
}
}
Bootstrap bootstrap({void Function() onUpdate}) => Bootstrap( Bootstrap bootstrap({void Function() onUpdate}) => Bootstrap(
encryption: this, encryption: this,
onUpdate: onUpdate, onUpdate: onUpdate,
); );
void handleDeviceOneTimeKeysCount(Map<String, int> countJson) { void handleDeviceOneTimeKeysCount(
runInRoot(() => olmManager.handleDeviceOneTimeKeysCount(countJson)); Map<String, int> countJson, List<String> unusedFallbackKeyTypes) {
runInRoot(() => olmManager.handleDeviceOneTimeKeysCount(
countJson, unusedFallbackKeyTypes));
} }
void onSync() { void onSync() {

View File

@ -138,10 +138,12 @@ class OlmManager {
bool _uploadKeysLock = false; bool _uploadKeysLock = false;
/// Generates new one time keys, signs everything and upload it to the server. /// Generates new one time keys, signs everything and upload it to the server.
Future<bool> uploadKeys( Future<bool> uploadKeys({
{bool uploadDeviceKeys = false, bool uploadDeviceKeys = false,
int oldKeyCount = 0, int oldKeyCount = 0,
bool updateDatabase = true}) async { bool updateDatabase = true,
bool unusedFallbackKey = false,
}) async {
if (!enabled) { if (!enabled) {
return true; return true;
} }
@ -152,32 +154,53 @@ class OlmManager {
_uploadKeysLock = true; _uploadKeysLock = true;
try { try {
// check if we have OTKs that still need uploading. If we do, we don't try to generate new ones,
// instead we try to upload the old ones first
final oldOTKsNeedingUpload =
json.decode(_olmAccount.one_time_keys())['curve25519'].entries.length;
// generate one-time keys
// we generate 2/3rds of max, so that other keys people may still have can
// still be used
final oneTimeKeysCount =
(_olmAccount.max_number_of_one_time_keys() * 2 / 3).floor() -
oldKeyCount -
oldOTKsNeedingUpload;
if (oneTimeKeysCount > 0) {
_olmAccount.generate_one_time_keys(oneTimeKeysCount);
}
final Map<String, dynamic> oneTimeKeys =
json.decode(_olmAccount.one_time_keys());
// now sign all the one-time keys
final signedOneTimeKeys = <String, dynamic>{}; final signedOneTimeKeys = <String, dynamic>{};
for (final entry in oneTimeKeys['curve25519'].entries) { int uploadedOneTimeKeysCount;
final key = entry.key; if (oldKeyCount != null) {
final value = entry.value; // check if we have OTKs that still need uploading. If we do, we don't try to generate new ones,
signedOneTimeKeys['signed_curve25519:$key'] = <String, dynamic>{}; // instead we try to upload the old ones first
signedOneTimeKeys['signed_curve25519:$key'] = signJson({ final oldOTKsNeedingUpload = json
'key': value, .decode(_olmAccount.one_time_keys())['curve25519']
}); .entries
.length;
// generate one-time keys
// we generate 2/3rds of max, so that other keys people may still have can
// still be used
final oneTimeKeysCount =
(_olmAccount.max_number_of_one_time_keys() * 2 / 3).floor() -
oldKeyCount -
oldOTKsNeedingUpload;
if (oneTimeKeysCount > 0) {
_olmAccount.generate_one_time_keys(oneTimeKeysCount);
}
uploadedOneTimeKeysCount = oneTimeKeysCount + oldOTKsNeedingUpload;
final Map<String, dynamic> oneTimeKeys =
json.decode(_olmAccount.one_time_keys());
// now sign all the one-time keys
for (final entry in oneTimeKeys['curve25519'].entries) {
final key = entry.key;
final value = entry.value;
signedOneTimeKeys['signed_curve25519:$key'] = signJson({
'key': value,
});
}
}
final signedFallbackKeys = <String, dynamic>{};
if (encryption.isMinOlmVersion(3, 2, 0) && unusedFallbackKey == false) {
// we don't have an unused fallback key uploaded....so let's change that!
_olmAccount.generate_fallback_key();
final fallbackKey = json.decode(_olmAccount.fallback_key());
// now sign all the fallback keys
for (final entry in fallbackKey['curve25519'].entries) {
final key = entry.key;
final value = entry.value;
signedFallbackKeys['signed_curve25519:$key'] = signJson({
'key': value,
'fallback': true,
});
}
} }
// and now generate the payload to upload // and now generate the payload to upload
@ -217,28 +240,43 @@ class OlmManager {
? MatrixDeviceKeys.fromJson(keysContent['device_keys']) ? MatrixDeviceKeys.fromJson(keysContent['device_keys'])
: null, : null,
oneTimeKeys: signedOneTimeKeys, oneTimeKeys: signedOneTimeKeys,
fallbackKeys: signedFallbackKeys,
); );
// mark the OTKs as published and save that to datbase // mark the OTKs as published and save that to datbase
_olmAccount.mark_keys_as_published(); _olmAccount.mark_keys_as_published();
if (updateDatabase) { if (updateDatabase) {
await client.database?.updateClientKeys(pickledOlmAccount, client.id); await client.database?.updateClientKeys(pickledOlmAccount, client.id);
} }
return response['signed_curve25519'] == oneTimeKeysCount; return (uploadedOneTimeKeysCount != null &&
response['signed_curve25519'] == uploadedOneTimeKeysCount) ||
uploadedOneTimeKeysCount == null;
} finally { } finally {
_uploadKeysLock = false; _uploadKeysLock = false;
} }
} }
void handleDeviceOneTimeKeysCount(Map<String, int> countJson) { void handleDeviceOneTimeKeysCount(
Map<String, int> countJson, List<String> unusedFallbackKeyTypes) {
if (!enabled) { if (!enabled) {
return; return;
} }
final haveFallbackKeys = encryption.isMinOlmVersion(3, 2, 0);
// Check if there are at least half of max_number_of_one_time_keys left on the server // Check if there are at least half of max_number_of_one_time_keys left on the server
// and generate and upload more if not. // and generate and upload more if not.
if (countJson.containsKey('signed_curve25519') && if ((countJson != null &&
countJson['signed_curve25519'] < ((countJson.containsKey('signed_curve25519') &&
(_olmAccount.max_number_of_one_time_keys() / 2)) { countJson['signed_curve25519'] <
uploadKeys(oldKeyCount: countJson['signed_curve25519']); (_olmAccount.max_number_of_one_time_keys() / 2)) ||
!countJson.containsKey('signed_curve25519'))) ||
(haveFallbackKeys &&
unusedFallbackKeyTypes?.contains('signed_curve25519') == false)) {
uploadKeys(
oldKeyCount:
countJson != null ? (countJson['signed_curve25519'] ?? 0) : null,
unusedFallbackKey: haveFallbackKeys
? unusedFallbackKeyTypes?.contains('signed_curve25519')
: null,
);
} }
} }

View File

@ -1073,8 +1073,11 @@ class Client extends MatrixApi {
if (sync.deviceLists != null) { if (sync.deviceLists != null) {
await _handleDeviceListsEvents(sync.deviceLists); await _handleDeviceListsEvents(sync.deviceLists);
} }
if (sync.deviceOneTimeKeysCount != null && encryptionEnabled) { if ((sync.deviceUnusedFallbackKeyTypes != null ||
encryption.handleDeviceOneTimeKeysCount(sync.deviceOneTimeKeysCount); sync.deviceOneTimeKeysCount != null) &&
encryptionEnabled) {
encryption.handleDeviceOneTimeKeysCount(
sync.deviceOneTimeKeysCount, sync.deviceUnusedFallbackKeyTypes);
} }
onSync.add(sync); onSync.add(sync);
} }

View File

@ -19,11 +19,11 @@ dependencies:
crypto: ^2.1.5 crypto: ^2.1.5
base58check: ^1.0.1 base58check: ^1.0.1
password_hash: ^2.0.0 password_hash: ^2.0.0
olm: ^1.2.1 olm: ^1.3.0
matrix_file_e2ee: ^1.0.5 matrix_file_e2ee: ^1.0.5
isolate: ^2.0.3 isolate: ^2.0.3
logger: ^0.9.4 logger: ^0.9.4
matrix_api_lite: ^0.1.8 matrix_api_lite: ^0.1.9
dev_dependencies: dev_dependencies:
test: ^1.15.7 test: ^1.15.7

View File

@ -61,16 +61,17 @@ void main() {
toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList(); toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList();
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().w('[LibOlm] Enabled: $olmEnabled');
test('Login', () async { test('Login', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().w('[LibOlm] Enabled: $olmEnabled');
var presenceCounter = 0; var presenceCounter = 0;
var accountDataCounter = 0; var accountDataCounter = 0;
matrix.onPresence.stream.listen((Presence data) { matrix.onPresence.stream.listen((Presence data) {

View File

@ -74,24 +74,25 @@ void main() {
}); });
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
}); });
test('reject devices without self-signature', () async { test('reject devices without self-signature', () async {
if (!olmEnabled) return;
var key = DeviceKeys.fromJson({ var key = DeviceKeys.fromJson({
'user_id': '@test:fakeServer.notExisting', 'user_id': '@test:fakeServer.notExisting',
'device_id': 'BADDEVICE', 'device_id': 'BADDEVICE',
@ -128,6 +129,7 @@ void main() {
}); });
test('set blocked / verified', () async { test('set blocked / verified', () async {
if (!olmEnabled) return;
final key = final key =
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
client.userDeviceKeys[client.userID].deviceKeys['UNSIGNEDDEVICE'] = client.userDeviceKeys[client.userID].deviceKeys['UNSIGNEDDEVICE'] =
@ -203,6 +205,7 @@ void main() {
}); });
test('verification based on signatures', () async { test('verification based on signatures', () async {
if (!olmEnabled) return;
final user = client.userDeviceKeys[client.userID]; final user = client.userDeviceKeys[client.userID];
user.masterKey.setDirectVerified(true); user.masterKey.setDirectVerified(true);
expect(user.deviceKeys['GHTYAJCE'].crossVerified, true); expect(user.deviceKeys['GHTYAJCE'].crossVerified, true);
@ -238,6 +241,7 @@ void main() {
}); });
test('start verification', () async { test('start verification', () async {
if (!olmEnabled) return;
var req = client var req = client
.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS'] .userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
.startVerification(); .startVerification();
@ -251,6 +255,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -31,16 +31,6 @@ void main() {
group('Bootstrap', () { group('Bootstrap', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
Map<String, dynamic> oldSecret; Map<String, dynamic> oldSecret;
@ -52,6 +42,16 @@ void main() {
}); });
test('setup', () async { test('setup', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Bootstrap bootstrap; Bootstrap bootstrap;
bootstrap = client.encryption.bootstrap( bootstrap = client.encryption.bootstrap(
onUpdate: () async { onUpdate: () async {
@ -108,6 +108,7 @@ void main() {
}, timeout: Timeout(Duration(minutes: 2))); }, timeout: Timeout(Duration(minutes: 2)));
test('change recovery passphrase', () async { test('change recovery passphrase', () async {
if (!olmEnabled) return;
Bootstrap bootstrap; Bootstrap bootstrap;
bootstrap = client.encryption.bootstrap( bootstrap = client.encryption.bootstrap(
onUpdate: () async { onUpdate: () async {
@ -158,6 +159,7 @@ void main() {
}, timeout: Timeout(Duration(minutes: 2))); }, timeout: Timeout(Duration(minutes: 2)));
test('change passphrase with multiple keys', () async { test('change passphrase with multiple keys', () async {
if (!olmEnabled) return;
await client.setAccountData(client.userID, 'foxes', oldSecret); await client.setAccountData(client.userID, 'foxes', oldSecret);
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
@ -212,6 +214,7 @@ void main() {
}, timeout: Timeout(Duration(minutes: 2))); }, timeout: Timeout(Duration(minutes: 2)));
test('setup new ssss', () async { test('setup new ssss', () async {
if (!olmEnabled) return;
client.accountData.clear(); client.accountData.clear();
Bootstrap bootstrap; Bootstrap bootstrap;
bootstrap = client.encryption.bootstrap( bootstrap = client.encryption.bootstrap(
@ -237,6 +240,7 @@ void main() {
}, timeout: Timeout(Duration(minutes: 2))); }, timeout: Timeout(Duration(minutes: 2)));
test('bad ssss', () async { test('bad ssss', () async {
if (!olmEnabled) return;
client.accountData.clear(); client.accountData.clear();
await client.setAccountData(client.userID, 'foxes', oldSecret); await client.setAccountData(client.userID, 'foxes', oldSecret);
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
@ -262,6 +266,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -30,28 +30,30 @@ void main() {
group('Cross Signing', () { group('Cross Signing', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
}); });
test('basic things', () async { test('basic things', () async {
if (!olmEnabled) return;
expect(client.encryption.crossSigning.enabled, true); expect(client.encryption.crossSigning.enabled, true);
}); });
test('selfSign', () async { test('selfSign', () async {
if (!olmEnabled) return;
final key = client.userDeviceKeys[client.userID].masterKey; final key = client.userDeviceKeys[client.userID].masterKey;
key.setDirectVerified(false); key.setDirectVerified(false);
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
@ -65,6 +67,7 @@ void main() {
}); });
test('signable', () async { test('signable', () async {
if (!olmEnabled) return;
expect( expect(
client.encryption.crossSigning client.encryption.crossSigning
.signable([client.userDeviceKeys[client.userID].masterKey]), .signable([client.userDeviceKeys[client.userID].masterKey]),
@ -86,6 +89,7 @@ void main() {
}); });
test('sign', () async { test('sign', () async {
if (!olmEnabled) return;
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
await client.encryption.crossSigning.sign([ await client.encryption.crossSigning.sign([
client.userDeviceKeys[client.userID].masterKey, client.userDeviceKeys[client.userID].masterKey,
@ -109,6 +113,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -27,16 +27,6 @@ void main() {
group('Encrypt/Decrypt room message', () { group('Encrypt/Decrypt room message', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
final roomId = '!726s6s6q:example.com'; final roomId = '!726s6s6q:example.com';
@ -45,11 +35,22 @@ void main() {
final now = DateTime.now(); final now = DateTime.now();
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
room = client.getRoomById(roomId); room = client.getRoomById(roomId);
}); });
test('encrypt payload', () async { test('encrypt payload', () async {
if (!olmEnabled) return;
payload = await client.encryption.encryptGroupMessagePayload(roomId, { payload = await client.encryption.encryptGroupMessagePayload(roomId, {
'msgtype': 'm.text', 'msgtype': 'm.text',
'text': 'Hello foxies!', 'text': 'Hello foxies!',
@ -62,6 +63,7 @@ void main() {
}); });
test('decrypt payload', () async { test('decrypt payload', () async {
if (!olmEnabled) return;
final encryptedEvent = Event( final encryptedEvent = Event(
type: EventTypes.Encrypted, type: EventTypes.Encrypted,
content: payload, content: payload,
@ -78,6 +80,7 @@ void main() {
}); });
test('decrypt payload nocache', () async { test('decrypt payload nocache', () async {
if (!olmEnabled) return;
client.encryption.keyManager.clearInboundGroupSessions(); client.encryption.keyManager.clearInboundGroupSessions();
final encryptedEvent = Event( final encryptedEvent = Event(
type: EventTypes.Encrypted, type: EventTypes.Encrypted,
@ -98,6 +101,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -33,16 +33,6 @@ void main() {
group('Encrypt/Decrypt to-device messages', () { group('Encrypt/Decrypt to-device messages', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
var otherClient = Client('othertestclient', var otherClient = Client('othertestclient',
@ -51,6 +41,16 @@ void main() {
Map<String, dynamic> payload; Map<String, dynamic> payload;
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
await client.abortSync(); await client.abortSync();
await otherClient.checkHomeserver('https://fakeserver.notexisting', await otherClient.checkHomeserver('https://fakeserver.notexisting',
@ -81,11 +81,13 @@ void main() {
}); });
test('encryptToDeviceMessage', () async { test('encryptToDeviceMessage', () async {
if (!olmEnabled) return;
payload = await otherClient.encryption payload = await otherClient.encryption
.encryptToDeviceMessage([device], 'm.to_device', {'hello': 'foxies'}); .encryptToDeviceMessage([device], 'm.to_device', {'hello': 'foxies'});
}); });
test('decryptToDeviceEvent', () async { test('decryptToDeviceEvent', () async {
if (!olmEnabled) return;
final encryptedEvent = ToDeviceEvent( final encryptedEvent = ToDeviceEvent(
sender: '@othertest:fakeServer.notExisting', sender: '@othertest:fakeServer.notExisting',
type: EventTypes.Encrypted, type: EventTypes.Encrypted,
@ -98,6 +100,7 @@ void main() {
}); });
test('decryptToDeviceEvent nocache', () async { test('decryptToDeviceEvent nocache', () async {
if (!olmEnabled) return;
client.encryption.olmManager.olmSessions.clear(); client.encryption.olmManager.olmSessions.clear();
payload = await otherClient.encryption.encryptToDeviceMessage( payload = await otherClient.encryption.encryptToDeviceMessage(
[device], 'm.to_device', {'hello': 'superfoxies'}); [device], 'm.to_device', {'hello': 'superfoxies'});
@ -113,6 +116,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
await otherClient.dispose(closeDatabase: true); await otherClient.dispose(closeDatabase: true);
}); });

View File

@ -29,24 +29,25 @@ void main() {
group('Key Manager', () { group('Key Manager', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
}); });
test('handle new m.room_key', () async { test('handle new m.room_key', () async {
if (!olmEnabled) return;
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU'; final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg'; final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
final sessionKey = final sessionKey =
@ -94,6 +95,7 @@ void main() {
}); });
test('outbound group session', () async { test('outbound group session', () async {
if (!olmEnabled) return;
final roomId = '!726s6s6q:example.com'; final roomId = '!726s6s6q:example.com';
expect( expect(
client.encryption.keyManager.getOutboundGroupSession(roomId) != null, client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
@ -244,6 +246,7 @@ void main() {
}); });
test('inbound group session', () async { test('inbound group session', () async {
if (!olmEnabled) return;
final roomId = '!726s6s6q:example.com'; final roomId = '!726s6s6q:example.com';
final sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU'; final sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg'; final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
@ -325,6 +328,7 @@ void main() {
}); });
test('setInboundGroupSession', () async { test('setInboundGroupSession', () async {
if (!olmEnabled) return;
final session = olm.OutboundGroupSession(); final session = olm.OutboundGroupSession();
session.create(); session.create();
final inbound = olm.InboundGroupSession(); final inbound = olm.InboundGroupSession();
@ -495,6 +499,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -42,20 +42,20 @@ void main() {
group('Key Request', () { group('Key Request', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU'; final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg'; final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
test('Create Request', () async { test('Create Request', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
var matrix = await getClient(); var matrix = await getClient();
final requestRoom = matrix.getRoomById('!726s6s6q:example.com'); final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
await matrix.encryption.keyManager.request( await matrix.encryption.keyManager.request(
@ -83,6 +83,7 @@ void main() {
await matrix.dispose(closeDatabase: true); await matrix.dispose(closeDatabase: true);
}); });
test('Reply To Request', () async { test('Reply To Request', () async {
if (!olmEnabled) return;
var matrix = await getClient(); var matrix = await getClient();
matrix.setUserId('@alice:example.com'); // we need to pretend to be alice matrix.setUserId('@alice:example.com'); // we need to pretend to be alice
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
@ -277,6 +278,7 @@ void main() {
await matrix.dispose(closeDatabase: true); await matrix.dispose(closeDatabase: true);
}); });
test('Receive shared keys', () async { test('Receive shared keys', () async {
if (!olmEnabled) return;
var matrix = await getClient(); var matrix = await getClient();
final requestRoom = matrix.getRoomById('!726s6s6q:example.com'); final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
await matrix.encryption.keyManager.request( await matrix.encryption.keyManager.request(

View File

@ -64,16 +64,6 @@ void main() {
group('Key Verification', () { group('Key Verification', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
// key @othertest:fakeServer.notExisting // key @othertest:fakeServer.notExisting
const otherPickledOlmAccount = const otherPickledOlmAccount =
@ -83,6 +73,16 @@ void main() {
Client client2; Client client2;
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client1 = await getClient(); client1 = await getClient();
client2 = Client('othertestclient', client2 = Client('othertestclient',
httpClient: FakeMatrixApi(), httpClient: FakeMatrixApi(),
@ -109,6 +109,7 @@ void main() {
}); });
test('Run emoji / number verification', () async { test('Run emoji / number verification', () async {
if (!olmEnabled) return;
// for a full run we test in-room verification in a cleartext room // for a full run we test in-room verification in a cleartext room
// because then we can easily intercept the payloads and inject in the other client // because then we can easily intercept the payloads and inject in the other client
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
@ -209,6 +210,7 @@ void main() {
}); });
test('ask SSSS start', () async { test('ask SSSS start', () async {
if (!olmEnabled) return;
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true); client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true);
await client1.encryption.ssss.clearCache(); await client1.encryption.ssss.clearCache();
final req1 = final req1 =
@ -223,6 +225,7 @@ void main() {
}); });
test('ask SSSS end', () async { test('ask SSSS end', () async {
if (!olmEnabled) return;
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
// make sure our master key is *not* verified to not triger SSSS for now // make sure our master key is *not* verified to not triger SSSS for now
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
@ -327,6 +330,7 @@ void main() {
}); });
test('reject verification', () async { test('reject verification', () async {
if (!olmEnabled) return;
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
// make sure our master key is *not* verified to not triger SSSS for now // make sure our master key is *not* verified to not triger SSSS for now
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
@ -355,6 +359,7 @@ void main() {
}); });
test('reject sas', () async { test('reject sas', () async {
if (!olmEnabled) return;
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
// make sure our master key is *not* verified to not triger SSSS for now // make sure our master key is *not* verified to not triger SSSS for now
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
@ -415,6 +420,7 @@ void main() {
}); });
test('other device accepted', () async { test('other device accepted', () async {
if (!olmEnabled) return;
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
// make sure our master key is *not* verified to not triger SSSS for now // make sure our master key is *not* verified to not triger SSSS for now
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false); client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
@ -460,6 +466,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client1.dispose(closeDatabase: true); await client1.dispose(closeDatabase: true);
await client2.dispose(closeDatabase: true); await client2.dispose(closeDatabase: true);
}); });

View File

@ -30,24 +30,25 @@ void main() {
group('Olm Manager', () { group('Olm Manager', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
}); });
test('signatures', () async { test('signatures', () async {
if (!olmEnabled) return;
final payload = <String, dynamic>{ final payload = <String, dynamic>{
'fox': 'floof', 'fox': 'floof',
}; };
@ -59,6 +60,7 @@ void main() {
}); });
test('uploadKeys', () async { test('uploadKeys', () async {
if (!olmEnabled) return;
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
final res = final res =
await client.encryption.olmManager.uploadKeys(uploadDeviceKeys: true); await client.encryption.olmManager.uploadKeys(uploadDeviceKeys: true);
@ -68,22 +70,28 @@ void main() {
expect(sent['device_keys'] != null, true); expect(sent['device_keys'] != null, true);
expect(sent['one_time_keys'] != null, true); expect(sent['one_time_keys'] != null, true);
expect(sent['one_time_keys'].keys.length, 66); expect(sent['one_time_keys'].keys.length, 66);
expect(sent['fallback_keys'] != null, true);
expect(sent['fallback_keys'].keys.length, 1);
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
await client.encryption.olmManager.uploadKeys(); await client.encryption.olmManager.uploadKeys();
sent = json.decode( sent = json.decode(
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first); FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
expect(sent['device_keys'] != null, false); expect(sent['device_keys'] != null, false);
expect(sent['fallback_keys'].keys.length, 1);
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
await client.encryption.olmManager.uploadKeys(oldKeyCount: 20); await client.encryption.olmManager
.uploadKeys(oldKeyCount: 20, unusedFallbackKey: true);
sent = json.decode( sent = json.decode(
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first); FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
expect(sent['one_time_keys'].keys.length, 46); expect(sent['one_time_keys'].keys.length, 46);
expect(sent['fallback_keys'].keys.length, 0);
}); });
test('handleDeviceOneTimeKeysCount', () async { test('handleDeviceOneTimeKeysCount', () async {
if (!olmEnabled) return;
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
client.encryption.olmManager client.encryption.olmManager
.handleDeviceOneTimeKeysCount({'signed_curve25519': 20}); .handleDeviceOneTimeKeysCount({'signed_curve25519': 20}, null);
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect( expect(
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'), FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
@ -91,7 +99,22 @@ void main() {
FakeMatrixApi.calledEndpoints.clear(); FakeMatrixApi.calledEndpoints.clear();
client.encryption.olmManager client.encryption.olmManager
.handleDeviceOneTimeKeysCount({'signed_curve25519': 70}); .handleDeviceOneTimeKeysCount({'signed_curve25519': 70}, null);
await Future.delayed(Duration(milliseconds: 50));
expect(
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
false);
FakeMatrixApi.calledEndpoints.clear();
client.encryption.olmManager.handleDeviceOneTimeKeysCount(null, []);
await Future.delayed(Duration(milliseconds: 50));
expect(
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
true);
FakeMatrixApi.calledEndpoints.clear();
client.encryption.olmManager
.handleDeviceOneTimeKeysCount(null, ['signed_curve25519']);
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
expect( expect(
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'), FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
@ -99,6 +122,7 @@ void main() {
}); });
test('restoreOlmSession', () async { test('restoreOlmSession', () async {
if (!olmEnabled) return;
client.encryption.olmManager.olmSessions.clear(); client.encryption.olmManager.olmSessions.clear();
await client.encryption.olmManager await client.encryption.olmManager
.restoreOlmSession(client.userID, client.identityKey); .restoreOlmSession(client.userID, client.identityKey);
@ -116,6 +140,7 @@ void main() {
}); });
test('startOutgoingOlmSessions', () async { test('startOutgoingOlmSessions', () async {
if (!olmEnabled) return;
// start an olm session.....with ourself! // start an olm session.....with ourself!
client.encryption.olmManager.olmSessions.clear(); client.encryption.olmManager.olmSessions.clear();
await client.encryption.olmManager.startOutgoingOlmSessions( await client.encryption.olmManager.startOutgoingOlmSessions(
@ -127,6 +152,7 @@ void main() {
}); });
test('replay to_device events', () async { test('replay to_device events', () async {
if (!olmEnabled) return;
final userId = '@alice:example.com'; final userId = '@alice:example.com';
final deviceId = 'JLAFKJWSCS'; final deviceId = 'JLAFKJWSCS';
final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8'; final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8';
@ -209,6 +235,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -30,16 +30,6 @@ void main() {
group('Online Key Backup', () { group('Online Key Backup', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
@ -48,10 +38,21 @@ void main() {
final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg'; final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
}); });
test('basic things', () async { test('basic things', () async {
if (!olmEnabled) return;
expect(client.encryption.keyManager.enabled, true); expect(client.encryption.keyManager.enabled, true);
expect(await client.encryption.keyManager.isCached(), false); expect(await client.encryption.keyManager.isCached(), false);
final handle = client.encryption.ssss.open(); final handle = client.encryption.ssss.open();
@ -61,6 +62,7 @@ void main() {
}); });
test('load key', () async { test('load key', () async {
if (!olmEnabled) return;
client.encryption.keyManager.clearInboundGroupSessions(); client.encryption.keyManager.clearInboundGroupSessions();
await client.encryption.keyManager await client.encryption.keyManager
.request(client.getRoomById(roomId), sessionId, senderKey); .request(client.getRoomById(roomId), sessionId, senderKey);
@ -72,6 +74,7 @@ void main() {
}); });
test('upload key', () async { test('upload key', () async {
if (!olmEnabled) return;
final session = olm.OutboundGroupSession(); final session = olm.OutboundGroupSession();
session.create(); session.create();
final inbound = olm.InboundGroupSession(); final inbound = olm.InboundGroupSession();
@ -115,6 +118,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -46,29 +46,31 @@ void main() {
group('SSSS', () { group('SSSS', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
Client client; Client client;
test('setupClient', () async { test('setupClient', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return;
client = await getClient(); client = await getClient();
}); });
test('basic things', () async { test('basic things', () async {
if (!olmEnabled) return;
expect(client.encryption.ssss.defaultKeyId, expect(client.encryption.ssss.defaultKeyId,
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3'); '0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3');
}); });
test('encrypt / decrypt', () { test('encrypt / decrypt', () {
if (!olmEnabled) return;
final key = Uint8List.fromList(SecureRandom(32).bytes); final key = Uint8List.fromList(SecureRandom(32).bytes);
final enc = SSSS.encryptAes('secret foxies', key, 'name'); final enc = SSSS.encryptAes('secret foxies', key, 'name');
@ -77,6 +79,7 @@ void main() {
}); });
test('store', () async { test('store', () async {
if (!olmEnabled) return;
final handle = client.encryption.ssss.open(); final handle = client.encryption.ssss.open();
var failed = false; var failed = false;
try { try {
@ -113,6 +116,7 @@ void main() {
}); });
test('encode / decode recovery key', () async { test('encode / decode recovery key', () async {
if (!olmEnabled) return;
final key = Uint8List.fromList(SecureRandom(32).bytes); final key = Uint8List.fromList(SecureRandom(32).bytes);
final encoded = SSSS.encodeRecoveryKey(key); final encoded = SSSS.encodeRecoveryKey(key);
final decoded = SSSS.decodeRecoveryKey(encoded); final decoded = SSSS.decodeRecoveryKey(encoded);
@ -124,6 +128,7 @@ void main() {
}); });
test('cache', () async { test('cache', () async {
if (!olmEnabled) return;
await client.encryption.ssss.clearCache(); await client.encryption.ssss.clearCache();
final handle = final handle =
client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning); client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning);
@ -157,6 +162,7 @@ void main() {
}); });
test('postUnlock', () async { test('postUnlock', () async {
if (!olmEnabled) return;
await client.encryption.ssss.clearCache(); await client.encryption.ssss.clearCache();
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false); client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false);
final handle = final handle =
@ -181,6 +187,7 @@ void main() {
}); });
test('make share requests', () async { test('make share requests', () async {
if (!olmEnabled) return;
final key = final key =
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
key.setDirectVerified(true); key.setDirectVerified(true);
@ -193,6 +200,7 @@ void main() {
}); });
test('answer to share requests', () async { test('answer to share requests', () async {
if (!olmEnabled) return;
var event = ToDeviceEvent( var event = ToDeviceEvent(
sender: client.userID, sender: client.userID,
type: 'm.secret.request', type: 'm.secret.request',
@ -291,6 +299,7 @@ void main() {
}); });
test('receive share requests', () async { test('receive share requests', () async {
if (!olmEnabled) return;
final key = final key =
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
key.setDirectVerified(true); key.setDirectVerified(true);
@ -433,6 +442,7 @@ void main() {
}); });
test('request all', () async { test('request all', () async {
if (!olmEnabled) return;
final key = final key =
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE']; client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
key.setDirectVerified(true); key.setDirectVerified(true);
@ -443,6 +453,7 @@ void main() {
}); });
test('periodicallyRequestMissingCache', () async { test('periodicallyRequestMissingCache', () async {
if (!olmEnabled) return;
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(true); client.userDeviceKeys[client.userID].masterKey.setDirectVerified(true);
client.encryption.ssss = MockSSSS(client.encryption); client.encryption.ssss = MockSSSS(client.encryption);
(client.encryption.ssss as MockSSSS).requestedSecrets = false; (client.encryption.ssss as MockSSSS).requestedSecrets = false;
@ -455,6 +466,7 @@ void main() {
}); });
test('createKey', () async { test('createKey', () async {
if (!olmEnabled) return;
// with passphrase // with passphrase
var newKey = await client.encryption.ssss.createKey('test'); var newKey = await client.encryption.ssss.createKey('test');
expect(client.encryption.ssss.isKeyValid(newKey.keyId), true); expect(client.encryption.ssss.isKeyValid(newKey.keyId), true);
@ -470,6 +482,7 @@ void main() {
}); });
test('dispose client', () async { test('dispose client', () async {
if (!olmEnabled) return;
await client.dispose(closeDatabase: true); await client.dispose(closeDatabase: true);
}); });
}); });

View File

@ -35,14 +35,6 @@ void main() {
group('Event', () { group('Event', () {
Logs().level = Level.error; Logs().level = Level.error;
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
final timestamp = DateTime.now().millisecondsSinceEpoch; final timestamp = DateTime.now().millisecondsSinceEpoch;
final id = '!4fsdfjisjf:server.abc'; final id = '!4fsdfjisjf:server.abc';
@ -68,6 +60,17 @@ void main() {
var event = Event.fromJson( var event = Event.fromJson(
jsonObj, Room(id: '!localpart:server.abc', client: client)); jsonObj, Room(id: '!localpart:server.abc', client: client));
test('setup', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
});
test('Create from json', () async { test('Create from json', () async {
jsonObj.remove('status'); jsonObj.remove('status');
jsonObj['content'] = json.decode(contentJson); jsonObj['content'] = json.decode(contentJson);

View File

@ -35,19 +35,19 @@ void main() {
var updateCount = 0; var updateCount = 0;
var insertList = <int>[]; var insertList = <int>[];
var olmEnabled = true; var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
Client client; Client client;
Room room; Room room;
Timeline timeline; Timeline timeline;
test('create stuff', () async { test('create stuff', () async {
try {
await olm.init();
olm.get_library_version();
} catch (e) {
olmEnabled = false;
Logs().w('[LibOlm] Failed to load LibOlm', e);
}
Logs().i('[LibOlm] Enabled: $olmEnabled');
client = await getClient(); client = await getClient();
client.sendMessageTimeoutSeconds = 5; client.sendMessageTimeoutSeconds = 5;