diff --git a/.gitignore b/.gitignore index 070d4317..fa553e2e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ bandit.txt coverage.* coverage docker-compose.yml +!docs/_examples/*/docker-compose.yml docker-compose.override.yml reports results.* diff --git a/docs/_examples/network/README.md b/docs/_examples/network/README.md new file mode 100644 index 00000000..fb382ebd --- /dev/null +++ b/docs/_examples/network/README.md @@ -0,0 +1 @@ +See the documentation in this repository at docs/examples.rst in the Network example section diff --git a/docs/_examples/network/docker-compose.yml b/docs/_examples/network/docker-compose.yml new file mode 100644 index 00000000..83a0c2bb --- /dev/null +++ b/docs/_examples/network/docker-compose.yml @@ -0,0 +1,119 @@ +x-host-extras: &extra-hosts + extra_hosts: + - "host.docker.internal:host-gateway" + +x-magpie: &magpie + <<: *extra-hosts + image: pavics/magpie:latest + entrypoint: /magpie-entrypoint.sh + volumes: + - ./magpie-entrypoint.sh:/magpie-entrypoint.sh + healthcheck: + test: ["CMD", "wget", "-qO-", "http://0.0.0.0:2001"] + interval: 60s + timeout: 5s + retries: 3 + start_period: 30s + start_interval: 5s + +x-magpie-admin-credentials-env: &magpie-admin-credentials + MAGPIE_ADMIN_USER: admin + MAGPIE_ADMIN_PASSWORD: qwertyqwerty! + +x-magpie-env: &magpie-env + <<: *magpie-admin-credentials + HOSTNAME: localhost + FORWARDED_ALLOW_IPS: "*" + MAGPIE_SECRET: itzaseekrit + MAGPIE_ADMIN_GROUP: administrators + MAGPIE_USER_GROUP: users + MAGPIE_ANONYMOUS_USER: anonymous + MAGPIE_PORT: 2001 + MAGPIE_LOG_LEVEL: DEBUG + TWITCHER_PROTECTED_PATH: /twitcher/ows/proxy + MAGPIE_POSTGRES_USERNAME: magpie + MAGPIE_POSTGRES_PASSWORD: qwerty + MAGPIE_POSTGRES_DB: magpie + MAGPIE_POSTGRES_PORT: 5432 + MAGPIE_NETWORK_ENABLED: True + MAGPIE_NETWORK_CREATE_MISSING_PEM_FILE: True + +x-postgres: &postgres + <<: *extra-hosts + image: postgres:latest + environment: + POSTGRES_PASSWORD: qwerty + POSTGRES_DB: magpie + POSTGRES_USER: magpie + POSTGRES_PORT : 5432 + + +services: + magpie1: + <<: *magpie + depends_on: + - postgres1 + environment: + <<: *magpie-env + MAGPIE_POSTGRES_HOST: postgres1 + MAGPIE_PREFIX: /magpie1 + MAGPIE_URL: http://host.docker.internal/magpie1/ + MAGPIE_NETWORK_INSTANCE_NAME: magpie1 + postgres1: + <<: *postgres + magpie2: + <<: *magpie + depends_on: + - postgres2 + environment: + <<: *magpie-env + MAGPIE_POSTGRES_HOST: postgres2 + MAGPIE_PREFIX: /magpie2 + MAGPIE_URL: http://host.docker.internal/magpie2/ + MAGPIE_NETWORK_INSTANCE_NAME: magpie2 + postgres2: + <<: *postgres + magpie3: + <<: *magpie + depends_on: + - postgres3 + environment: + <<: *magpie-env + MAGPIE_POSTGRES_HOST: postgres3 + MAGPIE_PREFIX: /magpie3 + MAGPIE_URL: http://host.docker.internal/magpie3/ + MAGPIE_NETWORK_INSTANCE_NAME: magpie3 + postgres3: + <<: *postgres + nginx: + <<: *extra-hosts + image: nginx:1.23.4 + depends_on: + magpie1: + condition: service_healthy + magpie2: + condition: service_healthy + magpie3: + condition: service_healthy + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + healthcheck: + test: ["CMD", "curl", "--fail", "http://0.0.0.0/magpie1/"] + interval: 60s + timeout: 5s + retries: 3 + start_period: 30s + start_interval: 5s + ports: + - 80:80 + initializer: + <<: *extra-hosts + image: alpine/curl:latest + depends_on: + nginx: + condition: service_healthy + volumes: + - ./init.sh:/init.sh + environment: + <<: *magpie-admin-credentials + command: ["/init.sh"] diff --git a/docs/_examples/network/init.sh b/docs/_examples/network/init.sh new file mode 100755 index 00000000..4dddb28f --- /dev/null +++ b/docs/_examples/network/init.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env sh + +HOSTS="magpie1 magpie2 magpie3" + +for magpie in $HOSTS; do + cookiejar=/tmp/"${magpie}".cookiejar + curl \ + --cookie-jar "${cookiejar}" \ + -X POST "http://host.docker.internal/${magpie}/signin" \ + -H "Content-Type: application/json" \ + -d '{"user_name": "'${MAGPIE_ADMIN_USER}'", "password": "'${MAGPIE_ADMIN_PASSWORD}'"}' + for user in test1 test2 test3; do + curl \ + --cookie "${cookiejar}" \ + -X POST "http://host.docker.internal/${magpie}/users" \ + -d user_name="${user}" \ + -d email="${user}@example.com" \ + -d password='qwertyqwerty!' \ + -d group_name="users" + done + for other in $HOSTS; do + [ "$magpie" = "$other" ] && continue + curl \ + --cookie "${cookiejar}" \ + -X POST "http://host.docker.internal/${magpie}/network/nodes" \ + -d base_url="http://host.docker.internal/${other}/" \ + -d name="${other}" \ + -d jwks_url="http://host.docker.internal/${other}/network/jwks" \ + -d token_url="http://host.docker.internal/${other}/network/token" \ + -d authorization_url="http://host.docker.internal/${other}/ui/network/authorize" \ + -d redirect_uris="[\"http://host.docker.internal/${other}/network/link\"]" + done +done diff --git a/docs/_examples/network/magpie-entrypoint.sh b/docs/_examples/network/magpie-entrypoint.sh new file mode 100755 index 00000000..10f3544e --- /dev/null +++ b/docs/_examples/network/magpie-entrypoint.sh @@ -0,0 +1,5 @@ +#! /usr/bin/env bash + +sed -i "s:^prefix = /magpie:prefix = ${MAGPIE_PREFIX}:" config/magpie.ini + +exec pserve config/magpie.ini diff --git a/docs/_examples/network/nginx.conf b/docs/_examples/network/nginx.conf new file mode 100644 index 00000000..4831833d --- /dev/null +++ b/docs/_examples/network/nginx.conf @@ -0,0 +1,32 @@ + +user root; + +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile off; + keepalive_timeout 65; + server { + listen 80; + server_name localhost; + + location /magpie1/ { + proxy_pass http://magpie1:2001/; + proxy_set_header Host $host; + } + location /magpie2/ { + proxy_pass http://magpie2:2001/; + proxy_set_header Host $host; + } + location /magpie3/ { + proxy_pass http://magpie3:2001/; + proxy_set_header Host $host; + } + } +} diff --git a/docs/conf.py b/docs/conf.py index d87a3563..660d9026 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -217,6 +217,7 @@ def ignore_down_providers(): "https://wso2.com/", # sporadic broken (probably robots or similar) "https://docs.wso2.com/*", "https://pcmdi.llnl.gov/", # works, but very often causes false-positive 'broken' links + "http://host.docker.internal/*", # for examples that refer to magpie on the host machine ] + ignore_down_providers() linkcheck_anchors_ignore = [ r".*issuecomment.*", # GitHub issue comment anchors not resolved diff --git a/docs/examples.rst b/docs/examples.rst new file mode 100644 index 00000000..e4f1906e --- /dev/null +++ b/docs/examples.rst @@ -0,0 +1,89 @@ +.. _examples: + +Examples +======== + +This section contains example configurations for `Magpie` that further illustrate how the software can be used. + +.. _examples_network: + +Network +------- + +This example contains a ``docker compose`` configuration to create 3 local `Magpie` deployments, all of which are +networked together using the Magpie :ref:`network_mode` feature. + +.. seealso:: + :reF:`Example Network Files ` + +.. _examples_network_setup: + +Setup +~~~~~ + +Start by copying the files below into a directory and then running: + +.. code-block:: shell + + docker compose up -d + + +Once the stack has started then 3 `Magpie` instance will be available on the host machine at: + +* http://host.docker.internal/magpie1 +* http://host.docker.internal/magpie2 +* http://host.docker.internal/magpie3 + +Note that this will run on port 80 on the host machine so we recommend not running this on a machine that exposes port +80 to your network. + +Each instance is created with 3 users (``test1``, ``test2``, ``test3``) +and an *administrator* user with the username ``admin``. All users have the same password: ``qwertyqwerty!``. + +You can log in to any of the three `Magpie` instances as any of those users and explore the :ref:`network_mode` +feature. + +.. _examples_network_usage: + +Usage +~~~~~ + +Once the example instances are running with Network mode, you can do any of the following operations. + +* Link two users in the network: + + 1. log in to the ``magpie1`` instance as ``test1`` + 2. go to http://host.docker.internal/magpie1/ui/users/current + 3. click the "*Create*" button beside ``magpie2`` in the "*Network Account Links*" table + 4. sign in to ``magpie2`` as a different user and accept the authorization + +* Request a token for another instance: + + 1. log in to the ``magpie1`` instance as ``test1`` + 2. request a token for ``magpie2`` by going to http://host.docker.internal/magpie1/network/nodes/magpie2/token + +.. _examples_network_files: + +Files +~~~~~ +Download all files below into the same directory in order to run this example. + +docker-compose.yml +^^^^^^^^^^^^^^^^^^ +.. literalinclude:: _examples/network/docker-compose.yml + :language: yaml + +init.sh +^^^^^^^ +.. literalinclude:: _examples/network/init.sh + :language: shell + +nginx.conf +^^^^^^^^^^ +.. literalinclude:: _examples/network/nginx.conf + :language: nginx + +magpie-entrypoint.sh +^^^^^^^^^^^^^^^^^^^^ +.. literalinclude:: _examples/network/magpie-entrypoint.sh + :language: shell diff --git a/docs/toc.rst b/docs/toc.rst index aa615d4a..f6f918fe 100644 --- a/docs/toc.rst +++ b/docs/toc.rst @@ -23,4 +23,5 @@ changes security glossary + examples references_page