diff --git a/src/rest/creator.js b/src/rest/creator.js index 05976552d0..9090a21e70 100644 --- a/src/rest/creator.js +++ b/src/rest/creator.js @@ -18,6 +18,7 @@ const util = require('util'); const exec = util.promisify(require('child_process').exec); const request = require('request-promise-native'); const RestSession = require('./session'); +const RestMultiSession = require('./multi'); module.exports = class RestSessionCreator { constructor(synapseSubdir, hsUrl, cwd) { @@ -26,6 +27,12 @@ module.exports = class RestSessionCreator { this.cwd = cwd; } + async createSessionRange(usernames, password) { + const sessionPromises = usernames.map((username) => this.createSession(username, password)); + const sessions = await Promise.all(sessionPromises); + return new RestMultiSession(sessions); + } + async createSession(username, password) { await this._register(username, password); const authResult = await this._authenticate(username, password); diff --git a/src/rest/multi.js b/src/rest/multi.js new file mode 100644 index 0000000000..12ebe9d4ab --- /dev/null +++ b/src/rest/multi.js @@ -0,0 +1,61 @@ +/* +Copyright 2018 New Vector Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +const request = require('request-promise-native'); +const RestRoom = require('./room'); +const {approveConsent} = require('./consent'); + +module.exports = class RestMultiSession { + constructor(sessions) { + this.sessions = sessions; + } + + slice(start, end) { + return new RestMultiSession(this.sessions.slice(start, end)); + } + + pop(userName) { + const idx = this.sessions.findIndex((s) => s.userName() === userName); + if(idx === -1) { + throw new Error(`user ${userName} not found`); + } + const session = this.sessions.splice(idx, 1)[0]; + return session; + } + + async setDisplayName(fn) { + await Promise.all(this.sessions.map((s) => s.setDisplayName(fn(s)))); + } + + async join(roomId) { + const rooms = await Promise.all(this.sessions.map((s) => s.join(roomId))); + return new RestMultiRoom(rooms); + } +} + +class RestMultiRoom { + constructor(rooms) { + this.rooms = rooms; + } + + async talk(message) { + await Promise.all(this.rooms.map((r) => r.talk(message))); + } + + async leave() { + await Promise.all(this.rooms.map((r) => r.leave())); + } +} diff --git a/src/rest/room.js b/src/rest/room.js index b7da1789ff..d8de958a27 100644 --- a/src/rest/room.js +++ b/src/rest/room.js @@ -20,12 +20,12 @@ const uuidv4 = require('uuid/v4'); module.exports = class RestRoom { constructor(session, roomId) { this.session = session; - this.roomId = roomId; + this._roomId = roomId; } async talk(message) { const txId = uuidv4(); - await this.session._put(`/rooms/${this.roomId}/send/m.room.message/${txId}`, { + await this.session._put(`/rooms/${this._roomId}/send/m.room.message/${txId}`, { "msgtype": "m.text", "body": message }); @@ -33,10 +33,10 @@ module.exports = class RestRoom { } async leave() { - await this.session._post(`/rooms/${this.roomId}/leave`); + await this.session._post(`/rooms/${this._roomId}/leave`); } - id() { - return this.roomId; + roomId() { + return this._roomId; } } diff --git a/src/rest/session.js b/src/rest/session.js index caa10a430b..44be15c3ff 100644 --- a/src/rest/session.js +++ b/src/rest/session.js @@ -23,38 +23,12 @@ module.exports = class RestSession { this.credentials = credentials; } - _post(csApiPath, body) { - return this._request("POST", csApiPath, body); + userId() { + return this.credentials.userId; } - _put(csApiPath, body) { - return this._request("PUT", csApiPath, body); - } - - async _request(method, csApiPath, body) { - try { - const responseBody = await request({ - url: `${this.credentials.hsUrl}/_matrix/client/r0${csApiPath}`, - method, - headers: { - "Authorization": `Bearer ${this.credentials.accessToken}` - }, - json: true, - body - }); - return responseBody; - - } catch(err) { - const responseBody = err.response.body; - if (responseBody.errcode === 'M_CONSENT_NOT_GIVEN') { - await approveConsent(responseBody.consent_uri); - return this._request(method, csApiPath, body); - } else if(responseBody && responseBody.error) { - throw new Error(`${method} ${csApiPath}: ${responseBody.error}`); - } else { - throw new Error(`${method} ${csApiPath}: ${err.response.statusCode}`); - } - } + userName() { + return this.credentials.userId.split(":")[0].substr(1); } async setDisplayName(displayName) { @@ -90,4 +64,38 @@ module.exports = class RestSession { const {room_id} = await this._post(`/createRoom`, body); return new RestRoom(this, room_id); } + + _post(csApiPath, body) { + return this._request("POST", csApiPath, body); + } + + _put(csApiPath, body) { + return this._request("PUT", csApiPath, body); + } + + async _request(method, csApiPath, body) { + try { + const responseBody = await request({ + url: `${this.credentials.hsUrl}/_matrix/client/r0${csApiPath}`, + method, + headers: { + "Authorization": `Bearer ${this.credentials.accessToken}` + }, + json: true, + body + }); + return responseBody; + + } catch(err) { + const responseBody = err.response.body; + if (responseBody.errcode === 'M_CONSENT_NOT_GIVEN') { + await approveConsent(responseBody.consent_uri); + return this._request(method, csApiPath, body); + } else if(responseBody && responseBody.error) { + throw new Error(`${method} ${csApiPath}: ${responseBody.error}`); + } else { + throw new Error(`${method} ${csApiPath}: ${err.response.statusCode}`); + } + } + } }