From 816b0c7d83e54430dc45bea28cfe32d2ca36b51d Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Tue, 24 May 2022 23:32:00 +0200 Subject: [PATCH] flows: fix re-imports of entries with identical PK re-creating objects closes #2941 Signed-off-by: Jens Langhammer --- authentik/flows/tests/test_transfer.py | 32 +++++++++++++++++++ authentik/flows/transfer/importer.py | 7 +++- .../stages/authenticator_validate/stage.py | 5 --- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/authentik/flows/tests/test_transfer.py b/authentik/flows/tests/test_transfer.py index bf5d7efa8..4e6808c4a 100644 --- a/authentik/flows/tests/test_transfer.py +++ b/authentik/flows/tests/test_transfer.py @@ -13,6 +13,25 @@ from authentik.policies.models import PolicyBinding from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage from authentik.stages.user_login.models import UserLoginStage +STATIC_PROMPT_EXPORT = """{ + "version": 1, + "entries": [ + { + "identifiers": { + "pk": "cb954fd4-65a5-4ad9-b1ee-180ee9559cf4" + }, + "model": "authentik_stages_prompt.prompt", + "attrs": { + "field_key": "username", + "label": "Username", + "type": "username", + "required": true, + "placeholder": "Username", + "order": 0 + } + } + ] +}""" class TestFlowTransfer(TransactionTestCase): """Test flow transfer""" @@ -58,6 +77,19 @@ class TestFlowTransfer(TransactionTestCase): self.assertTrue(Flow.objects.filter(slug=flow_slug).exists()) + def test_export_validate_import_re_import(self): + """Test export and import it twice""" + importer = FlowImporter(STATIC_PROMPT_EXPORT) + self.assertTrue(importer.validate()) + self.assertTrue(importer.apply()) + + self.assertEqual(Prompt.objects.filter(field_key="username").count(), 1) + + importer = FlowImporter(STATIC_PROMPT_EXPORT) + self.assertTrue(importer.apply()) + + self.assertEqual(Prompt.objects.filter(field_key="username").count(), 1) + def test_export_validate_import_policies(self): """Test export and validate it""" flow_slug = generate_id() diff --git a/authentik/flows/transfer/importer.py b/authentik/flows/transfer/importer.py index f0e7f2298..dec5aae24 100644 --- a/authentik/flows/transfer/importer.py +++ b/authentik/flows/transfer/importer.py @@ -115,6 +115,11 @@ class FlowImporter: serializer_kwargs["instance"] = model_instance else: self.logger.debug("initialise new instance", model=model, **updated_identifiers) + model_instance = model() + # pk needs to be set on the model instance otherwise a new one will be generated + if "pk" in updated_identifiers: + model_instance.pk = updated_identifiers["pk"] + serializer_kwargs["instance"] = model_instance full_data = self.__update_pks_for_attrs(entry.attrs) full_data.update(updated_identifiers) serializer_kwargs["data"] = full_data @@ -167,7 +172,7 @@ class FlowImporter: def validate(self) -> bool: """Validate loaded flow export, ensure all models are allowed and serializers have no errors""" - self.logger.debug("Starting flow import validaton") + self.logger.debug("Starting flow import validation") if self.__import.version != 1: self.logger.warning("Invalid bundle version") return False diff --git a/authentik/stages/authenticator_validate/stage.py b/authentik/stages/authenticator_validate/stage.py index 2e9f43b35..bb6565454 100644 --- a/authentik/stages/authenticator_validate/stage.py +++ b/authentik/stages/authenticator_validate/stage.py @@ -168,11 +168,6 @@ class AuthenticatorValidateStageView(ChallengeStageView): continue # check if device has been used within threshold and skip this stage if so if threshold.total_seconds() > 0: - print("yeet") - print(get_device_last_usage(device)) - print(_now - get_device_last_usage(device)) - print(threshold) - print(_now - get_device_last_usage(device) <= threshold) if _now - get_device_last_usage(device) <= threshold: LOGGER.info("Device has been used within threshold", device=device) raise FlowSkipStageException()