From 4c4d87d3bd69a2acf941c15b73470413eb5c2a80 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 10 Sep 2022 13:54:28 +0200 Subject: [PATCH] blueprints: validate instance before creating in metaapplyblueprint Signed-off-by: Jens Langhammer --- authentik/blueprints/models.py | 4 +-- authentik/blueprints/tests/test_packaged.py | 2 ++ .../blueprints/v1/meta/apply_blueprint.py | 30 +++++++++++++------ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/authentik/blueprints/models.py b/authentik/blueprints/models.py index 9b53c12f9..d53fc12e6 100644 --- a/authentik/blueprints/models.py +++ b/authentik/blueprints/models.py @@ -98,7 +98,7 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel): WithDefaultName(path), WithDebug(True), ) - LOGGER.debug("Fetching OCI manifests for blueprint", instance=self) + LOGGER.info("Fetching OCI manifests for blueprint", instance=self) manifest_request = client.NewRequest( "GET", "/v2//manifests/", @@ -137,7 +137,7 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel): """Retrieve blueprint contents""" full_path = Path(CONFIG.y("blueprints_dir")).joinpath(Path(self.path)) if full_path.exists(): - LOGGER.info("Blueprint path exists locally", instance=self) + LOGGER.debug("Blueprint path exists locally", instance=self) with full_path.open("r", encoding="utf-8") as _file: return _file.read() return self.retrieve_oci() diff --git a/authentik/blueprints/tests/test_packaged.py b/authentik/blueprints/tests/test_packaged.py index 21188e893..bbb38bd39 100644 --- a/authentik/blueprints/tests/test_packaged.py +++ b/authentik/blueprints/tests/test_packaged.py @@ -33,4 +33,6 @@ def blueprint_tester(file_name: Path) -> Callable: for blueprint_file in Path("blueprints/").glob("**/*.yaml"): + if "local" in str(blueprint_file): + continue setattr(TestPackaged, f"test_blueprint_{blueprint_file}", blueprint_tester(blueprint_file)) diff --git a/authentik/blueprints/v1/meta/apply_blueprint.py b/authentik/blueprints/v1/meta/apply_blueprint.py index 03824aeb3..81406b771 100644 --- a/authentik/blueprints/v1/meta/apply_blueprint.py +++ b/authentik/blueprints/v1/meta/apply_blueprint.py @@ -1,4 +1,6 @@ """Apply Blueprint meta model""" +from typing import TYPE_CHECKING + from rest_framework.exceptions import ValidationError from rest_framework.fields import BooleanField, JSONField from structlog.stdlib import get_logger @@ -6,6 +8,9 @@ from structlog.stdlib import get_logger from authentik.blueprints.v1.meta.registry import BaseMetaModel, MetaResult, registry from authentik.core.api.utils import PassiveSerializer, is_dict +if TYPE_CHECKING: + from authentik.blueprints.models import BlueprintInstance + LOGGER = get_logger() @@ -15,21 +20,28 @@ class ApplyBlueprintMetaSerializer(PassiveSerializer): identifiers = JSONField(validators=[is_dict]) required = BooleanField(default=True) - def create(self, validated_data: dict) -> MetaResult: + instance: "BlueprintInstance" + + def validate(self, attrs): from authentik.blueprints.models import BlueprintInstance + + identifiers = attrs["identifiers"] + required = attrs["required"] + instance = BlueprintInstance.objects.filter(**identifiers).first() + if not instance and required: + raise ValidationError("Required blueprint does not exist") + self.instance = instance + return super().validate(attrs) + + def create(self, validated_data: dict) -> MetaResult: from authentik.blueprints.v1.tasks import apply_blueprint - identifiers = validated_data["identifiers"] - required = validated_data["required"] - instance = BlueprintInstance.objects.filter(**identifiers).first() - if not instance: - if required: - raise ValidationError("Required blueprint does not exist") + if not self.instance: LOGGER.info("Blueprint does not exist, but not required") return MetaResult() - LOGGER.debug("Applying blueprint from meta model", blueprint=instance) + LOGGER.debug("Applying blueprint from meta model", blueprint=self.instance) # pylint: disable=no-value-for-parameter - apply_blueprint(str(instance.pk)) + apply_blueprint(str(self.instance.pk)) return MetaResult()