Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ [#2262] Add setup configuration steps for ZGW and KIC #1116

Merged
merged 6 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements/base.in
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ django-mailer
django-image-cropping
django-log-outgoing-requests
xsdata
django-setup-configuration

# django cms
django-cms
Expand Down
3 changes: 3 additions & 0 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ django==4.2.10
# django-relativedelta
# django-sekizai
# django-sendfile2
# django-setup-configuration
# django-simple-certmanager
# django-sniplates
# django-solo
Expand Down Expand Up @@ -237,6 +238,8 @@ django-sessionprofile==1.0
# via
# -r requirements/base.in
# django-digid-eherkenning
django-setup-configuration==0.1.0
# via -r requirements/base.in
django-simple-certmanager==1.4.1
# via
# django-digid-eherkenning
Expand Down
5 changes: 5 additions & 0 deletions requirements/ci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ django==4.2.10
# django-relativedelta
# django-sekizai
# django-sendfile2
# django-setup-configuration
# django-simple-certmanager
# django-sniplates
# django-solo
Expand Down Expand Up @@ -399,6 +400,10 @@ django-sessionprofile==1.0
# -c requirements/base.txt
# -r requirements/base.txt
# django-digid-eherkenning
django-setup-configuration==0.1.0
# via
# -c requirements/base.txt
# -r requirements/base.txt
django-simple-certmanager==1.4.1
# via
# -c requirements/base.txt
Expand Down
5 changes: 5 additions & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ django==4.2.10
# django-relativedelta
# django-sekizai
# django-sendfile2
# django-setup-configuration
# django-silk
# django-simple-certmanager
# django-sniplates
Expand Down Expand Up @@ -442,6 +443,10 @@ django-sessionprofile==1.0
# -c requirements/ci.txt
# -r requirements/ci.txt
# django-digid-eherkenning
django-setup-configuration==0.1.0
# via
# -c requirements/ci.txt
# -r requirements/ci.txt
django-silk==5.1.0
# via -r requirements/dev.in
django-simple-certmanager==1.4.1
Expand Down
6 changes: 2 additions & 4 deletions src/open_inwoner/cms/cases/views/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,10 +938,8 @@ def register_by_api(self, form, config: OpenKlantConfig):
if ztc and ztc.contact_subject_code:
data["onderwerp"] = ztc.contact_subject_code

if contactmomenten_client := build_client_openklant("contactmomenten"):
contactmoment = contactmomenten_client.create_contactmoment(
data, klant=klant
)
if contactmoment_client := build_client_openklant("contactmomenten"):
contactmoment = contactmoment_client.create_contactmoment(data, klant=klant)
if contactmoment:
self.log_system_action(
"registered contactmoment by API", user=self.request.user
Expand Down
103 changes: 103 additions & 0 deletions src/open_inwoner/conf/app/setup_configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from ..utils import config

SETUP_CONFIGURATION_STEPS = [
"open_inwoner.configurations.bootstrap.zgw.ZakenAPIConfigurationStep",
"open_inwoner.configurations.bootstrap.zgw.CatalogiAPIConfigurationStep",
"open_inwoner.configurations.bootstrap.zgw.DocumentenAPIConfigurationStep",
"open_inwoner.configurations.bootstrap.zgw.FormulierenAPIConfigurationStep",
"open_inwoner.configurations.bootstrap.zgw.ZGWAPIsConfigurationStep",
"open_inwoner.configurations.bootstrap.kic.KlantenAPIConfigurationStep",
"open_inwoner.configurations.bootstrap.kic.ContactmomentenAPIConfigurationStep",
"open_inwoner.configurations.bootstrap.kic.KICAPIsConfigurationStep",
]
OIP_ORGANIZATION = config("OIP_ORGANIZATION", "")

# ZGW configuration variables
ZGW_CONFIG_ENABLE = config("ZGW_CONFIG_ENABLE", default=True)
ZGW_CONFIG_ZAKEN_API_ROOT = config("ZGW_CONFIG_ZAKEN_API_ROOT", "")
if ZGW_CONFIG_ZAKEN_API_ROOT and not ZGW_CONFIG_ZAKEN_API_ROOT.endswith("/"):
ZGW_CONFIG_ZAKEN_API_ROOT = f"{ZGW_CONFIG_ZAKEN_API_ROOT.strip()}/"
ZGW_CONFIG_ZAKEN_OAS_URL = ZGW_CONFIG_ZAKEN_API_ROOT # this is still required by the form, but not actually used
ZGW_CONFIG_ZAKEN_API_CLIENT_ID = config("ZGW_CONFIG_ZAKEN_API_CLIENT_ID", "")
ZGW_CONFIG_ZAKEN_API_SECRET = config("ZGW_CONFIG_ZAKEN_API_SECRET", "")
ZGW_CONFIG_CATALOGI_API_ROOT = config("ZGW_CONFIG_CATALOGI_API_ROOT", "")
if ZGW_CONFIG_CATALOGI_API_ROOT and not ZGW_CONFIG_CATALOGI_API_ROOT.endswith("/"):
ZGW_CONFIG_CATALOGI_API_ROOT = f"{ZGW_CONFIG_CATALOGI_API_ROOT.strip()}/"
ZGW_CONFIG_CATALOGI_OAS_URL = ZGW_CONFIG_CATALOGI_API_ROOT # this is still required by the form, but not actually used
ZGW_CONFIG_CATALOGI_API_CLIENT_ID = config("ZGW_CONFIG_CATALOGI_API_CLIENT_ID", "")
ZGW_CONFIG_CATALOGI_API_SECRET = config("ZGW_CONFIG_CATALOGI_API_SECRET", "")
ZGW_CONFIG_DOCUMENTEN_API_ROOT = config("ZGW_CONFIG_DOCUMENTEN_API_ROOT", "")
if ZGW_CONFIG_DOCUMENTEN_API_ROOT and not ZGW_CONFIG_DOCUMENTEN_API_ROOT.endswith("/"):
ZGW_CONFIG_DOCUMENTEN_API_ROOT = f"{ZGW_CONFIG_DOCUMENTEN_API_ROOT.strip()}/"
ZGW_CONFIG_DOCUMENTEN_OAS_URL = ZGW_CONFIG_DOCUMENTEN_API_ROOT # this is still required by the form, but not actually used
ZGW_CONFIG_DOCUMENTEN_API_CLIENT_ID = config("ZGW_CONFIG_DOCUMENTEN_API_CLIENT_ID", "")
ZGW_CONFIG_DOCUMENTEN_API_SECRET = config("ZGW_CONFIG_DOCUMENTEN_API_SECRET", "")
ZGW_CONFIG_FORMULIEREN_API_ROOT = config("ZGW_CONFIG_FORMULIEREN_API_ROOT", "")
if ZGW_CONFIG_FORMULIEREN_API_ROOT and not ZGW_CONFIG_FORMULIEREN_API_ROOT.endswith(
"/"
):
ZGW_CONFIG_FORMULIEREN_API_ROOT = f"{ZGW_CONFIG_FORMULIEREN_API_ROOT.strip()}/"
ZGW_CONFIG_FORMULIEREN_OAS_URL = ZGW_CONFIG_FORMULIEREN_API_ROOT # this is still required by the form, but not actually used
ZGW_CONFIG_FORMULIEREN_API_CLIENT_ID = config(
"ZGW_CONFIG_FORMULIEREN_API_CLIENT_ID", ""
)
ZGW_CONFIG_FORMULIEREN_API_SECRET = config("ZGW_CONFIG_FORMULIEREN_API_SECRET", "")
# ZGW config options
ZGW_CONFIG_ZAAK_MAX_CONFIDENTIALITY = config(
"ZGW_CONFIG_ZAAK_MAX_CONFIDENTIALITY", None
)
ZGW_CONFIG_DOCUMENT_MAX_CONFIDENTIALITY = config(
"ZGW_CONFIG_DOCUMENT_MAX_CONFIDENTIALITY", None
)
ZGW_CONFIG_ACTION_REQUIRED_DEADLINE_DAYS = config("ACTION_REQUIRED_DEADLINE_DAYS", None)
ZGW_CONFIG_ALLOWED_FILE_EXTENSIONS = config("ZGW_CONFIG_ALLOWED_FILE_EXTENSIONS", None)
ZGW_CONFIG_MIJN_AANVRAGEN_TITLE_TEXT = config(
"ZGW_CONFIG_MIJN_AANVRAGEN_TITLE_TEXT", None
)
ZGW_CONFIG_ENABLE_CATEGORIES_FILTERING_WITH_ZAKEN = config(
"ZGW_CONFIG_ENABLE_CATEGORIES_FILTERING_WITH_ZAKEN", None
)
ZGW_CONFIG_SKIP_NOTIFICATION_STATUSTYPE_INFORMEREN = config(
"ZGW_CONFIG_SKIP_NOTIFICATION_STATUSTYPE_INFORMEREN", None
)
ZGW_CONFIG_REFORMAT_ESUITE_ZAAK_IDENTIFICATIE = config(
"ZGW_CONFIG_REFORMAT_ESUITE_ZAAK_IDENTIFICATIE", None
)
ZGW_CONFIG_FETCH_EHERKENNING_ZAKEN_WITH_RSIN = config(
"ZGW_CONFIG_FETCH_EHERKENNING_ZAKEN_WITH_RSIN", None
)

# KIC configuration variables
KIC_CONFIG_ENABLE = config("KIC_CONFIG_ENABLE", default=True)
KIC_CONFIG_KLANTEN_API_ROOT = config("KIC_CONFIG_KLANTEN_API_ROOT", "")
if KIC_CONFIG_KLANTEN_API_ROOT and not KIC_CONFIG_KLANTEN_API_ROOT.endswith("/"):
KIC_CONFIG_KLANTEN_API_ROOT = f"{KIC_CONFIG_KLANTEN_API_ROOT.strip()}/"
KIC_CONFIG_KLANTEN_OAS_URL = KIC_CONFIG_KLANTEN_API_ROOT # this is still required by the form, but not actually used
KIC_CONFIG_KLANTEN_API_CLIENT_ID = config("KIC_CONFIG_KLANTEN_API_CLIENT_ID", "")
KIC_CONFIG_KLANTEN_API_SECRET = config("KIC_CONFIG_KLANTEN_API_SECRET", "")
KIC_CONFIG_CONTACTMOMENTEN_API_ROOT = config("KIC_CONFIG_CONTACTMOMENTEN_API_ROOT", "")
if (
KIC_CONFIG_CONTACTMOMENTEN_API_ROOT
and not KIC_CONFIG_CONTACTMOMENTEN_API_ROOT.endswith("/")
):
KIC_CONFIG_CONTACTMOMENTEN_API_ROOT = (
f"{KIC_CONFIG_CONTACTMOMENTEN_API_ROOT.strip()}/"
)
KIC_CONFIG_CONTACTMOMENTEN_OAS_URL = KIC_CONFIG_CONTACTMOMENTEN_API_ROOT # this is still required by the form, but not actually used
KIC_CONFIG_CONTACTMOMENTEN_API_CLIENT_ID = config(
"KIC_CONFIG_CONTACTMOMENTEN_API_CLIENT_ID", ""
)
KIC_CONFIG_CONTACTMOMENTEN_API_SECRET = config(
"KIC_CONFIG_CONTACTMOMENTEN_API_SECRET", ""
)
KIC_CONFIG_REGISTER_EMAIL = config("KIC_CONFIG_REGISTER_EMAIL", None)
KIC_CONFIG_REGISTER_CONTACT_MOMENT = config("KIC_CONFIG_REGISTER_CONTACT_MOMENT", None)
KIC_CONFIG_REGISTER_BRONORGANISATIE_RSIN = config(
"KIC_CONFIG_REGISTER_BRONORGANISATIE_RSIN", None
)
KIC_CONFIG_REGISTER_CHANNEL = config("KIC_CONFIG_REGISTER_CHANNEL", None)
KIC_CONFIG_REGISTER_TYPE = config("KIC_CONFIG_REGISTER_TYPE", None)
KIC_CONFIG_REGISTER_EMPLOYEE_ID = config("KIC_CONFIG_REGISTER_EMPLOYEE_ID", None)
KIC_CONFIG_USE_RSIN_FOR_INNNNPID_QUERY_PARAMETER = config(
"KIC_CONFIG_USE_RSIN_FOR_INNNNPID_QUERY_PARAMETER", None
)
5 changes: 5 additions & 0 deletions src/open_inwoner/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@
"mailer",
"log_outgoing_requests",
"formtools",
"django_setup_configuration",
# Project applications.
"open_inwoner.components",
"open_inwoner.kvk",
Expand Down Expand Up @@ -929,6 +930,10 @@
}
}

