From 0e9762072a5c6a87daa14f568fab312c7c3e0283 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 18 Aug 2022 17:41:53 +0200 Subject: [PATCH] blueprints: keep more modular state Signed-off-by: Jens Langhammer --- authentik/blueprints/v1/common.py | 23 +++++++++++++++-------- authentik/blueprints/v1/importer.py | 3 ++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/authentik/blueprints/v1/common.py b/authentik/blueprints/v1/common.py index d84f1d111..1197c0b9e 100644 --- a/authentik/blueprints/v1/common.py +++ b/authentik/blueprints/v1/common.py @@ -27,16 +27,23 @@ def get_attrs(obj: SerializerModel) -> dict[str, Any]: continue if _field.read_only: data.pop(field_name, None) - if _field.default == data.get(field_name, None): + if _field.get_initial() == data.get(field_name, None): data.pop(field_name, None) if field_name.endswith("_set"): data.pop(field_name, None) return data +@dataclass +class BlueprintEntryState: + """State of a single instance""" + + instance: Optional[Model] = None + + @dataclass class BlueprintEntry: - """Single entry of a bundle""" + """Single entry of a blueprint""" identifiers: dict[str, Any] model: str @@ -45,11 +52,11 @@ class BlueprintEntry: # pylint: disable=invalid-name id: Optional[str] = None - _instance: Optional[Model] = None + _state: BlueprintEntryState = field(default_factory=BlueprintEntryState) @staticmethod def from_model(model: SerializerModel, *extra_identifier_names: str) -> "BlueprintEntry": - """Convert a SerializerModel instance to a Bundle Entry""" + """Convert a SerializerModel instance to a blueprint Entry""" identifiers = { "pk": model.pk, } @@ -123,15 +130,15 @@ class KeyOf(YAMLTag): def resolve(self, entry: BlueprintEntry, blueprint: Blueprint) -> Any: for _entry in blueprint.entries: - if _entry.id == self.id_from and _entry._instance: + if _entry.id == self.id_from and _entry._state.instance: # Special handling for PolicyBindingModels, as they'll have a different PK # which is used when creating policy bindings if ( - isinstance(_entry._instance, PolicyBindingModel) + isinstance(_entry._state.instance, PolicyBindingModel) and entry.model.lower() == "authentik_policies.policybinding" ): - return _entry._instance.pbm_uuid - return _entry._instance.pk + return _entry._state.instance.pbm_uuid + return _entry._state.instance.pk raise ValueError( f"KeyOf: failed to find entry with `id` of `{self.id_from}` and a model instance" ) diff --git a/authentik/blueprints/v1/importer.py b/authentik/blueprints/v1/importer.py index 2a844d22e..c4fc44a34 100644 --- a/authentik/blueprints/v1/importer.py +++ b/authentik/blueprints/v1/importer.py @@ -21,6 +21,7 @@ from yaml import load from authentik.blueprints.v1.common import ( Blueprint, BlueprintEntry, + BlueprintEntryState, BlueprintLoader, EntryInvalidError, ) @@ -220,7 +221,7 @@ class Importer: model = serializer.save() if "pk" in entry.identifiers: self.__pk_map[entry.identifiers["pk"]] = model.pk - entry._instance = model + entry._state = BlueprintEntryState(model) self.logger.debug("updated model", model=model, pk=model.pk) return True