blueprints: fix error caused by overriding rest_framework's instance attribute

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-09-10 14:34:43 +02:00
parent 7a50d5a4f8
commit ae9dbf3014
3 changed files with 19 additions and 7 deletions

View file

@ -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

View file

@ -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:

View file

@ -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()