diff --git a/README.md b/README.md index 65aadaf..59f1c57 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,12 @@ Use the script with the `-d` option to use the local tests: ```shell ./run.sh -d . css ``` + +## Tips for CSS +For testing CSS, the run script has the ability to register test accounts on a fresh server installation. It depends on +node 18+ being available. It calls `clientCredentials.js` to add the required client ids and secrets to a temporary env +file. + ## Creating a script for a CI workflow If you just want to run tests against a single test subject, for example in a CI workflow, you can create a script such as this one which will run the tests embedded in the latest published CTH image: diff --git a/createCredentials.js b/createCredentials.js new file mode 100644 index 0000000..e247215 --- /dev/null +++ b/createCredentials.js @@ -0,0 +1,120 @@ +// This script is derived from a script created for CSS: +// https://github.com/CommunitySolidServer/CommunitySolidServer/blob/main/test/deploy/createAccountCredentials.ts + +if (process.argv.length !== 3) { + throw new Error('Exactly 1 parameter is needed: the server URL.'); +} + +const baseUrl = process.argv[2]; + +const alice = { + email: 'alice@example.com', + password: 'alice-secret', + podName: 'alice', +}; + +const bob = { + email: 'bob@example.com', + password: 'bob-secret', + podName: 'bob', +}; + +/** + * Registers a user with the server and provides them with a pod. + * @param user - The user settings necessary to register a user. + */ +async function register(user) { + // Get controls + let res = await fetch(new URL('.account/', baseUrl)); + let { controls } = await res.json(); + + // Create account + res = await fetch(controls.account.create, { method: 'POST' }); + if (res.status !== 200) { + throw new Error(`Account creation failed: ${await res.text()}`); + } + const authorization = `CSS-Account-Token ${(await res.json()).authorization}`; + + // Get account controls + res = await fetch(controls.main.index, { + headers: { authorization }, + }); + ({ controls } = await res.json()); + + // Add login method + res = await fetch(controls.password.create, { + method: 'POST', + headers: { authorization, 'content-type': 'application/json' }, + body: JSON.stringify({ + email: user.email, + password: user.password, + }), + }); + if (res.status !== 200) { + throw new Error(`Login creation failed: ${await res.text()}`); + } + + // Create pod + res = await fetch(controls.account.pod, { + method: 'POST', + headers: { authorization, 'content-type': 'application/json' }, + body: JSON.stringify({ name: user.podName }), + }); + if (res.status !== 200) { + throw new Error(`Pod creation failed: ${await res.text()}`); + } + const { webId } = await res.json(); + + return { webId, authorization }; +} + +/** + * Requests a client credentials API token. + * @param webId - WebID to create credentials for. + * @param authorization - Authorization header for the account that tries to create credentials. + * @returns The id/secret for the client credentials request. + */ +async function createCredentials(webId, authorization) { + let res = await fetch(new URL('.account/', baseUrl), { + headers: { authorization }, + }); + const { controls } = await res.json(); + + res = await fetch(controls.account.clientCredentials, { + method: 'POST', + headers: { authorization, 'content-type': 'application/json' }, + body: JSON.stringify({ name: 'token', webId }), + }); + if (res.status !== 200) { + throw new Error(`Token generation failed: ${await res.text()}`); + } + + return res.json(); +} + +/** + * Generates all the necessary data and outputs the necessary lines + * that need to be added to the CTH environment file + * so it can use client credentials. + * @param user - User for which data needs to be generated. + */ +async function outputCredentials(user) { + const { webId, authorization } = await register(user); + const { id, secret } = await createCredentials(webId, authorization); + + const name = user.podName.toUpperCase(); + console.log(`USERS_${name}_CLIENTID=${id}`); + console.log(`USERS_${name}_CLIENTSECRET=${secret}`); +} + +/** + * Ends the process and writes out an error in case something goes wrong. + */ +function endProcess(error) { + console.error(error); + process.exit(1); +} + +// Create tokens for Alice and Bob +outputCredentials(alice).catch(endProcess); +outputCredentials(bob).catch(endProcess); diff --git a/run.sh b/run.sh index 3e6b988..f79a4c0 100755 --- a/run.sh +++ b/run.sh @@ -29,22 +29,22 @@ setup_css() { mkdir -p config cat > ./config/css-config.json <> css-creds.env } stop_css() { @@ -171,7 +169,7 @@ shift echo "Running tests on $subject and reporting to $cwd/reports/$subject" -dockerargs+=('-v' "$cwd/reports/$outdir:/reports" "--env-file=$envfile") +dockerargs+=('-v' "$cwd/reports/$outdir:/reports") if ! [[ "$*" == *"--target="* ]]; then harnessargs+=("--target=https://github.com/solid/conformance-test-harness/$subject") fi @@ -183,7 +181,10 @@ mkdir -p reports/$subject if [ $subject == "css" ] then setup_css - dockerargs+=('--network=testnet') + dockerargs+=('--env-file=css-creds.env' '--network=testnet') + harnessargs+=('--skip-teardown') +else + dockerargs+=('--env-file=$envfile') fi # optionally pull published CTH image