diff --git a/authentik/blueprints/v1/common.py b/authentik/blueprints/v1/common.py index 138607e72..8fa77ffa6 100644 --- a/authentik/blueprints/v1/common.py +++ b/authentik/blueprints/v1/common.py @@ -253,3 +253,9 @@ class BlueprintLoader(SafeLoader): class EntryInvalidError(SentryIgnoredException): """Error raised when an entry is invalid""" + + serializer_errors: Optional[dict] + + def __init__(self, *args: object, serializer_errors: Optional[dict] = None) -> None: + super().__init__(*args) + self.serializer_errors = serializer_errors diff --git a/authentik/blueprints/v1/importer.py b/authentik/blueprints/v1/importer.py index 4341ed3fd..96ff74bdb 100644 --- a/authentik/blueprints/v1/importer.py +++ b/authentik/blueprints/v1/importer.py @@ -148,7 +148,9 @@ class Importer: try: serializer.is_valid(raise_exception=True) except ValidationError as exc: - raise EntryInvalidError(f"Serializer errors {serializer.errors}") from exc + raise EntryInvalidError( + f"Serializer errors {serializer.errors}", serializer_errors=serializer.errors + ) from exc return serializer if entry.identifiers == {}: raise EntryInvalidError("No identifiers") @@ -193,7 +195,9 @@ class Importer: try: serializer.is_valid(raise_exception=True) except ValidationError as exc: - raise EntryInvalidError(f"Serializer errors {serializer.errors}") from exc + raise EntryInvalidError( + f"Serializer errors {serializer.errors}", serializer_errors=serializer.errors + ) from exc return serializer def apply(self) -> bool: diff --git a/authentik/blueprints/v1/meta/apply_blueprint.py b/authentik/blueprints/v1/meta/apply_blueprint.py index 81406b771..770882d77 100644 --- a/authentik/blueprints/v1/meta/apply_blueprint.py +++ b/authentik/blueprints/v1/meta/apply_blueprint.py @@ -20,7 +20,9 @@ class ApplyBlueprintMetaSerializer(PassiveSerializer): identifiers = JSONField(validators=[is_dict]) required = BooleanField(default=True) - instance: "BlueprintInstance" + # We cannot override `instance` as that will confuse rest_framework + # and make it attempt to update the instance + blueprint_instance: "BlueprintInstance" def validate(self, attrs): from authentik.blueprints.models import BlueprintInstance @@ -30,18 +32,18 @@ class ApplyBlueprintMetaSerializer(PassiveSerializer): instance = BlueprintInstance.objects.filter(**identifiers).first() if not instance and required: raise ValidationError("Required blueprint does not exist") - self.instance = instance + self.blueprint_instance = instance return super().validate(attrs) def create(self, validated_data: dict) -> MetaResult: from authentik.blueprints.v1.tasks import apply_blueprint - if not self.instance: + if not self.blueprint_instance: LOGGER.info("Blueprint does not exist, but not required") return MetaResult() - LOGGER.debug("Applying blueprint from meta model", blueprint=self.instance) + LOGGER.debug("Applying blueprint from meta model", blueprint=self.blueprint_instance) # pylint: disable=no-value-for-parameter - apply_blueprint(str(self.instance.pk)) + apply_blueprint(str(self.blueprint_instance.pk)) return MetaResult()