matrix-0.8.13/test_driver/matrixsdk_test.dart

340 lines
14 KiB
Dart

/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020, 2021 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:matrix/matrix.dart';
import '../test/fake_database.dart';
import 'test_config.dart';
import 'package:olm/olm.dart' as olm;
void main() => test();
const String testMessage = 'Hello world';
const String testMessage2 = 'Hello moon';
const String testMessage3 = 'Hello sun';
const String testMessage4 = 'Hello star';
const String testMessage5 = 'Hello earth';
const String testMessage6 = 'Hello mars';
void test() async {
Client? testClientA, testClientB;
try {
await olm.init();
olm.Account();
Logs().i('[LibOlm] Enabled');
Logs().i('++++ Login Alice at ++++');
testClientA = Client('TestClientA', databaseBuilder: getDatabase);
await testClientA.checkHomeserver(TestUser.homeserver);
await testClientA.login(LoginType.mLoginPassword,
identifier: AuthenticationUserIdentifier(user: TestUser.username),
password: TestUser.password);
assert(testClientA.encryptionEnabled);
Logs().i('++++ Login Bob ++++');
testClientB = Client('TestClientB', databaseBuilder: getDatabase);
await testClientB.checkHomeserver(TestUser.homeserver);
await testClientB.login(LoginType.mLoginPassword,
identifier: AuthenticationUserIdentifier(user: TestUser.username2),
password: TestUser.password);
assert(testClientB.encryptionEnabled);
Logs().i('++++ (Alice) Leave all rooms ++++');
while (testClientA.rooms.isNotEmpty) {
final room = testClientA.rooms.first;
if (room.canonicalAlias.isNotEmpty) {
break;
}
try {
await room.leave();
await room.forget();
} catch (_) {}
}
Logs().i('++++ (Bob) Leave all rooms ++++');
for (var i = 0; i < 3; i++) {
if (testClientB.rooms.isNotEmpty) {
final room = testClientB.rooms.first;
try {
await room.leave();
await room.forget();
} catch (_) {}
}
}
Logs().i('++++ Check if own olm device is verified by default ++++');
assert(testClientA.userDeviceKeys.containsKey(TestUser.username));
assert(testClientA.userDeviceKeys[TestUser.username]!.deviceKeys
.containsKey(testClientA.deviceID));
assert(testClientA.userDeviceKeys[TestUser.username]!
.deviceKeys[testClientA.deviceID!]!.verified);
assert(!testClientA.userDeviceKeys[TestUser.username]!
.deviceKeys[testClientA.deviceID!]!.blocked);
assert(testClientB.userDeviceKeys.containsKey(TestUser.username2));
assert(testClientB.userDeviceKeys[TestUser.username2]!.deviceKeys
.containsKey(testClientB.deviceID));
assert(testClientB.userDeviceKeys[TestUser.username2]!
.deviceKeys[testClientB.deviceID!]!.verified);
assert(!testClientB.userDeviceKeys[TestUser.username2]!
.deviceKeys[testClientB.deviceID!]!.blocked);
Logs().i('++++ (Alice) Create room and invite Bob ++++');
await testClientA.createRoom(invite: [TestUser.username2]);
await Future.delayed(Duration(seconds: 1));
final room = testClientA.rooms.first;
final roomId = room.id;
Logs().i('++++ (Bob) Join room ++++');
final inviteRoom = testClientB.getRoomById(roomId)!;
await inviteRoom.join();
await Future.delayed(Duration(seconds: 1));
assert(inviteRoom.membership == Membership.join);
Logs().i('++++ (Alice) Enable encryption ++++');
assert(room.encrypted == false);
await room.enableEncryption();
await Future.delayed(Duration(seconds: 5));
assert(room.encrypted == true);
assert(
room.client.encryption!.keyManager.getOutboundGroupSession(room.id) ==
null);
Logs().i('++++ (Alice) Check known olm devices ++++');
assert(testClientA.userDeviceKeys.containsKey(TestUser.username2));
assert(testClientA.userDeviceKeys[TestUser.username2]!.deviceKeys
.containsKey(testClientB.deviceID));
assert(!testClientA.userDeviceKeys[TestUser.username2]!
.deviceKeys[testClientB.deviceID!]!.verified);
assert(!testClientA.userDeviceKeys[TestUser.username2]!
.deviceKeys[testClientB.deviceID!]!.blocked);
assert(testClientB.userDeviceKeys.containsKey(TestUser.username));
assert(testClientB.userDeviceKeys[TestUser.username]!.deviceKeys
.containsKey(testClientA.deviceID));
assert(!testClientB.userDeviceKeys[TestUser.username]!
.deviceKeys[testClientA.deviceID!]!.verified);
assert(!testClientB.userDeviceKeys[TestUser.username]!
.deviceKeys[testClientA.deviceID!]!.blocked);
await testClientA
.userDeviceKeys[TestUser.username2]!.deviceKeys[testClientB.deviceID!]!
.setVerified(true);
Logs().i('++++ Check if own olm device is verified by default ++++');
assert(testClientA.userDeviceKeys.containsKey(TestUser.username));
assert(testClientA.userDeviceKeys[TestUser.username]!.deviceKeys
.containsKey(testClientA.deviceID));
assert(testClientA.userDeviceKeys[TestUser.username]!
.deviceKeys[testClientA.deviceID!]!.verified);
assert(testClientB.userDeviceKeys.containsKey(TestUser.username2));
assert(testClientB.userDeviceKeys[TestUser.username2]!.deviceKeys
.containsKey(testClientB.deviceID));
assert(testClientB.userDeviceKeys[TestUser.username2]!
.deviceKeys[testClientB.deviceID!]!.verified);
Logs().i("++++ (Alice) Send encrypted message: '$testMessage' ++++");
await room.sendTextEvent(testMessage);
await Future.delayed(Duration(seconds: 5));
assert(
room.client.encryption!.keyManager.getOutboundGroupSession(room.id) !=
null);
var currentSessionIdA = room.client.encryption!.keyManager
.getOutboundGroupSession(room.id)!
.outboundGroupSession!
.session_id();
/*assert(room.client.encryption.keyManager
.getInboundGroupSession(room.id, currentSessionIdA, '') !=
null);*/
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.length ==
1);
assert(testClientB.encryption!.olmManager
.olmSessions[testClientA.identityKey]!.length ==
1);
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.first.sessionId ==
testClientB.encryption!.olmManager.olmSessions[testClientA.identityKey]!
.first.sessionId);
/*assert(inviteRoom.client.encryption.keyManager
.getInboundGroupSession(inviteRoom.id, currentSessionIdA, '') !=
null);*/
assert(room.lastEvent!.body == testMessage);
assert(inviteRoom.lastEvent!.body == testMessage);
Logs().i(
"++++ (Bob) Received decrypted message: '${inviteRoom.lastEvent!.body}' ++++");
Logs().i("++++ (Alice) Send again encrypted message: '$testMessage2' ++++");
await room.sendTextEvent(testMessage2);
await Future.delayed(Duration(seconds: 5));
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.length ==
1);
assert(testClientB.encryption!.olmManager
.olmSessions[testClientA.identityKey]!.length ==
1);
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.first.sessionId ==
testClientB.encryption!.olmManager.olmSessions[testClientA.identityKey]!
.first.sessionId);
assert(room.client.encryption!.keyManager
.getOutboundGroupSession(room.id)!
.outboundGroupSession!
.session_id() ==
currentSessionIdA);
/*assert(room.client.encryption.keyManager
.getInboundGroupSession(room.id, currentSessionIdA, '') !=
null);*/
assert(room.lastEvent!.body == testMessage2);
assert(inviteRoom.lastEvent!.body == testMessage2);
Logs().i(
"++++ (Bob) Received decrypted message: '${inviteRoom.lastEvent!.body}' ++++");
Logs().i("++++ (Bob) Send again encrypted message: '$testMessage3' ++++");
await inviteRoom.sendTextEvent(testMessage3);
await Future.delayed(Duration(seconds: 5));
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.length ==
1);
assert(testClientB.encryption!.olmManager
.olmSessions[testClientA.identityKey]!.length ==
1);
assert(room.client.encryption!.keyManager
.getOutboundGroupSession(room.id)!
.outboundGroupSession!
.session_id() ==
currentSessionIdA);
final inviteRoomOutboundGroupSession = inviteRoom
.client.encryption!.keyManager
.getOutboundGroupSession(inviteRoom.id)!;
assert(inviteRoomOutboundGroupSession.isValid);
/*assert(inviteRoom.client.encryption.keyManager.getInboundGroupSession(
inviteRoom.id,
inviteRoomOutboundGroupSession.outboundGroupSession.session_id(),
'') !=
null);
assert(room.client.encryption.keyManager.getInboundGroupSession(
room.id,
inviteRoomOutboundGroupSession.outboundGroupSession.session_id(),
'') !=
null);*/
assert(inviteRoom.lastEvent!.body == testMessage3);
assert(room.lastEvent!.body == testMessage3);
Logs().i(
"++++ (Alice) Received decrypted message: '${room.lastEvent!.body}' ++++");
Logs().i('++++ Login Bob in another client ++++');
final testClientC = Client('TestClientC', databaseBuilder: getDatabase);
await testClientC.checkHomeserver(TestUser.homeserver);
await testClientC.login(LoginType.mLoginPassword,
identifier: AuthenticationUserIdentifier(user: TestUser.username2),
password: TestUser.password);
await Future.delayed(Duration(seconds: 3));
Logs().i("++++ (Alice) Send again encrypted message: '$testMessage4' ++++");
await room.sendTextEvent(testMessage4);
await Future.delayed(Duration(seconds: 5));
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.length ==
1);
assert(testClientB.encryption!.olmManager
.olmSessions[testClientA.identityKey]!.length ==
1);
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.first.sessionId ==
testClientB.encryption!.olmManager.olmSessions[testClientA.identityKey]!
.first.sessionId);
assert(testClientA.encryption!.olmManager
.olmSessions[testClientC.identityKey]!.length ==
1);
assert(testClientC.encryption!.olmManager
.olmSessions[testClientA.identityKey]!.length ==
1);
assert(testClientA.encryption!.olmManager
.olmSessions[testClientC.identityKey]!.first.sessionId ==
testClientC.encryption!.olmManager.olmSessions[testClientA.identityKey]!
.first.sessionId);
assert(room.client.encryption!.keyManager
.getOutboundGroupSession(room.id)!
.outboundGroupSession!
.session_id() !=
currentSessionIdA);
currentSessionIdA = room.client.encryption!.keyManager
.getOutboundGroupSession(room.id)!
.outboundGroupSession!
.session_id();
/*assert(inviteRoom.client.encryption.keyManager
.getInboundGroupSession(inviteRoom.id, currentSessionIdA, '') !=
null);*/
assert(room.lastEvent!.body == testMessage4);
assert(inviteRoom.lastEvent!.body == testMessage4);
Logs().i(
"++++ (Bob) Received decrypted message: '${inviteRoom.lastEvent!.body}' ++++");
Logs().i('++++ Logout Bob another client ++++');
await testClientC.dispose(closeDatabase: false);
await testClientC.logout();
await Future.delayed(Duration(seconds: 5));
Logs().i("++++ (Alice) Send again encrypted message: '$testMessage6' ++++");
await room.sendTextEvent(testMessage6);
await Future.delayed(Duration(seconds: 5));
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.length ==
1);
assert(testClientB.encryption!.olmManager
.olmSessions[testClientA.identityKey]!.length ==
1);
assert(testClientA.encryption!.olmManager
.olmSessions[testClientB.identityKey]!.first.sessionId ==
testClientB.encryption!.olmManager.olmSessions[testClientA.identityKey]!
.first.sessionId);
assert(room.client.encryption!.keyManager
.getOutboundGroupSession(room.id)!
.outboundGroupSession!
.session_id() !=
currentSessionIdA);
currentSessionIdA = room.client.encryption!.keyManager
.getOutboundGroupSession(room.id)!
.outboundGroupSession!
.session_id();
/*assert(inviteRoom.client.encryption.keyManager
.getInboundGroupSession(inviteRoom.id, currentSessionIdA, '') !=
null);*/
assert(room.lastEvent!.body == testMessage6);
assert(inviteRoom.lastEvent!.body == testMessage6);
Logs().i(
"++++ (Bob) Received decrypted message: '${inviteRoom.lastEvent!.body}' ++++");
await room.leave();
await room.forget();
await inviteRoom.leave();
await inviteRoom.forget();
await Future.delayed(Duration(seconds: 1));
} catch (e, s) {
Logs().e('Test failed', e, s);
rethrow;
} finally {
Logs().i('++++ Logout Alice and Bob ++++');
if (testClientA?.isLogged() ?? false) await testClientA!.logoutAll();
if (testClientA?.isLogged() ?? false) await testClientB!.logoutAll();
await testClientA?.dispose(closeDatabase: false);
await testClientB?.dispose(closeDatabase: false);
testClientA = null;
testClientB = null;
}
return;
}