#
# django-setup-configuration
#
from .app.setup_configuration import * # noqa

#
# Project specific settings
Expand Down
Empty file.
167 changes: 167 additions & 0 deletions src/open_inwoner/configurations/bootstrap/kic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
from django.conf import settings

import requests
from django_setup_configuration.configuration import BaseConfigurationStep
from django_setup_configuration.exceptions import SelfTestFailed
from zgw_consumers.constants import APITypes, AuthTypes
from zgw_consumers.models import Service

from open_inwoner.openklant.clients import build_client
from open_inwoner.openklant.models import OpenKlantConfig
from open_inwoner.utils.api import ClientError


class KlantenAPIConfigurationStep(BaseConfigurationStep):
"""
Configure the required Service to establish a connection with the Klanten API
"""

verbose_name = "Klanten API configuration"
required_settings = [
"KIC_CONFIG_KLANTEN_API_ROOT",
"KIC_CONFIG_KLANTEN_API_CLIENT_ID",
"KIC_CONFIG_KLANTEN_API_SECRET",
]
enable_setting = "KIC_CONFIG_ENABLE"

def is_configured(self) -> bool:
return Service.objects.filter(
api_root=settings.KIC_CONFIG_KLANTEN_API_ROOT
).exists()

def configure(self):
organization = settings.OIP_ORGANIZATION or settings.ENVIRONMENT
org_label = f"Open Inwoner {organization}".strip()

