refactor: Check server

This commit is contained in:
Christian Pauly 2020-10-23 11:34:08 +02:00
parent 343c26b3ed
commit 5381c3935c
11 changed files with 73 additions and 70 deletions

View File

@ -26,45 +26,38 @@ import 'package:famedlysdk/famedlysdk.dart';
2. Create a new client: 2. Create a new client:
```dart ```dart
Client matrix = Client("HappyChat"); Client client = Client("HappyChat");
``` ```
Take a look here for an example store: Take a look here for an example store:
[https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets](https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets) [https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets](https://gitlab.com/ChristianPauly/fluffychat-flutter/snippets)
```dart
Client matrix = Client("HappyChat");
```
3. Connect to a Matrix Homeserver and listen to the streams: 3. Connect to a Matrix Homeserver and listen to the streams:
```dart ```dart
matrix.onLoginStateChanged.stream.listen((bool loginState){ client.onLoginStateChanged.stream.listen((bool loginState){
print("LoginState: ${loginState.toString()}"); print("LoginState: ${loginState.toString()}");
}); });
matrix.onEvent.stream.listen((EventUpdate eventUpdate){ client.onEvent.stream.listen((EventUpdate eventUpdate){
print("New event update!"); print("New event update!");
}); });
matrix.onRoomUpdate.stream.listen((RoomUpdate eventUpdate){ client.onRoomUpdate.stream.listen((RoomUpdate eventUpdate){
print("New room update!"); print("New room update!");
}); });
final bool serverValid = await matrix.checkServer("https://yourhomeserver.abc"); try {
await client.checkHomeserver("https://yourhomeserver.abc");
final bool loginValid = await matrix.login("username", "password"); await client.login("username", "password");
}
catch(e) {
print('No luck...');
}
``` ```
4. Send a message to a Room: 4. Send a message to a Room:
```dart ```dart
final resp = await matrix.jsonRequest( await client.getRoomById('your_room_id').sendTextEvent('Hello world');
type: "PUT",
action: "/r0/rooms/!fjd823j:example.com/send/m.room.message/$txnId",
data: {
"msgtype": "m.text",
"body": "hello"
}
);
``` ```

View File

@ -232,43 +232,51 @@ class Client extends MatrixApi {
return WellKnownInformations.fromJson(rawJson); return WellKnownInformations.fromJson(rawJson);
} }
/// Checks the supported versions of the Matrix protocol and the supported @Deprecated('Use [checkHomeserver] instead.')
/// login types. Returns false if the server is not compatible with the
/// client.
/// Throws FormatException, TimeoutException and MatrixException on error.
Future<bool> checkServer(dynamic serverUrl) async { Future<bool> checkServer(dynamic serverUrl) async {
try { try {
if (serverUrl is Uri) { await checkHomeserver(serverUrl);
homeserver = serverUrl; } catch (_) {
return false;
}
return true;
}
/// Checks the supported versions of the Matrix protocol and the supported
/// login types. Throws an exception if the server is not compatible with the
/// client and sets [homeserver] to [serverUrl] if it is. Supports the types [Uri]
/// and [String].
Future<void> checkHomeserver(dynamic homeserverUrl,
{Set<String> supportedLoginTypes = supportedLoginTypes}) async {
try {
if (homeserverUrl is Uri) {
homeserver = homeserverUrl;
} else { } else {
// URLs allow to have whitespace surrounding them, see https://www.w3.org/TR/2011/WD-html5-20110525/urls.html // URLs allow to have whitespace surrounding them, see https://www.w3.org/TR/2011/WD-html5-20110525/urls.html
// As we want to strip a trailing slash, though, we have to trim the url ourself // As we want to strip a trailing slash, though, we have to trim the url ourself
// and thus can't let Uri.parse() deal with it. // and thus can't let Uri.parse() deal with it.
serverUrl = serverUrl.trim(); homeserverUrl = homeserverUrl.trim();
// strip a trailing slash // strip a trailing slash
if (serverUrl.endsWith('/')) { if (homeserverUrl.endsWith('/')) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1); homeserverUrl = homeserverUrl.substring(0, homeserverUrl.length - 1);
} }
homeserver = Uri.parse(serverUrl); homeserver = Uri.parse(homeserverUrl);
} }
final versions = await requestSupportedVersions(); final versions = await requestSupportedVersions();
for (var i = 0; i < versions.versions.length; i++) { if (!versions.versions
if (versions.versions[i] == 'r0.5.0' || .any((version) => supportedVersions.contains(version))) {
versions.versions[i] == 'r0.6.0') { throw Exception(
break; 'Server supports the versions: ${versions.versions.toString()} but this application is only compatible with ${supportedVersions.toString()}.');
} else if (i == versions.versions.length - 1) {
return false;
}
} }
final loginTypes = await requestLoginTypes(); final loginTypes = await requestLoginTypes();
if (loginTypes.flows.indexWhere((f) => f.type == 'm.login.password') == if (!loginTypes.flows.any((f) => supportedLoginTypes.contains(f.type))) {
-1) { throw Exception(
return false; 'Server supports the Login Types: ${loginTypes.flows.map((f) => f.toJson).toList().toString()} but this application is only compatible with ${supportedLoginTypes.toString()}.');
} }
return true; return;
} catch (_) { } catch (_) {
homeserver = null; homeserver = null;
rethrow; rethrow;
@ -277,7 +285,7 @@ class Client extends MatrixApi {
/// Checks to see if a username is available, and valid, for the server. /// Checks to see if a username is available, and valid, for the server.
/// Returns the fully-qualified Matrix user ID (MXID) that has been registered. /// Returns the fully-qualified Matrix user ID (MXID) that has been registered.
/// You have to call [checkServer] first to set a homeserver. /// You have to call [checkHomeserver] first to set a homeserver.
@override @override
Future<LoginResponse> register({ Future<LoginResponse> register({
String username, String username,
@ -315,7 +323,7 @@ class Client extends MatrixApi {
/// Handles the login and allows the client to call all APIs which require /// Handles the login and allows the client to call all APIs which require
/// authentication. Returns false if the login was not successful. Throws /// authentication. Returns false if the login was not successful. Throws
/// MatrixException if login was not successful. /// MatrixException if login was not successful.
/// You have to call [checkServer] first to set a homeserver. /// You have to call [checkHomeserver] first to set a homeserver.
@override @override
Future<LoginResponse> login({ Future<LoginResponse> login({
String type = 'm.login.password', String type = 'm.login.password',
@ -479,8 +487,11 @@ class Client extends MatrixApi {
? PushRuleSet.fromJson(accountData['m.push_rules'].content) ? PushRuleSet.fromJson(accountData['m.push_rules'].content)
: null; : null;
static String syncFilters = '{"room":{"state":{"lazy_load_members":true}}}'; static const Set<String> supportedVersions = {'r0.5.0', 'r0.6.0'};
static String messagesFilters = '{"lazy_load_members":true}'; static const Set<String> supportedLoginTypes = {'m.login.password'};
static const String syncFilters =
'{"room":{"state":{"lazy_load_members":true}}}';
static const String messagesFilters = '{"lazy_load_members":true}';
static const List<String> supportedDirectEncryptionAlgorithms = [ static const List<String> supportedDirectEncryptionAlgorithms = [
'm.olm.v1.curve25519-aes-sha2' 'm.olm.v1.curve25519-aes-sha2'
]; ];

View File

@ -77,11 +77,11 @@ void main() {
expect(matrix.homeserver, null); expect(matrix.homeserver, null);
try { try {
await matrix.checkServer('https://fakeserver.wrongaddress'); await matrix.checkHomeserver('https://fakeserver.wrongaddress');
} on FormatException catch (exception) { } on FormatException catch (exception) {
expect(exception != null, true); expect(exception != null, true);
} }
await matrix.checkServer('https://fakeserver.notexisting'); await matrix.checkHomeserver('https://fakeserver.notexisting');
expect(matrix.homeserver.toString(), 'https://fakeserver.notexisting'); expect(matrix.homeserver.toString(), 'https://fakeserver.notexisting');
final available = await matrix.usernameAvailable('testuser'); final available = await matrix.usernameAvailable('testuser');
@ -311,12 +311,11 @@ void main() {
roomUpdateListFuture = matrix.onRoomUpdate.stream.toList(); roomUpdateListFuture = matrix.onRoomUpdate.stream.toList();
eventUpdateListFuture = matrix.onEvent.stream.toList(); eventUpdateListFuture = matrix.onEvent.stream.toList();
final checkResp =
await matrix.checkServer('https://fakeServer.notExisting'); await matrix.checkHomeserver('https://fakeServer.notExisting');
final loginResp = await matrix.login(user: 'test', password: '1234'); final loginResp = await matrix.login(user: 'test', password: '1234');
expect(checkResp, true);
expect(loginResp != null, true); expect(loginResp != null, true);
}); });

View File

@ -50,7 +50,7 @@ void main() {
test('setupClient', () async { test('setupClient', () async {
client = await getClient(); client = await getClient();
otherClient.database = client.database; otherClient.database = client.database;
await otherClient.checkServer('https://fakeServer.notExisting'); await otherClient.checkHomeserver('https://fakeServer.notExisting');
otherClient.connect( otherClient.connect(
newToken: 'abc', newToken: 'abc',
newUserID: '@othertest:fakeServer.notExisting', newUserID: '@othertest:fakeServer.notExisting',

View File

@ -85,7 +85,7 @@ void main() {
client1 = await getClient(); client1 = await getClient();
client2 = Client('othertestclient', httpClient: FakeMatrixApi()); client2 = Client('othertestclient', httpClient: FakeMatrixApi());
client2.database = client1.database; client2.database = client1.database;
await client2.checkServer('https://fakeServer.notExisting'); await client2.checkHomeserver('https://fakeServer.notExisting');
client2.connect( client2.connect(
newToken: 'abc', newToken: 'abc',
newUserID: '@othertest:fakeServer.notExisting', newUserID: '@othertest:fakeServer.notExisting',

View File

@ -264,7 +264,7 @@ void main() {
test('sendAgain', () async { test('sendAgain', () async {
var matrix = Client('testclient', httpClient: FakeMatrixApi()); var matrix = Client('testclient', httpClient: FakeMatrixApi());
await matrix.checkServer('https://fakeServer.notExisting'); await matrix.checkHomeserver('https://fakeServer.notExisting');
await matrix.login(user: 'test', password: '1234'); await matrix.login(user: 'test', password: '1234');
var event = Event.fromJson( var event = Event.fromJson(
@ -280,7 +280,7 @@ void main() {
test('requestKey', () async { test('requestKey', () async {
var matrix = Client('testclient', httpClient: FakeMatrixApi()); var matrix = Client('testclient', httpClient: FakeMatrixApi());
await matrix.checkServer('https://fakeServer.notExisting'); await matrix.checkHomeserver('https://fakeServer.notExisting');
await matrix.login(user: 'test', password: '1234'); await matrix.login(user: 'test', password: '1234');
var event = Event.fromJson( var event = Event.fromJson(
@ -990,7 +990,7 @@ void main() {
THUMBNAIL_BUFF, THUMBNAIL_BUFF,
}[url]; }[url];
}; };
await client.checkServer('https://fakeServer.notExisting'); await client.checkHomeserver('https://fakeServer.notExisting');
final room = Room(id: '!localpart:server.abc', client: client); final room = Room(id: '!localpart:server.abc', client: client);
var event = Event.fromJson({ var event = Event.fromJson({
'type': EventTypes.Message, 'type': EventTypes.Message,
@ -1133,7 +1133,7 @@ void main() {
FILE_BUFF, FILE_BUFF,
}[url]; }[url];
}; };
await client.checkServer('https://fakeServer.notExisting'); await client.checkHomeserver('https://fakeServer.notExisting');
final room = Room(id: '!localpart:server.abc', client: await getClient()); final room = Room(id: '!localpart:server.abc', client: await getClient());
var event = Event.fromJson({ var event = Event.fromJson({
'type': EventTypes.Message, 'type': EventTypes.Message,

View File

@ -31,7 +31,7 @@ const pickledOlmAccount =
Future<Client> getClient() async { Future<Client> getClient() async {
final client = Client('testclient', httpClient: FakeMatrixApi()); final client = Client('testclient', httpClient: FakeMatrixApi());
client.database = getDatabase(); client.database = getDatabase();
await client.checkServer('https://fakeServer.notExisting'); await client.checkHomeserver('https://fakeServer.notExisting');
client.connect( client.connect(
newToken: 'abcd', newToken: 'abcd',
newUserID: '@test:fakeServer.notExisting', newUserID: '@test:fakeServer.notExisting',

View File

@ -27,7 +27,7 @@ void main() {
group('MxContent', () { group('MxContent', () {
test('Formatting', () async { test('Formatting', () async {
var client = Client('testclient', httpClient: FakeMatrixApi()); var client = Client('testclient', httpClient: FakeMatrixApi());
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
final mxc = 'mxc://exampleserver.abc/abcdefghijklmn'; final mxc = 'mxc://exampleserver.abc/abcdefghijklmn';
final content = Uri.parse(mxc); final content = Uri.parse(mxc);
expect(content.isScheme('mxc'), true); expect(content.isScheme('mxc'), true);

View File

@ -49,7 +49,7 @@ void main() {
}); });
test('Create', () async { test('Create', () async {
await client.checkServer('https://fakeServer.notExisting'); await client.checkHomeserver('https://fakeServer.notExisting');
client.onEvent.add(EventUpdate( client.onEvent.add(EventUpdate(
type: EventUpdateType.timeline, type: EventUpdateType.timeline,

View File

@ -85,28 +85,28 @@ void main() {
user3.calcDisplayname(mxidLocalPartFallback: false), 'Unknown user'); user3.calcDisplayname(mxidLocalPartFallback: false), 'Unknown user');
}); });
test('kick', () async { test('kick', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
await user1.kick(); await user1.kick();
}); });
test('ban', () async { test('ban', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
await user1.ban(); await user1.ban();
}); });
test('unban', () async { test('unban', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
await user1.unban(); await user1.unban();
}); });
test('setPower', () async { test('setPower', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
await user1.setPower(50); await user1.setPower(50);
}); });
test('startDirectChat', () async { test('startDirectChat', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
await client.login(user: 'test', password: '1234'); await client.login(user: 'test', password: '1234');
await user1.startDirectChat(); await user1.startDirectChat();
}); });
test('getPresence', () async { test('getPresence', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
await client.handleSync(SyncUpdate.fromJson({ await client.handleSync(SyncUpdate.fromJson({
'presence': { 'presence': {
'events': [ 'events': [
@ -121,15 +121,15 @@ void main() {
expect(user1.presence.presence.presence, PresenceType.online); expect(user1.presence.presence.presence, PresenceType.online);
}); });
test('canBan', () async { test('canBan', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
expect(user1.canBan, false); expect(user1.canBan, false);
}); });
test('canKick', () async { test('canKick', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
expect(user1.canKick, false); expect(user1.canKick, false);
}); });
test('canChangePowerLevel', () async { test('canChangePowerLevel', () async {
await client.checkServer('https://fakeserver.notexisting'); await client.checkHomeserver('https://fakeserver.notexisting');
expect(user1.canChangePowerLevel, false); expect(user1.canChangePowerLevel, false);
}); });
test('dispose client', () async { test('dispose client', () async {

View File

@ -24,7 +24,7 @@ void test() async {
Logs.success('++++ Login Alice at ++++'); Logs.success('++++ Login Alice at ++++');
testClientA = Client('TestClientA'); testClientA = Client('TestClientA');
testClientA.database = getDatabase(); testClientA.database = getDatabase();
await testClientA.checkServer(TestUser.homeserver); await testClientA.checkHomeserver(TestUser.homeserver);
await testClientA.login( await testClientA.login(
user: TestUser.username, password: TestUser.password); user: TestUser.username, password: TestUser.password);
assert(testClientA.encryptionEnabled); assert(testClientA.encryptionEnabled);
@ -32,7 +32,7 @@ void test() async {
Logs.success('++++ Login Bob ++++'); Logs.success('++++ Login Bob ++++');
testClientB = Client('TestClientB'); testClientB = Client('TestClientB');
testClientB.database = getDatabase(); testClientB.database = getDatabase();
await testClientB.checkServer(TestUser.homeserver); await testClientB.checkHomeserver(TestUser.homeserver);
await testClientB.login( await testClientB.login(
user: TestUser.username2, password: TestUser.password); user: TestUser.username2, password: TestUser.password);
assert(testClientB.encryptionEnabled); assert(testClientB.encryptionEnabled);
@ -222,7 +222,7 @@ void test() async {
Logs.success('++++ Login Bob in another client ++++'); Logs.success('++++ Login Bob in another client ++++');
var testClientC = Client('TestClientC', database: getDatabase()); var testClientC = Client('TestClientC', database: getDatabase());
await testClientC.checkServer(TestUser.homeserver); await testClientC.checkHomeserver(TestUser.homeserver);
await testClientC.login( await testClientC.login(
user: TestUser.username2, password: TestUser.password); user: TestUser.username2, password: TestUser.password);
await Future.delayed(Duration(seconds: 3)); await Future.delayed(Duration(seconds: 3));