Merge branch 'client-enhance-add-register-methods' into 'master'

[Client] Add register methods

See merge request famedly/famedlysdk!159
This commit is contained in:
Christian Pauly 2020-01-14 15:16:24 +00:00
commit f5eed1159e
4 changed files with 109 additions and 30 deletions

View file

@ -234,39 +234,99 @@ class Client {
} }
} }
/// Checks to see if a username is available, and valid, for the server.
/// You have to call [checkServer] first to set a homeserver.
Future<bool> usernameAvailable(String username) async {
final Map<String, dynamic> response = await this.jsonRequest(
type: HTTPType.GET,
action: "/client/r0/register/available?username=$username",
);
return response["available"];
}
/// 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.
/// You have to call [checkServer] first to set a homeserver.
Future<Map<String, dynamic>> register({
String kind,
String username,
String password,
Map<String, dynamic> auth,
String deviceId,
String initialDeviceDisplayName,
bool inhibitLogin,
}) async {
final String action =
"/client/r0/register" + (kind != null ? "?kind=$kind" : "");
Map<String, dynamic> data = {};
if (username != null) data["username"] = username;
if (password != null) data["password"] = password;
if (auth != null) data["auth"] = auth;
if (deviceId != null) data["device_id"] = deviceId;
if (initialDeviceDisplayName != null) {
data["initial_device_display_name"] = initialDeviceDisplayName;
}
if (inhibitLogin != null) data["inhibit_login"] = inhibitLogin;
final Map<String, dynamic> response =
await this.jsonRequest(type: HTTPType.POST, action: action, data: data);
// Connect if there is an access token in the response.
if (response.containsKey("access_token") &&
response.containsKey("device_id") &&
response.containsKey("user_id")) {
await this.connect(
newToken: response["access_token"],
newUserID: response["user_id"],
newHomeserver: homeserver,
newDeviceName: initialDeviceDisplayName ?? "",
newDeviceID: response["device_id"],
newMatrixVersions: matrixVersions,
newLazyLoadMembers: lazyLoadMembers);
}
return response;
}
/// 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.
Future<bool> login(String username, String password) async { /// You have to call [checkServer] first to set a homeserver.
final loginResp = await jsonRequest( Future<bool> login(
type: HTTPType.POST, String username,
action: "/client/r0/login", String password, {
data: { String initialDeviceDisplayName,
"type": "m.login.password", String deviceId,
"user": username, }) async {
"identifier": { Map<String, dynamic> data = {
"type": "m.id.user", "type": "m.login.password",
"user": username, "user": username,
}, "identifier": {
"password": password, "type": "m.id.user",
"initial_device_display_name": "Famedly Talk" "user": username,
}); },
"password": password,
final userID = loginResp["user_id"]; };
final accessToken = loginResp["access_token"]; if (deviceId != null) data["device_id"] = deviceId;
if (userID == null || accessToken == null) { if (initialDeviceDisplayName != null) {
return false; data["initial_device_display_name"] = initialDeviceDisplayName;
} }
await this.connect( final loginResp = await jsonRequest(
newToken: accessToken, type: HTTPType.POST, action: "/client/r0/login", data: data);
newUserID: userID,
newHomeserver: homeserver, if (loginResp.containsKey("user_id") &&
newDeviceName: "", loginResp.containsKey("access_token") &&
newDeviceID: "", loginResp.containsKey("device_id")) {
newMatrixVersions: matrixVersions, await this.connect(
newLazyLoadMembers: lazyLoadMembers); newToken: loginResp["access_token"],
return true; newUserID: loginResp["user_id"],
newHomeserver: homeserver,
newDeviceName: initialDeviceDisplayName ?? "",
newDeviceID: loginResp["device_id"],
newMatrixVersions: matrixVersions,
newLazyLoadMembers: lazyLoadMembers);
return true;
}
return false;
} }
/// Sends a logout command to the homeserver and clears all local data, /// Sends a logout command to the homeserver and clears all local data,

View file

@ -87,8 +87,8 @@ class MatrixException implements Exception {
if (!raw.containsKey("flows") || !(raw["flows"] is List)) return null; if (!raw.containsKey("flows") || !(raw["flows"] is List)) return null;
List<AuthenticationFlow> flows = []; List<AuthenticationFlow> flows = [];
for (Map<String, dynamic> flow in raw["flows"]) { for (Map<String, dynamic> flow in raw["flows"]) {
if (flow["stages"] is List<String>) { if (flow["stages"] is List) {
flows.add(AuthenticationFlow(flow["stages"])); flows.add(AuthenticationFlow(List<String>.from(flow["stages"])));
} }
} }
return flows; return flows;

View file

@ -88,6 +88,18 @@ void main() {
"initial_device_display_name": "Fluffy Matrix Client" "initial_device_display_name": "Fluffy Matrix Client"
}); });
final bool available = await matrix.usernameAvailable("testuser");
expect(available, true);
Map registerResponse = await matrix.register(username: "testuser");
expect(registerResponse["user_id"], "@testuser:example.com");
registerResponse =
await matrix.register(username: "testuser", kind: "user");
expect(registerResponse["user_id"], "@testuser:example.com");
registerResponse =
await matrix.register(username: "testuser", kind: "guest");
expect(registerResponse["user_id"], "@testuser:example.com");
Future<LoginState> loginStateFuture = Future<LoginState> loginStateFuture =
matrix.onLoginStateChanged.stream.first; matrix.onLoginStateChanged.stream.first;
Future<bool> firstSyncFuture = matrix.onFirstSync.stream.first; Future<bool> firstSyncFuture = matrix.onFirstSync.stream.first;

View file

@ -756,8 +756,15 @@ class FakeMatrixApi extends MockClient {
(var req) => archiveSyncResponse, (var req) => archiveSyncResponse,
"/client/r0/sync?filter=%7B%22room%22:%7B%22state%22:%7B%22lazy_load_members%22:true%7D%7D%7D": "/client/r0/sync?filter=%7B%22room%22:%7B%22state%22:%7B%22lazy_load_members%22:true%7D%7D%7D":
(var req) => syncResponse, (var req) => syncResponse,
"/client/r0/register/available?username=testuser": (var req) =>
{"available": true},
}, },
"POST": { "POST": {
"/client/r0/register": (var req) => {"user_id": "@testuser:example.com"},
"/client/r0/register?kind=user": (var req) =>
{"user_id": "@testuser:example.com"},
"/client/r0/register?kind=guest": (var req) =>
{"user_id": "@testuser:example.com"},
"/client/r0/user/@test:fakeServer.notExisting/openid/request_token": "/client/r0/user/@test:fakeServer.notExisting/openid/request_token":
(var req) => { (var req) => {
"access_token": "SomeT0kenHere", "access_token": "SomeT0kenHere",