This commit adds two path operations, *GET /login* and *GET /oidc-callback*, which initiate and complete the OpenID connect login flow, respectively. Only the *Authorization Code* flow is supported, since this is the only flow implemented by Authelia. There is quite a bit of boilerplate required to fully implement an OIDC relying party, especially in Rust. The documentation for `openidconnect` is decent, but it still took quite a bit of trial and error to get everything working. After successfully finishing the OIDC login, the client will receive a cookie containing a JWT that can be used for further communication with the server. We're not using the OIDC tokens themselves for authorization. For development and testing, Dex is a simple and convenient OIDC IdP. The only caveat is its configuration file must contain list the TCP port clients will use to connect to it, meaning we cannot use Podman dynamic port allocation like we do for Meilisearch. Ultimately, this just means the integration tests will fail if there is another process already listening on 5556.
94 lines
2.4 KiB
Bash
Executable File
94 lines
2.4 KiB
Bash
Executable File
#!/bin/sh
|
|
# vim: set ts=4 sts=4 sw=4 et :
|
|
|
|
cleanup() {
|
|
if [ -n "${cid}" ]; then
|
|
echo 'Stopping Meilisearch ...' >&2
|
|
podman stop "${cid}" >/dev/null
|
|
fi
|
|
unset cid
|
|
if [ -f "${meilisearch_key}" ]; then
|
|
rm "${meilisearch_key}"
|
|
fi
|
|
unset meilisearch_key
|
|
if [ -n "${dex_cid}" ]; then
|
|
echo 'Stopping Dex ...' >&2
|
|
podman stop "${dex_cid}" >/dev/null
|
|
fi
|
|
unset cid
|
|
if [ -f "${jwt_key}" ]; then
|
|
rm "${jwt_key}"
|
|
fi
|
|
unset jwt_key
|
|
if [ -f "${ROCKET_CONFIG}" ]; then
|
|
rm "${ROCKET_CONFIG}"
|
|
fi
|
|
unset ROCKET_CONFIG
|
|
}
|
|
|
|
trap cleanup INT TERM QUIT EXIT
|
|
|
|
echo 'Generating Meilisearch master key ...' >&2
|
|
MEILI_MASTER_KEY=$(tr -cd 0-9A-Za-z_- < /dev/urandom | head -c 32)
|
|
|
|
echo 'Starting Meilisearch ...' >&2
|
|
cid=$(
|
|
export MEILI_MASTER_KEY
|
|
podman run --rm -d -P \
|
|
-e MEILI_NO_ANALYTICS=true \
|
|
-e MEILI_MASTER_KEY \
|
|
docker.io/getmeili/meilisearch:v1.13
|
|
)
|
|
|
|
port=$(podman port ${cid} 7700/tcp | cut -d: -f2)
|
|
printf 'Waiting for Meilisearch on port %d ...' "${port}" >&2
|
|
until curl -fs -o /dev/null 127.0.0.1:${port}; do
|
|
printf '.'
|
|
sleep 0.25
|
|
done
|
|
echo ' ready' >&2
|
|
|
|
meilisearch_key=$(mktemp meilisearch.token.XXXXXX)
|
|
curl -s 127.0.0.1:${port}/keys -H "Authorization: Bearer ${MEILI_MASTER_KEY}" \
|
|
| jq -r '.results[] | select(.name == "Default Admin API Key") | .key' \
|
|
> "${meilisearch_key}"
|
|
|
|
echo 'Starting Dex ...'
|
|
dex_cid=$(
|
|
podman run --rm -d \
|
|
-p 5556:5556 \
|
|
-v ./dex.yaml:/etc/dex/config.yaml:ro,z \
|
|
ghcr.io/dexidp/dex \
|
|
dex serve /etc/dex/config.yaml
|
|
) || exit
|
|
dex_port=5556
|
|
printf 'Waiting for Dex on port %d ...' "${dex_port}" >&2
|
|
until curl -fs -o /dev/null 127.0.0.1:${dex_port}/dex/healthz; do
|
|
printf '.'
|
|
sleep 0.25
|
|
done
|
|
echo ' ready' >&2
|
|
|
|
echo 'Generating JWT secret key ...' >&2
|
|
jwt_key=$(mktemp jwt.secret.XXXXXX)
|
|
tr -cd 0-9A-Za-z_- < /dev/urandom | head -c 32 > "${jwt_key}"
|
|
|
|
ROCKET_CONFIG=$(mktemp Rocket.toml.XXXXXX)
|
|
cat > "${ROCKET_CONFIG}" <<EOF
|
|
[test.meilisearch]
|
|
url = "http://127.0.0.1:${port}"
|
|
token = "${meilisearch_key}"
|
|
|
|
[test.auth]
|
|
jwt_secret = "${jwt_key}"
|
|
|
|
[test.oidc]
|
|
discovery_url = "http://127.0.0.1:${dex_port}/dex"
|
|
client_id = "example-app"
|
|
client_secret = "example-app-secret"
|
|
callback_url = "http://localhost:8000/oidc-callback"
|
|
EOF
|
|
export ROCKET_PROFILE=test
|
|
export ROCKET_CONFIG
|
|
cargo test "$@"
|