Service.objects.update_or_create(
api_root=settings.KIC_CONFIG_KLANTEN_API_ROOT,
defaults={
"label": "Klanten API",
"api_type": APITypes.kc,
"oas": settings.KIC_CONFIG_KLANTEN_API_ROOT,
"auth_type": AuthTypes.zgw,
"client_id": settings.KIC_CONFIG_KLANTEN_API_CLIENT_ID,
"secret": settings.KIC_CONFIG_KLANTEN_API_SECRET,
"user_id": settings.KIC_CONFIG_KLANTEN_API_CLIENT_ID,
"user_representation": org_label,
},
)

def test_configuration(self):
"""
actual testing is done in final step
"""


class ContactmomentenAPIConfigurationStep(BaseConfigurationStep):
"""
Configure the required Service to establish a connection with the Contactmomenten API
"""

verbose_name = "Contactmomenten API configuration"
required_settings = [
"KIC_CONFIG_CONTACTMOMENTEN_API_ROOT",
"KIC_CONFIG_CONTACTMOMENTEN_API_CLIENT_ID",
"KIC_CONFIG_CONTACTMOMENTEN_API_SECRET",
]
enable_setting = "KIC_CONFIG_ENABLE"

def is_configured(self) -> bool:
return Service.objects.filter(
api_root=settings.KIC_CONFIG_CONTACTMOMENTEN_API_ROOT
).exists()

