diff --git a/authentik/outposts/api/outposts.py b/authentik/outposts/api/outposts.py index af0941edac..d026fa5031 100644 --- a/authentik/outposts/api/outposts.py +++ b/authentik/outposts/api/outposts.py @@ -1,23 +1,33 @@ """Outpost API Views""" +from dacite.core import from_dict +from dacite.exceptions import DaciteError from drf_yasg.utils import swagger_auto_schema from rest_framework.decorators import action from rest_framework.fields import BooleanField, CharField, DateTimeField from rest_framework.request import Request from rest_framework.response import Response -from rest_framework.serializers import JSONField, ModelSerializer +from rest_framework.serializers import JSONField, ModelSerializer, ValidationError from rest_framework.viewsets import ModelViewSet from authentik.core.api.providers import ProviderSerializer from authentik.core.api.utils import PassiveSerializer, is_dict -from authentik.outposts.models import Outpost, default_outpost_config +from authentik.outposts.models import Outpost, OutpostConfig, default_outpost_config class OutpostSerializer(ModelSerializer): """Outpost Serializer""" - _config = JSONField(validators=[is_dict]) + config = JSONField(validators=[is_dict], source="_config") providers_obj = ProviderSerializer(source="providers", many=True, read_only=True) + def validate_config(self, config) -> dict: + """Check that the config has all required fields""" + try: + from_dict(OutpostConfig, config) + except DaciteError as exc: + raise ValidationError(f"Failed to validate config: {str(exc)}") from exc + return config + class Meta: model = Outpost @@ -29,7 +39,7 @@ class OutpostSerializer(ModelSerializer): "providers_obj", "service_connection", "token_identifier", - "_config", + "config", ] diff --git a/authentik/outposts/tests/test_api.py b/authentik/outposts/tests/test_api.py index 841f52a153..ce44674473 100644 --- a/authentik/outposts/tests/test_api.py +++ b/authentik/outposts/tests/test_api.py @@ -3,6 +3,10 @@ from django.urls import reverse from rest_framework.test import APITestCase from authentik.core.models import PropertyMapping, User +from authentik.flows.models import Flow +from authentik.outposts.api.outposts import OutpostSerializer +from authentik.outposts.models import default_outpost_config +from authentik.providers.proxy.models import ProxyProvider class TestOutpostServiceConnectionsAPI(APITestCase): @@ -22,3 +26,20 @@ class TestOutpostServiceConnectionsAPI(APITestCase): reverse("authentik_api:outpostserviceconnection-types"), ) self.assertEqual(response.status_code, 200) + + def test_outpost_config(self): + """Test Outpost's config field""" + provider = ProxyProvider.objects.create(name="test", authorization_flow=Flow.objects.first()) + invalid = OutpostSerializer(data={ + "name": "foo", + "providers": [provider.pk], + "config": {} + }) + self.assertFalse(invalid.is_valid()) + self.assertIn("config", invalid.errors) + valid = OutpostSerializer(data={ + "name": "foo", + "providers": [provider.pk], + "config": default_outpost_config("foo") + }) + self.assertTrue(valid.is_valid()) diff --git a/swagger.yaml b/swagger.yaml index edf6a34d31..2b8da5f836 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -16198,7 +16198,7 @@ definitions: required: - name - providers - - _config + - config type: object properties: pk: @@ -16237,8 +16237,8 @@ definitions: title: Token identifier type: string readOnly: true - _config: - title: config + config: + title: Config type: object OutpostDefaultConfig: type: object diff --git a/web/src/pages/outposts/OutpostForm.ts b/web/src/pages/outposts/OutpostForm.ts index 24d531a40a..1e65dd045e 100644 --- a/web/src/pages/outposts/OutpostForm.ts +++ b/web/src/pages/outposts/OutpostForm.ts @@ -102,18 +102,18 @@ export class OutpostForm extends Form {

${t`Hold control/command to select multiple items.`}

- ${until(new OutpostsApi(DEFAULT_CONFIG).outpostsOutpostsDefaultSettings({}).then(config => { - let fc = config.config; - if (this.outpost) { - fc = this.outpost.config; - } - return html` - -

${t`Set custom attributes using YAML or JSON.`}

-
`; - }))} + + +

${t`Set custom attributes using YAML or JSON.`}

+
`; }