From 1c3507bc117a4fef33401b0bc17d2f79f4d4bfde Mon Sep 17 00:00:00 2001 From: David Baker <dbkr@users.noreply.github.com> Date: Fri, 11 Feb 2022 17:03:22 +0000 Subject: [PATCH] Use the shared secret registration API directly (#7774) * Use the shared secret registration API directly rather than invoking the synapse module to do it. It's probably a bit simpler, if anything, and allows for synapse to be run in a separate container (or rather, avoids the javascript having to have a copy of synapse source & server config). * Make registration secret required Update commander (8 major versions!) to get requiredOption * Wrong options object :/ --- test/end-to-end-tests/package.json | 2 +- test/end-to-end-tests/run.sh | 3 +- test/end-to-end-tests/src/rest/creator.ts | 53 +++++++++-------------- test/end-to-end-tests/start.ts | 24 +++++----- test/end-to-end-tests/synapse/getcfg.sh | 17 ++++++++ test/end-to-end-tests/yarn.lock | 8 ++-- 6 files changed, 58 insertions(+), 49 deletions(-) create mode 100755 test/end-to-end-tests/synapse/getcfg.sh diff --git a/test/end-to-end-tests/package.json b/test/end-to-end-tests/package.json index 53df635ce1..08e2a36cac 100644 --- a/test/end-to-end-tests/package.json +++ b/test/end-to-end-tests/package.json @@ -11,7 +11,7 @@ "license": "ISC", "dependencies": { "cheerio": "^1.0.0-rc.2", - "commander": "^2.19.0", + "commander": "^9", "puppeteer": "10.0.0", "request": "^2.88.0", "request-promise-native": "^1.0.7", diff --git a/test/end-to-end-tests/run.sh b/test/end-to-end-tests/run.sh index 1a9009a886..b65ce2a956 100755 --- a/test/end-to-end-tests/run.sh +++ b/test/end-to-end-tests/run.sh @@ -32,9 +32,10 @@ handle_error() { trap 'handle_error' ERR ./synapse/start.sh +reg_secret=`./synapse/getcfg.sh registration_shared_secret` if [ $has_custom_app -ne "1" ]; then ./element/start.sh fi yarn build -node lib/start.js $@ +node lib/start.js --registration-shared-secret=$reg_secret $@ stop_servers diff --git a/test/end-to-end-tests/src/rest/creator.ts b/test/end-to-end-tests/src/rest/creator.ts index b88501e48d..33eea675d9 100644 --- a/test/end-to-end-tests/src/rest/creator.ts +++ b/test/end-to-end-tests/src/rest/creator.ts @@ -15,29 +15,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { exec } from 'child_process'; import request = require('request-promise-native'); +import * as crypto from 'crypto'; import { RestSession } from './session'; import { RestMultiSession } from './multi'; -interface ExecResult { - stdout: string; - stderr: string; -} - -function execAsync(command: string, options: Parameters<typeof exec>[1]): Promise<ExecResult> { - return new Promise((resolve, reject) => { - exec(command, options, (error, stdout, stderr) => { - if (error) { - reject(error); - } else { - resolve({ stdout, stderr }); - } - }); - }); -} - export interface Credentials { accessToken: string; homeServer: string; @@ -47,7 +30,7 @@ export interface Credentials { } export class RestSessionCreator { - constructor(private readonly synapseSubdir: string, private readonly hsUrl: string, private readonly cwd: string) {} + constructor(private readonly hsUrl: string, private readonly regSecret: string) {} public async createSessionRange(usernames: string[], password: string, groupName: string): Promise<RestMultiSession> { @@ -64,21 +47,25 @@ export class RestSessionCreator { } private async register(username: string, password: string): Promise<void> { - const registerArgs = [ - '-c homeserver.yaml', - `-u ${username}`, - `-p ${password}`, - '--no-admin', - this.hsUrl, - ]; - const registerCmd = `./register_new_matrix_user ${registerArgs.join(' ')}`; - const allCmds = [ - `cd ${this.synapseSubdir}`, - ". ./activate", - registerCmd, - ].join(' && '); + // get a nonce + const regUrl = `${this.hsUrl}/_synapse/admin/v1/register`; + const nonceResp = await request.get({ uri: regUrl, json: true }); - await execAsync(allCmds, { cwd: this.cwd, encoding: 'utf-8' }); + const mac = crypto.createHmac('sha1', this.regSecret).update( + `${nonceResp.nonce}\0${username}\0${password}\0notadmin`, + ).digest('hex'); + + await request.post({ + uri: regUrl, + json: true, + body: { + nonce: nonceResp.nonce, + username, + password, + mac, + admin: false, + }, + }); } private async authenticate(username: string, password: string): Promise<Credentials> { diff --git a/test/end-to-end-tests/start.ts b/test/end-to-end-tests/start.ts index 5e6b9b6066..f6c7400a15 100644 --- a/test/end-to-end-tests/start.ts +++ b/test/end-to-end-tests/start.ts @@ -15,12 +15,14 @@ limitations under the License. */ import * as fs from "fs"; -import program = require('commander'); +import { Command } from "commander"; import { ElementSession } from './src/session'; import { scenario } from './src/scenario'; import { RestSessionCreator } from './src/rest/creator'; +const program = new Command(); + program .option('--no-logs', "don't output logs, document html on error", false) .option('--app-url [url]', "url to test", "http://localhost:5000") @@ -30,6 +32,7 @@ program .option('--throttle-cpu [factor]', "factor to slow down the cpu with", parseFloat, 1.0) .option('--no-sandbox', "same as puppeteer arg", false) .option('--log-directory <dir>', 'a directory to dump html and network logs in when the tests fail') + .requiredOption('--registration-shared-secret <secret>', 'the secret to use for registering users') .parse(process.argv); const hsUrl = 'http://localhost:5005'; @@ -37,12 +40,12 @@ const hsUrl = 'http://localhost:5005'; async function runTests() { const sessions = []; const options = { - slowMo: program.slowMo ? 20 : undefined, - devtools: program.devTools, - headless: !program.windowed, + slowMo: program.opts().slowMo ? 20 : undefined, + devtools: program.opts().devTools, + headless: !program.opts().windowed, args: [], }; - if (!program.sandbox) { + if (!program.opts().sandbox) { options.args.push('--no-sandbox', '--disable-setuid-sandbox'); } if (process.env.CHROME_PATH) { @@ -52,13 +55,14 @@ async function runTests() { } const restCreator = new RestSessionCreator( - '../synapse/installations/consent/env/bin', hsUrl, - __dirname, + program.opts().registrationSharedSecret, ); async function createSession(username) { - const session = await ElementSession.create(username, options, program.appUrl, hsUrl, program.throttleCpu); + const session = await ElementSession.create( + username, options, program.opts().appUrl, hsUrl, program.opts().throttleCpu, + ); sessions.push(session); return session; } @@ -69,8 +73,8 @@ async function runTests() { } catch (err) { failure = true; console.log('failure: ', err); - if (program.logDirectory) { - await writeLogs(sessions, program.logDirectory); + if (program.opts().logDirectory) { + await writeLogs(sessions, program.opts().logDirectory); } } diff --git a/test/end-to-end-tests/synapse/getcfg.sh b/test/end-to-end-tests/synapse/getcfg.sh new file mode 100755 index 0000000000..e5e81586a4 --- /dev/null +++ b/test/end-to-end-tests/synapse/getcfg.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +if [ $# -eq 0 ] +then + echo "Prints a configuration directive from the synapse installation" + echo "Usage: getcfg.sh <synapse config file directive>" + exit 1 +fi + +# activate the virtualenv so we have pyyaml +BASE_DIR=$(cd $(dirname $0) && pwd) +cd $BASE_DIR +cd installations/consent/env/bin/ +source activate + +python -c "from yaml import load, Loader; import sys; print(load(sys.stdin, Loader=Loader)['$1'])" < homeserver.yaml diff --git a/test/end-to-end-tests/yarn.lock b/test/end-to-end-tests/yarn.lock index df8ee6c8b3..d03828fa79 100644 --- a/test/end-to-end-tests/yarn.lock +++ b/test/end-to-end-tests/yarn.lock @@ -146,10 +146,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" - integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== +commander@^9: + version "9.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.0.0.tgz#86d58f24ee98126568936bd1d3574e0308a99a40" + integrity sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw== concat-map@0.0.1: version "0.0.1"