authentik.flows.tests.test_stage_views
stage view tests
1"""stage view tests""" 2 3from collections.abc import Callable 4from unittest.mock import patch 5 6from django.test import RequestFactory, TestCase 7from django.urls import reverse 8 9from authentik.core.tests.utils import RequestFactory as AuthentikRequestFactory 10from authentik.core.tests.utils import create_test_flow 11from authentik.flows.models import Flow, FlowStageBinding 12from authentik.flows.stage import StageView 13from authentik.flows.views.executor import FlowExecutorView 14from authentik.lib.utils.reflection import all_subclasses 15from authentik.stages.dummy.models import DummyStage 16from authentik.stages.dummy.stage import DummyStageView 17 18 19class TestViews(TestCase): 20 """Generic model properties tests""" 21 22 def setUp(self) -> None: 23 self.factory = RequestFactory() 24 self.exec = FlowExecutorView(request=self.factory.get("/")) 25 self.authentik_factory = AuthentikRequestFactory() 26 27 def test_challenge_stage_flow_info_uses_relative_background(self): 28 """Test challenge flow info keeps background URLs app-relative.""" 29 flow = create_test_flow() 30 stage = DummyStage.objects.create(name="dummy") 31 FlowStageBinding.objects.create(target=flow, stage=stage, order=0) 32 request = self.authentik_factory.get("/") 33 34 executor = FlowExecutorView(flow=flow, request=request) 35 executor.current_stage = stage 36 37 view = DummyStageView(executor) 38 view.request = request 39 40 challenge = view._get_challenge() 41 42 self.assertEqual( 43 challenge.initial_data["flow_info"]["background"], 44 "/static/dist/assets/images/flow_background.jpg", 45 ) 46 47 def test_flow_interface_css_background_preserves_presigned_url_query(self): 48 """Test flow CSS keeps signed URL query separators intact.""" 49 flow = create_test_flow() 50 background_url = ( 51 "https://s3.ca-central-1.amazonaws.com/example/media/public/background.png" 52 "?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credential" 53 "&X-Amz-Signature=signature" 54 ) 55 56 with patch.object(Flow, "background_url", return_value=background_url): 57 response = self.client.get( 58 reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug}) 59 ) 60 61 self.assertContains( 62 response, 63 f'--ak-global--background-image: url("{background_url}");', 64 html=False, 65 ) 66 67 def test_flow_sfe_css_background_preserves_presigned_url_query(self): 68 """Test SFE flow CSS keeps signed URL query separators intact.""" 69 flow = create_test_flow() 70 background_url = ( 71 "https://s3.ca-central-1.amazonaws.com/example/media/public/background.png" 72 "?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credential" 73 "&X-Amz-Signature=signature" 74 ) 75 76 with patch.object(Flow, "background_url", return_value=background_url): 77 response = self.client.get( 78 reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug}) + "?sfe" 79 ) 80 81 self.assertContains( 82 response, 83 f'background-image: url("{background_url}");', 84 html=False, 85 ) 86 87 88def view_tester_factory(view_class: type[StageView]) -> Callable: 89 """Test a form""" 90 91 def tester(self: TestViews): 92 model_class = view_class(self.exec) 93 if not hasattr(model_class, "dispatch"): 94 self.assertIsNotNone(model_class.post) 95 self.assertIsNotNone(model_class.get) 96 97 return tester 98 99 100for view in all_subclasses(StageView): 101 setattr(TestViews, f"test_view_{view.__name__}", view_tester_factory(view))
20class TestViews(TestCase): 21 """Generic model properties tests""" 22 23 def setUp(self) -> None: 24 self.factory = RequestFactory() 25 self.exec = FlowExecutorView(request=self.factory.get("/")) 26 self.authentik_factory = AuthentikRequestFactory() 27 28 def test_challenge_stage_flow_info_uses_relative_background(self): 29 """Test challenge flow info keeps background URLs app-relative.""" 30 flow = create_test_flow() 31 stage = DummyStage.objects.create(name="dummy") 32 FlowStageBinding.objects.create(target=flow, stage=stage, order=0) 33 request = self.authentik_factory.get("/") 34 35 executor = FlowExecutorView(flow=flow, request=request) 36 executor.current_stage = stage 37 38 view = DummyStageView(executor) 39 view.request = request 40 41 challenge = view._get_challenge() 42 43 self.assertEqual( 44 challenge.initial_data["flow_info"]["background"], 45 "/static/dist/assets/images/flow_background.jpg", 46 ) 47 48 def test_flow_interface_css_background_preserves_presigned_url_query(self): 49 """Test flow CSS keeps signed URL query separators intact.""" 50 flow = create_test_flow() 51 background_url = ( 52 "https://s3.ca-central-1.amazonaws.com/example/media/public/background.png" 53 "?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credential" 54 "&X-Amz-Signature=signature" 55 ) 56 57 with patch.object(Flow, "background_url", return_value=background_url): 58 response = self.client.get( 59 reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug}) 60 ) 61 62 self.assertContains( 63 response, 64 f'--ak-global--background-image: url("{background_url}");', 65 html=False, 66 ) 67 68 def test_flow_sfe_css_background_preserves_presigned_url_query(self): 69 """Test SFE flow CSS keeps signed URL query separators intact.""" 70 flow = create_test_flow() 71 background_url = ( 72 "https://s3.ca-central-1.amazonaws.com/example/media/public/background.png" 73 "?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credential" 74 "&X-Amz-Signature=signature" 75 ) 76 77 with patch.object(Flow, "background_url", return_value=background_url): 78 response = self.client.get( 79 reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug}) + "?sfe" 80 ) 81 82 self.assertContains( 83 response, 84 f'background-image: url("{background_url}");', 85 html=False, 86 )
Generic model properties tests
23 def setUp(self) -> None: 24 self.factory = RequestFactory() 25 self.exec = FlowExecutorView(request=self.factory.get("/")) 26 self.authentik_factory = AuthentikRequestFactory()
Hook method for setting up the test fixture before exercising it.
28 def test_challenge_stage_flow_info_uses_relative_background(self): 29 """Test challenge flow info keeps background URLs app-relative.""" 30 flow = create_test_flow() 31 stage = DummyStage.objects.create(name="dummy") 32 FlowStageBinding.objects.create(target=flow, stage=stage, order=0) 33 request = self.authentik_factory.get("/") 34 35 executor = FlowExecutorView(flow=flow, request=request) 36 executor.current_stage = stage 37 38 view = DummyStageView(executor) 39 view.request = request 40 41 challenge = view._get_challenge() 42 43 self.assertEqual( 44 challenge.initial_data["flow_info"]["background"], 45 "/static/dist/assets/images/flow_background.jpg", 46 )
Test challenge flow info keeps background URLs app-relative.
48 def test_flow_interface_css_background_preserves_presigned_url_query(self): 49 """Test flow CSS keeps signed URL query separators intact.""" 50 flow = create_test_flow() 51 background_url = ( 52 "https://s3.ca-central-1.amazonaws.com/example/media/public/background.png" 53 "?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credential" 54 "&X-Amz-Signature=signature" 55 ) 56 57 with patch.object(Flow, "background_url", return_value=background_url): 58 response = self.client.get( 59 reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug}) 60 ) 61 62 self.assertContains( 63 response, 64 f'--ak-global--background-image: url("{background_url}");', 65 html=False, 66 )
Test flow CSS keeps signed URL query separators intact.
68 def test_flow_sfe_css_background_preserves_presigned_url_query(self): 69 """Test SFE flow CSS keeps signed URL query separators intact.""" 70 flow = create_test_flow() 71 background_url = ( 72 "https://s3.ca-central-1.amazonaws.com/example/media/public/background.png" 73 "?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credential" 74 "&X-Amz-Signature=signature" 75 ) 76 77 with patch.object(Flow, "background_url", return_value=background_url): 78 response = self.client.get( 79 reverse("authentik_core:if-flow", kwargs={"flow_slug": flow.slug}) + "?sfe" 80 ) 81 82 self.assertContains( 83 response, 84 f'background-image: url("{background_url}");', 85 html=False, 86 )
Test SFE flow CSS keeps signed URL query separators intact.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get)
The type of the None singleton.
89def view_tester_factory(view_class: type[StageView]) -> Callable: 90 """Test a form""" 91 92 def tester(self: TestViews): 93 model_class = view_class(self.exec) 94 if not hasattr(model_class, "dispatch"): 95 self.assertIsNotNone(model_class.post) 96 self.assertIsNotNone(model_class.get) 97 98 return tester
Test a form