diff --git a/src/objecttypes/conf/base.py b/src/objecttypes/conf/base.py index 2955e61b..46498f11 100644 --- a/src/objecttypes/conf/base.py +++ b/src/objecttypes/conf/base.py @@ -425,3 +425,29 @@ if config("DISABLE_2FA", default=False): # pragma: no cover MAYKIN_2FA_ALLOW_MFA_BYPASS_BACKENDS = AUTHENTICATION_BACKENDS + +# +# Django setup configuration +# +SETUP_CONFIGURATION_STEPS = [ + "objecttypes.config.site.SiteConfigurationStep", + "objecttypes.config.objects.ObjectsAuthStep", +] + + +# +# Objecttypes settings +# + +# setup_configuration command +# sites config +SITES_CONFIG_ENABLE = config("SITES_CONFIG_ENABLE", default=True) +OBJECTTYPES_DOMAIN = config("OBJECTTYPES_DOMAIN", "") +OBJECTTYPES_ORGANIZATION = config("OBJECTTYPES_ORGANIZATION", "") +# objects auth config +OBJECTS_OBJECTTYPES_CONFIG_ENABLE = config( + "OBJECTS_OBJECTTYPES_CONFIG_ENABLE", default=True +) +OBJECTS_OBJECTTYPES_TOKEN = config("OBJECTS_OBJECTTYPES_TOKEN", "") +OBJECTS_OBJECTTYPES_PERSON = config("OBJECTS_OBJECTTYPES_PERSON", "") +OBJECTS_OBJECTTYPES_EMAIL = config("OBJECTS_OBJECTTYPES_EMAIL", "") diff --git a/src/objecttypes/config/__init__.py b/src/objecttypes/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/objecttypes/config/objects.py b/src/objecttypes/config/objects.py new file mode 100644 index 00000000..6c9688bd --- /dev/null +++ b/src/objecttypes/config/objects.py @@ -0,0 +1,65 @@ +from django.conf import settings +from django.urls import reverse + +import requests +from django_setup_configuration.configuration import BaseConfigurationStep +from django_setup_configuration.exceptions import SelfTestFailed + +from objecttypes.token.models import TokenAuth +from objecttypes.utils import build_absolute_url + + +class ObjectsAuthStep(BaseConfigurationStep): + """ + Configure credentials for Objects API to request Objecttypes API + """ + + verbose_name = "Objects API Authentication Configuration" + required_settings = [ + "OBJECTS_OBJECTTYPES_TOKEN", + "OBJECTS_OBJECTTYPES_PERSON", + "OBJECTS_OBJECTTYPES_EMAIL", + ] + enable_setting = "OBJECTS_OBJECTTYPES_CONFIG_ENABLE" + + def is_configured(self) -> bool: + return TokenAuth.objects.filter( + token=settings.OBJECTS_OBJECTTYPES_TOKEN + ).exists() + + def configure(self): + token_auth, created = TokenAuth.objects.get_or_create( + token=settings.OBJECTS_OBJECTTYPES_TOKEN, + defaults={ + "contact_person": settings.OBJECTS_OBJECTTYPES_PERSON, + "email": settings.OBJECTS_OBJECTTYPES_EMAIL, + }, + ) + if ( + token_auth.contact_person != settings.OBJECTS_OBJECTTYPES_PERSON + or token_auth.email != settings.OBJECTS_OBJECTTYPES_EMAIL + ): + token_auth.contact_person = settings.OBJECTS_OBJECTTYPES_PERSON + token_auth.email = settings.OBJECTS_OBJECTTYPES_EMAIL + token_auth.save(update_fields=["contact_person", "email"]) + + def test_configuration(self): + """ + This check depends on the configuration of permissions in Open Zaak + """ + endpoint = reverse("v2:objecttype-list") + full_url = build_absolute_url(endpoint, request=None) + + try: + response = requests.get( + full_url, + headers={ + "HTTP_AUTHORIZATION": f"Token {settings.OBJECTS_OBJECTTYPES_TOKEN}", + "Accept": "application/json", + }, + ) + response.raise_for_status() + except requests.RequestException as exc: + raise SelfTestFailed( + "Could not list objecttypes for the configured token" + ) from exc diff --git a/src/objecttypes/config/site.py b/src/objecttypes/config/site.py new file mode 100644 index 00000000..3d00b878 --- /dev/null +++ b/src/objecttypes/config/site.py @@ -0,0 +1,37 @@ +from django.conf import settings +from django.contrib.sites.models import Site +from django.urls import reverse + +import requests +from django_setup_configuration.configuration import BaseConfigurationStep +from django_setup_configuration.exceptions import SelfTestFailed + +from objecttypes.utils import build_absolute_url + + +class SiteConfigurationStep(BaseConfigurationStep): + """ + Configure the application site/domain. + """ + + verbose_name = "Site Configuration" + required_settings = ["OBJECTTYPES_DOMAIN", "OBJECTTYPES_ORGANIZATION"] + enable_setting = "SITES_CONFIG_ENABLE" + + def is_configured(self) -> bool: + site = Site.objects.get_current() + return site.domain == settings.OBJECTTYPES_DOMAIN + + def configure(self): + site = Site.objects.get_current() + site.domain = settings.OBJECTTYPES_DOMAIN + site.name = f"Objecttypes {settings.OBJECTTYPES_ORGANIZATION}".strip() + site.save() + + def test_configuration(self): + full_url = build_absolute_url(reverse("home")) + try: + response = requests.get(full_url) + response.raise_for_status() + except requests.RequestException as exc: + raise SelfTestFailed(f"Could not access home page at '{full_url}'") from exc diff --git a/src/objecttypes/urls.py b/src/objecttypes/urls.py index a9c70b5f..8e256729 100644 --- a/src/objecttypes/urls.py +++ b/src/objecttypes/urls.py @@ -48,6 +48,7 @@ template_name="index.html", extra_context={"version": api_settings.DEFAULT_VERSION}, ), + name="home", ), path("oidc/", include("mozilla_django_oidc.urls")), path("api/", include("objecttypes.api.urls")), diff --git a/src/objecttypes/utils/__init__.py b/src/objecttypes/utils/__init__.py index e69de29b..e6be3482 100644 --- a/src/objecttypes/utils/__init__.py +++ b/src/objecttypes/utils/__init__.py @@ -0,0 +1,29 @@ +from django.conf import settings +from django.http import HttpRequest + +from furl import furl + + +def get_domain() -> str: + """ + Obtain the domain/netloc of Open Notificaties according to settings or configuration. + """ + from django.contrib.sites.models import Site + + if settings.OBJECTTYPES_DOMAIN: + return settings.OBJECTTYPES_DOMAIN + + return Site.objects.get_current().domain + + +def build_absolute_url(path: str, request: HttpRequest | None = None) -> str: + if request is not None: + return request.build_absolute_uri(path) + + domain = get_domain() + _furl = furl( + scheme="https" if settings.IS_HTTPS else "http", + netloc=domain, + path=path, + ) + return _furl.url