def configure(self):
organization = settings.OIP_ORGANIZATION or settings.ENVIRONMENT
org_label = f"Open Inwoner {organization}".strip()
stevenbal marked this conversation as resolved.
Show resolved Hide resolved

Service.objects.update_or_create(
api_root=settings.KIC_CONFIG_CONTACTMOMENTEN_API_ROOT,
defaults={
"label": "Contactmomenten API",
"api_type": APITypes.cmc,
"oas": settings.KIC_CONFIG_CONTACTMOMENTEN_API_ROOT,
"auth_type": AuthTypes.zgw,
"client_id": settings.KIC_CONFIG_CONTACTMOMENTEN_API_CLIENT_ID,
"secret": settings.KIC_CONFIG_CONTACTMOMENTEN_API_SECRET,
"user_id": settings.KIC_CONFIG_CONTACTMOMENTEN_API_CLIENT_ID,
"user_representation": org_label,
},
)

def test_configuration(self):
"""
actual testing is done in final step
"""


class KICAPIsConfigurationStep(BaseConfigurationStep):
"""
Configure the KIC settings and set any feature flags or other options if specified
"""

verbose_name = "Klantinteractie APIs configuration"
enable_setting = "KIC_CONFIG_ENABLE"

def is_configured(self) -> bool:
kic_config = OpenKlantConfig.get_solo()
return bool(kic_config.klanten_service) and bool(
kic_config.contactmomenten_service
)

