Skip to content

Commit

Permalink
parent 64fa395
Browse files Browse the repository at this point in the history
author Daniel Mursa <[email protected]> 1734341658 +0100
committer Daniel Mursa <[email protected]> 1734604578 +0100

parent 64fa395
author Daniel Mursa <[email protected]> 1734341658 +0100
committer Daniel Mursa <[email protected]> 1734604572 +0100

[#485] Merge closed branch

[#485] Add SitesConfigurationStep and TokenAuthConfigurationStep in settings

[#485] Black and isort

[#485] Fix requirements

[#485] Update namespace

[#486] Update TokenAuthConfigurationStep

[#486] Permissions can be empty list

[#486] Update tests

[#486] New tests

[#486] Update tests

[#486] Fix old tests

[#486] Update data.yaml

[#486] Activate ObjectTypesConfigurationStep

[#486] Add new test

[#486] Update config_cli.rst

[#486] Fix config_cli.rst

[#486] Fix config_cli.rst

[#486] Uniform data.yaml and config_cli.rst
  • Loading branch information
danielmursa-dev committed Dec 19, 2024
1 parent 64fa395 commit 02426aa
Show file tree
Hide file tree
Showing 7 changed files with 845 additions and 53 deletions.
15 changes: 13 additions & 2 deletions docker/setup_configuration/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,29 @@ objecttypes:
name: Object Type 1
service_identifier: objecttypes-api

- uuid: b0e8553f-8b1a-4d55-ab90-6d02f1bcf2c2
name: Object Type 2
service_identifier: objecttypes-api


tokenauth_config_enable: true
tokenauth:
items:
- identifier: token-1
token: 18b2b74ef994314b84021d47b9422e82b685d82f
token: ba9d233e95e04c4a8a661a27daffe7c9bd019067
contact_person: Person 1
email: [email protected]
organization: Organization 1
application: Application 1
administration: Administration 1
is_superuser: true
permissions:
- object_type: b427ef84-189d-43aa-9efd-7bb2c459e281
mode: read_and_write
- object_type: b0e8553f-8b1a-4d55-ab90-6d02f1bcf2c2
mode: read_only
use_fields: true
fields:
key1: value1


oidc_db_config_enable: true
Expand Down
43 changes: 37 additions & 6 deletions docs/installation/config_cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Objecttypes configuration
To configure objecttypes the following configuration could be used:

.. code-block:: yaml
...
zgw_consumers_config_enable: true
zgw_consumers:
Expand Down Expand Up @@ -68,6 +69,7 @@ To configure objecttypes the following configuration could be used:
name: Object Type 2
service_identifier: objecttypen-bar
...
.. note:: The ``uuid`` field will be used to lookup existing ``ObjectType``'s.

Objecttypes require a corresponding ``Service`` to work correctly. Creating
Expand All @@ -81,8 +83,8 @@ In order to be able to retrieve objecttypes, a corresponding ``Service`` should
created. An example of a configuration could be seen below:

.. code-block:: yaml
...
...
zgw_consumers_config_enable: true
zgw_consumers:
services:
Expand All @@ -102,7 +104,8 @@ created. An example of a configuration could be seen below:
auth_type: api_key
header_key: Authorization
header_value: Token b9f100590925b529664ed9d370f5f8da124b2c20
....
...
Tokens configuration
--------------------
Expand All @@ -121,14 +124,26 @@ Create or update the (single) YAML configuration file with your settings:
organization: Organization XYZ # optional
application: Application XYZ # optional
administration: Administration XYZ # optional
is_superuser: true # optional
permissions:
- object_type: b427ef84-189d-43aa-9efd-7bb2c459e281
mode: read_and_write
- identifier: token-2
token: 7b2b212d9f16d171a70a1d927cdcfbd5ca7a4799
contact_person: Person 2
email: [email protected]
permissions:
- object_type: b0e8553f-8b1a-4d55-ab90-6d02f1bcf2c2
mode: read_only
use_fields: true
fields:
key1: value1
...
.. note:: To ensure the proper functioning of the tokens, it is essential to first configure the ``objecttypes``.
Then, the token configuration must be completed to guarantee the correct configuration of the ``Permissions``.


Mozilla-django-oidc-db
----------------------

Expand Down Expand Up @@ -158,16 +173,32 @@ can be found at the _`documentation`: https://mozilla-django-oidc-db.readthedocs
Sites configuration
-------------------

.. code-block:: yaml
...
sites_config_enable: true
sites_config:
items:
- domain: example.com
name: Example site
- domain: test.example.com
name: Test site
...
More details about sites configuration through ``setup_configuration``
can be found at the _`site documentation`: https://github.com/maykinmedia/django-setup-configuration/blob/main/docs/sites_config.rst


Notifications configuration
-------------------------
---------------------------

To configure sending notifications for the application ensure there is a ``services``
item present that matches the ``notifications_api_service_identifier`` in the
``notifications_config`` namespace:

.. code-block:: yaml
...
...
zgw_consumers_config_enable: true
zgw_consumers:
services:
Expand All @@ -184,7 +215,7 @@ item present that matches the ``notifications_api_service_identifier`` in the
notification_delivery_max_retries: 1
notification_delivery_retry_backoff: 2
notification_delivery_retry_backoff_max: 3
....
...
Execution
Expand Down
1 change: 1 addition & 0 deletions src/objects/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,6 @@
"zgw_consumers.contrib.setup_configuration.steps.ServiceConfigurationStep",
"notifications_api_common.contrib.setup_configuration.steps.NotificationConfigurationStep",
"mozilla_django_oidc_db.setup_configuration.steps.AdminOIDCConfigurationStep",
"objects.setup_configuration.steps.objecttypes.ObjectTypesConfigurationStep",
"objects.setup_configuration.steps.token_auth.TokenAuthConfigurationStep",
)
20 changes: 19 additions & 1 deletion src/objects/setup_configuration/models/token_auth.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
from django_setup_configuration.models import ConfigurationModel
from pydantic import UUID4, Field

from objects.token.models import TokenAuth
from objects.token.models import Permission, TokenAuth


class TokenAuthPermissionConfigurationModel(ConfigurationModel):
object_type: UUID4
fields: dict | None = Field(default=None)

class Meta:
django_model_refs = {
Permission: (
"mode",
"use_fields",
),
}


class TokenAuthConfigurationModel(ConfigurationModel):
permissions: list[TokenAuthPermissionConfigurationModel] | None = Field(
default_factory=list,
)

class Meta:
django_model_refs = {
TokenAuth: (
Expand Down
90 changes: 65 additions & 25 deletions src/objects/setup_configuration/steps/token_auth.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import logging
from typing import Any

from django.core.exceptions import ValidationError
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import IntegrityError

from django_setup_configuration.configuration import BaseConfigurationStep
from django_setup_configuration.exceptions import ConfigurationRunFailed
from django_setup_configuration.exceptions import (
ConfigurationRunFailed,
PrerequisiteFailed,
)

from objects.core.models import ObjectType
from objects.setup_configuration.models.token_auth import (
TokenAuthGroupConfigurationModel,
)
from objects.token.models import TokenAuth
from objects.token.models import Permission, TokenAuth

logger = logging.getLogger(__name__)

Expand All @@ -18,7 +23,7 @@ class TokenAuthConfigurationStep(
BaseConfigurationStep[TokenAuthGroupConfigurationModel]
):
"""
Configure tokens for other applications to access Objects API
Configure tokens with permissions for other applications to access Objects API
"""

namespace = "tokenauth"
Expand All @@ -27,14 +32,56 @@ class TokenAuthConfigurationStep(
verbose_name = "Configuration to set up authentication tokens for objects"
config_model = TokenAuthGroupConfigurationModel

def _full_clean(self, instance: Any) -> None:
try:
instance.full_clean(exclude=("id",), validate_unique=False)
except ValidationError as exception:
raise ConfigurationRunFailed(
("Validation error(s) during instance cleaning: %s" % type(instance))
) from exception

def _configure_permissions(self, token: TokenAuth, permissions: list) -> None:
if len(permissions) == 0:
logger.warning("No permissions provided for %s", token.identifier)

for permission in permissions:
try:
permission_kwargs = {
"token_auth": token,
"object_type": ObjectType.objects.get(uuid=permission.object_type),
"mode": permission.mode,
"use_fields": permission.use_fields,
"fields": permission.fields,
}
except ObjectDoesNotExist as exception:
raise PrerequisiteFailed(step=self, validation_error=exception)

permission_instance = Permission(**permission_kwargs)
self._full_clean(permission_instance)

try:
Permission.objects.update_or_create(
token_auth=permission_kwargs["token_auth"],
object_type=permission_kwargs["object_type"],
defaults={
"mode": permission_kwargs["mode"],
"use_fields": permission_kwargs["use_fields"],
"fields": permission_kwargs["fields"],
},
)
except IntegrityError as exception:
raise ConfigurationRunFailed(
("Failed configuring permission for token %s" % token.identifier)
) from exception

def execute(self, model: TokenAuthGroupConfigurationModel) -> None:
if len(model.items) == 0:
logger.warning("No tokens provided for configuration")

for item in model.items:
logger.info(f"Configuring {item.identifier}")
logger.info("Configuring %s", item.identifier)

model_kwargs = {
token_kwargs = {
"identifier": item.identifier,
"token": item.token,
"contact_person": item.contact_person,
Expand All @@ -45,31 +92,24 @@ def execute(self, model: TokenAuthGroupConfigurationModel) -> None:
"is_superuser": item.is_superuser,
}

token_instance = TokenAuth(**model_kwargs)

token_instance = TokenAuth(**token_kwargs)
self._full_clean(token_instance)
try:
token_instance.full_clean(exclude=("id",), validate_unique=False)
except ValidationError as exception:
exception_message = (
f"Validation error(s) occured for {item.identifier}."
)
raise ConfigurationRunFailed(exception_message) from exception

logger.debug(f"No validation errors found for {item.identifier}")

try:
logger.debug(f"Saving {item.identifier}")

TokenAuth.objects.update_or_create(
logger.debug("Saving %s", item.identifier)
token, _ = TokenAuth.objects.update_or_create(
identifier=item.identifier,
defaults={
key: value
for key, value in model_kwargs.items()
for key, value in token_kwargs.items()
if key != "identifier"
},
)

self._configure_permissions(token, item.permissions)

except IntegrityError as exception:
exception_message = f"Failed configuring token {item.identifier}."
raise ConfigurationRunFailed(exception_message) from exception
raise ConfigurationRunFailed(
"Failed configuring token %s" % item.identifier
) from exception

logger.info(f"Configured {item.identifier}")
logger.info("Configured %s", item.identifier)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@ tokenauth:
organization: Organization 1
application: Application 1
administration: Administration 1
is_superuser: True
permissions:
- object_type: 3a82fb7f-fc9b-4104-9804-993f639d6d0d
mode: read_only
use_fields: true
fields:
key1: value1
key2: value2
key3: value3
- object_type: ca754b52-3f37-4c49-837c-130e8149e337
mode: read_and_write

- identifier: token-2
token: e882642bd0ec2482adcdc97258c2e6f98cb06d85
Expand All @@ -17,4 +26,15 @@ tokenauth:
organization: Organization 2
application: Application 2
administration: Administration 2
permissions:
- object_type: feeaa795-d212-4fa2-bb38-2c34996e5702
mode: read_only

- identifier: token-3
token: ff835859ecf8df4d541aab09f2d0854d17b41a77
contact_person: Person 3
email: [email protected]
organization: Organization 3
application: Application 3
administration: Administration 3
is_superuser: True
Loading

0 comments on commit 02426aa

Please sign in to comment.