Skip to content

Commit

Permalink
Fix for CSS7 including creating credentials via a script (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardsph authored Jan 9, 2024
1 parent c90f46d commit c16a731
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 16 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
120 changes: 120 additions & 0 deletions createCredentials.js
Original file line number Diff line number Diff line change
@@ -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: '[email protected]',
password: 'alice-secret',
podName: 'alice',
};

const bob = {
email: '[email protected]',
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);
33 changes: 17 additions & 16 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,22 @@ setup_css() {
mkdir -p config
cat > ./config/css-config.json <<EOF
{
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^5.0.0/components/context.jsonld",
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^7.0.0/components/context.jsonld",
"import": [
"css:config/app/init/static-root.json",
"css:config/app/main/default.json",
"css:config/app/init/initialize-prefilled-root.json",
"css:config/app/setup/optional.json",
"css:config/app/variables/default.json",
"css:config/http/handler/default.json",
"css:config/http/middleware/websockets.json",
"css:config/http/server-factory/https-websockets.json",
"css:config/http/middleware/default.json",
"css:config/http/notifications/all.json",
"css:config/http/server-factory/https.json",
"css:config/http/static/default.json",
"css:config/identity/access/public.json",
"css:config/identity/email/default.json",
"css:config/identity/handler/default.json",
"css:config/identity/oidc/default.json",
"css:config/identity/ownership/token.json",
"css:config/identity/pod/static.json",
"css:config/identity/registration/enabled.json",
"css:config/ldp/authentication/dpop-bearer.json",
"css:config/ldp/authorization/webacl.json",
"css:config/ldp/handler/default.json",
Expand All @@ -53,6 +53,7 @@ setup_css() {
"css:config/ldp/modes/default.json",
"css:config/storage/backend/memory.json",
"css:config/storage/key-value/resource-store.json",
"css:config/storage/location/pod.json",
"css:config/storage/middleware/default.json",
"css:config/util/auxiliary/acl.json",
"css:config/util/identifiers/suffix.json",
Expand All @@ -62,13 +63,6 @@ setup_css() {
"css:config/util/resource-locker/memory.json",
"css:config/util/variables/default.json"
],
"@graph": [
{
"comment": [
"Adds CLI options --httpsKey and --httpsCert and uses those to start an HTTPS server."
]
},
]
}
EOF

Expand All @@ -85,7 +79,7 @@ EOF
docker run -d --name=server --network=testnet --env NODE_TLS_REJECT_UNAUTHORIZED=0 \
-v "$(pwd)"/config:/config \
-v "$(pwd)"/certs:/certs \
-p 443:443 -it solidproject/community-server:5 \
-p 443:443 -it solidproject/community-server:7 \
-c /config/css-config.json \
--httpsKey=/certs/server.key --httpsCert=/certs/server.cert \
--port=443 --baseUrl=https://server/
Expand All @@ -96,6 +90,10 @@ EOF
sleep 1
done
echo 'CSS is running'

echo 'Creating client credentials'
cp css.env css-creds.env
NODE_TLS_REJECT_UNAUTHORIZED=0 node createCredentials.js https://server >> css-creds.env
}

stop_css() {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit c16a731

Please sign in to comment.