def configure(self):
config = OpenKlantConfig.get_solo()
config.klanten_service = Service.objects.get(
api_root=settings.KIC_CONFIG_KLANTEN_API_ROOT
)
config.contactmomenten_service = Service.objects.get(
api_root=settings.KIC_CONFIG_CONTACTMOMENTEN_API_ROOT
)

if settings.KIC_CONFIG_REGISTER_EMAIL:
config.register_email = settings.KIC_CONFIG_REGISTER_EMAIL
if settings.KIC_CONFIG_REGISTER_CONTACT_MOMENT is not None:
config.register_contact_moment = settings.KIC_CONFIG_REGISTER_CONTACT_MOMENT
if settings.KIC_CONFIG_REGISTER_BRONORGANISATIE_RSIN:
config.register_bronorganisatie_rsin = (
settings.KIC_CONFIG_REGISTER_BRONORGANISATIE_RSIN
)
if settings.KIC_CONFIG_REGISTER_CHANNEL:
config.register_channel = settings.KIC_CONFIG_REGISTER_CHANNEL
if settings.KIC_CONFIG_REGISTER_TYPE:
config.register_type = settings.KIC_CONFIG_REGISTER_TYPE
if settings.KIC_CONFIG_REGISTER_EMPLOYEE_ID:
config.register_employee_id = settings.KIC_CONFIG_REGISTER_EMPLOYEE_ID
if settings.KIC_CONFIG_USE_RSIN_FOR_INNNNPID_QUERY_PARAMETER is not None:
config.use_rsin_for_innNnpId_query_parameter = (
settings.KIC_CONFIG_USE_RSIN_FOR_INNNNPID_QUERY_PARAMETER
)

config.save()

def test_configuration(self):
"""
make requests to the APIs and verify that a connection can be made
"""
klanten_client = build_client("klanten")
contactmoment_client = build_client("contactmomenten")

try:
response = klanten_client.get(
"klanten", params={"subjectNatuurlijkPersoon__inpBsn": "000000000"}
)
response.raise_for_status()
except (ClientError, requests.RequestException) as exc:
raise SelfTestFailed(
"Could not retrieve list of klanten from Klanten API."
) from exc

try:
response = contactmoment_client.get(
"contactmomenten", params={"identificatie": "00000"}
)
response.raise_for_status()
except (ClientError, requests.RequestException) as exc:
raise SelfTestFailed(
"Could not retrieve list of objectcontactmomenten from Contactmomenten API."
) from exc
Loading
Loading