diff --git a/docker-compose.yml b/docker-compose.yml index d1762c5e..17e8a7a1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,11 +3,11 @@ version: '3.4' services: db: - image: postgres:12-alpine + image: postgis/postgis:12-2.5 environment: - POSTGRES_HOST_AUTH_METHOD=trust volumes: - - ./docker-init-db.sql:/docker-entrypoint-initdb.d/init_db.sql + - ./docker/postgres.entrypoint-initdb.d:/docker-entrypoint-initdb.d:ro - db:/var/lib/postgresql/data command: postgres -c max_connections=300 -c log_min_messages=LOG @@ -108,6 +108,44 @@ services: depends_on: - web + openzaak: + image: openzaak/open-zaak:latest + environment: &app-env + - DJANGO_SETTINGS_MODULE=openzaak.conf.docker + - SECRET_KEY=${SECRET_KEY:-7(h1r2hk)8z9+05edulo_3qzymwbo&c24=)qz7+_@3&2sp=u%i} + - DB_NAME=openzaak + - DB_USER=openzaak + - IS_HTTPS=no + - ALLOWED_HOSTS=localhost,127.0.0.1,web,web.local,openzaak + - CORS_ALLOW_ALL_ORIGINS=True + - CSRF_TRUSTED_ORIGINS=http://localhost:9000 + - CACHE_DEFAULT=redis:6379/0 + - CACHE_AXES=redis:6379/0 + - SUBPATH=${SUBPATH:-/} + - IMPORT_DOCUMENTEN_BASE_DIR=${IMPORT_DOCUMENTEN_BASE_DIR:-/app/import-data} + - IMPORT_DOCUMENTEN_BATCH_SIZE=${IMPORT_DOCUMENTEN_BATCH_SIZE:-500} + - OPENZAAK_SUPERUSER_USERNAME=admin + - DJANGO_SUPERUSER_PASSWORD=admin + - OPENZAAK_SUPERUSER_EMAIL=admin@localhost + - CELERY_BROKER_URL=redis://redis:6379/1 + - CELERY_RESULT_BACKEND=redis://redis:6379/1 + - CELERY_LOGLEVEL=DEBUG + - CELERY_WORKER_CONCURRENCY=${CELERY_WORKER_CONCURRENCY:-4} + - ENVIRONMENT=dev + healthcheck: + test: ["CMD", "python", "-c", "import requests; exit(requests.head('http://localhost:8000/admin/').status_code not in [200, 302])"] + interval: 30s + timeout: 5s + retries: 3 + # This should allow for enough time for migrations to run before the max + # retries have passed. This healthcheck in turn allows other containers + # to wait for the database migrations. + start_period: 30s + depends_on: + - db + ports: + - 8001:8000 + volumes: media: db: diff --git a/docker-init-db.sql b/docker/postgres.entrypoint-initdb.d/0001-opennotificaties.sql similarity index 100% rename from docker-init-db.sql rename to docker/postgres.entrypoint-initdb.d/0001-opennotificaties.sql diff --git a/docker/postgres.entrypoint-initdb.d/0002-openzaak.sql b/docker/postgres.entrypoint-initdb.d/0002-openzaak.sql new file mode 100644 index 00000000..66f0c99f --- /dev/null +++ b/docker/postgres.entrypoint-initdb.d/0002-openzaak.sql @@ -0,0 +1,3 @@ +CREATE USER openzaak; +CREATE DATABASE openzaak; +GRANT ALL PRIVILEGES ON DATABASE openzaak TO openzaak; diff --git a/docker/postgres.entrypoint-initdb.d/0003-openzaak-extensions.sh b/docker/postgres.entrypoint-initdb.d/0003-openzaak-extensions.sh new file mode 100755 index 00000000..1adfaeec --- /dev/null +++ b/docker/postgres.entrypoint-initdb.d/0003-openzaak-extensions.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "openzaak" <<-EOSQL + CREATE EXTENSION postgis; + CREATE EXTENSION pg_trgm; +EOSQL diff --git a/docker/setup_configuration/data.yaml b/docker/setup_configuration/data.yaml index 2c732bd1..4210b2b0 100644 --- a/docker/setup_configuration/data.yaml +++ b/docker/setup_configuration/data.yaml @@ -3,16 +3,16 @@ zgw_consumers: services: - identifier: autorisaties-api label: Autorisaties API - api_root: http://localhost:8000/autorisaties/api/v1/ + api_root: http://openzaak:8000/autorisaties/api/v1/ api_type: ac auth_type: zgw client_id: open-notificaties secret: oPMsHCEuoP9Qh8vP06D7 user_id: open-notificaties - user_representation: Open Notificaties Demodam + user_representation: Open Notificaties - identifier: notificaties-api label: Notificaties API - api_root: http://localhost:8001/api/v1/ + api_root: http://web:8000/api/v1/ api_type: nrc auth_type: zgw client_id: open-notificaties diff --git a/docs/installation/configuration/opennotifs_config_cli.rst b/docs/installation/configuration/opennotifs_config_cli.rst index b04c93f6..e28de749 100644 --- a/docs/installation/configuration/opennotifs_config_cli.rst +++ b/docs/installation/configuration/opennotifs_config_cli.rst @@ -8,6 +8,10 @@ After deploying Open Notificaties, it needs to be configured to be fully functio command line tool ``setup_configuration`` assist with this configuration by loading a YAML file in which the configuration information is specified. +.. code-block:: bash + + src/manage.py setup_configuration --yaml-file /path/to/your/yaml + You can get the full command documentation with: .. code-block:: bash @@ -30,7 +34,36 @@ used by each step. Services configuration ---------------------- -TODO: add generated documentation for ``zgw_consumers.ServiceConfigurationStep`` +In order for Open Notificaties to make requests to external services (such as the Autorisaties API), +``Services`` must be configured. To enable this step, set ``zgw_consumers_config_enable`` to ``true`` in your +configuration file and specify a list of ``Services``, for example: + +.. code-block:: yaml + + zgw_consumers_config_enable: true + zgw_consumers: + services: + # all possible configurable fields + - identifier: objecten-test + label: Objecten API test + api_root: http://objecten.local/api/v1/ + api_connection_check_path: objects + api_type: orc + auth_type: api_key + header_key: Authorization + header_value: Token foo + client_id: client + secret: super-secret + nlx: http://some-outway-adress.local:8080/ + user_id: open-formulieren + user_representation: Open Formulieren + timeout: 5 + # minimum required fields + - identifier: objecttypen-test + label: Objecttypen API test + api_root: http://objecttypen.local/api/v1/ + api_type: orc + auth_type: api_key Client credentials ------------------ @@ -41,7 +74,20 @@ TODO: add generated documentation for ``JWTSecretsConfigurationStep`` Autorisaties API configuration ------------------------------ -TODO: add generated documentation +Open Notificaties uses Autorisaties API to check permissions of the clients that +make requests to Open Notificaties. + +This step configures Open Notificaties to use the specified Autorisaties API (see also :ref:`installation_configuration`). It is +dependent on the `Services configuration`_ step to load a ``Service`` for this Autorisaties API, +which is referred to in this step by ``authorizations_api_service_identifier``. +To enable this step, set ``autorisaties_api_config_enable`` to ``true`` in your +configuration file and specify which ``Service`` to use as the Autorisaties API, for example: + +.. code-block:: yaml + + autorisaties_api_config_enable: True + autorisaties_api: + authorizations_api_service_identifier: autorisaties-api .. _installation_configuration_cli_retry: @@ -66,9 +112,5 @@ With the full command invocation, all defined configuration steps are applied. E so it's safe to run the command multiple times. The steps will overwrite any manual changes made in the admin if you run the command after making these changes. -.. code-block:: bash - - src/manage.py setup_configuration - .. note:: Due to a cache-bug in the underlying framework, you need to restart all replicas for part of this change to take effect everywhere. diff --git a/src/nrc/setup_configuration/authorization.py b/src/nrc/setup_configuration/authorization.py index cea0d93b..43fbb0c1 100644 --- a/src/nrc/setup_configuration/authorization.py +++ b/src/nrc/setup_configuration/authorization.py @@ -1,6 +1,5 @@ -# SPDX-License-Identifier: EUPL-1.2 -# Copyright (C) 2022 Dimpact from django_setup_configuration.configuration import BaseConfigurationStep +from django_setup_configuration.exceptions import ConfigurationRunFailed from vng_api_common.authorizations.models import AuthorizationsConfig, ComponentTypes from zgw_consumers.models import Service @@ -15,18 +14,18 @@ def get_service(slug: str) -> Service: try: return Service.objects.get(slug=slug) except Service.DoesNotExist as e: - raise Service.DoesNotExist(f"{str(e)} (identifier = {slug})") + raise ConfigurationRunFailed(f"{str(e)} (identifier = {slug})") class AuthorizationStep(BaseConfigurationStep[AuthorizationsConfigModel]): """ - Open Notificaties uses Autorisaties API to check permissions of the clients. + Open Notificaties uses Autorisaties API to check permissions of the clients that + make requests to Open Notificaties. - 1. Set up authorization to point to the API - 2. Add credentials for Open Notifications to request Open Zaak - - Normal mode doesn't change the credentials after its initial creation. - If the client_id or secret is changed, run this command with 'overwrite' flag + This step configures Open Notificaties to use the specified Autorisaties API. It is + dependent on ``zgw_consumers.contrib.setup_configuration.steps.ServiceConfigurationStep`` + to load a ``Service`` for this Autorisaties API, which is referred to in this step by + ``authorizations_api_service_identifier``. """ verbose_name = "Configuration for Autorisaties API" diff --git a/src/nrc/tests/setup_configuration/test_authorization_configuration.py b/src/nrc/tests/setup_configuration/test_authorization_configuration.py index 95398147..60e7a6be 100644 --- a/src/nrc/tests/setup_configuration/test_authorization_configuration.py +++ b/src/nrc/tests/setup_configuration/test_authorization_configuration.py @@ -1,5 +1,6 @@ from django.test import TestCase +from django_setup_configuration.exceptions import ConfigurationRunFailed from django_setup_configuration.test_utils import execute_single_step from vng_api_common.authorizations.models import AuthorizationsConfig, ComponentTypes from zgw_consumers.test.factories import ServiceFactory @@ -58,3 +59,20 @@ def make_assertions(): execute_single_step(AuthorizationStep, yaml_source=CONFIG_FILE_PATH) make_assertions() + + def test_execute_configuration_service_does_not_exist(self): + self.service.delete() + config = AuthorizationsConfig.get_solo() + config.authorizations_api_service = None + config.save() + + with self.assertRaises(ConfigurationRunFailed) as exc: + execute_single_step(AuthorizationStep, yaml_source=CONFIG_FILE_PATH) + self.assertEqual( + str(exc.exception), + "Service matching query does not exist. (identifier = autorisaties-api)", + ) + + config = AuthorizationsConfig.get_solo() + + self.assertIsNone(config.authorizations_api_service)