authentik.flows.tests.test_api
API flow tests
1"""API flow tests""" 2 3from json import loads 4 5from django.urls import reverse 6from rest_framework.test import APITestCase 7 8from authentik.core.tests.utils import create_test_admin_user, create_test_flow 9from authentik.flows.api.stages import StageSerializer, StageViewSet 10from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, Stage 11from authentik.lib.generators import generate_id 12from authentik.policies.dummy.models import DummyPolicy 13from authentik.policies.models import PolicyBinding 14from authentik.stages.dummy.models import DummyStage 15 16DIAGRAM_EXPECTED = """graph TD 17flow_start[["Flow 18test-default-context"]] 19--> stage_0(["Stage (Dummy Stage) 20dummy1"]) 21stage_1_policy_0 --Policy passed--> stage_1(["Stage (Dummy Stage) 22dummy2"]) 23stage_0 --> stage_1_policy_0{{"Policy (Dummy Policy) 24dummy2-policy"}} 25stage_1 --> done[["End of the flow"]]""" 26DIAGRAM_SHORT_EXPECTED = """graph TD 27flow_start[["Flow 28test-default-context"]] 29flow_start --> done[["End of the flow"]]""" 30 31 32class TestFlowsAPI(APITestCase): 33 """API tests""" 34 35 def test_models(self): 36 """Test that ui_user_settings returns none""" 37 self.assertIsNone(Stage().ui_user_settings()) 38 39 def test_api_serializer(self): 40 """Test that stage serializer returns the correct type""" 41 obj = DummyStage() 42 self.assertEqual(StageSerializer().get_component(obj), "ak-stage-dummy-form") 43 self.assertEqual(StageSerializer().get_verbose_name(obj), "Dummy Stage") 44 45 def test_api_viewset(self): 46 """Test that stage serializer returns the correct type""" 47 dummy = DummyStage.objects.create() 48 self.assertIn(dummy, StageViewSet().get_queryset()) 49 50 def test_api_diagram(self): 51 """Test flow diagram.""" 52 user = create_test_admin_user() 53 self.client.force_login(user) 54 55 flow = Flow.objects.create( 56 name="test-default-context", 57 slug="test-default-context", 58 designation=FlowDesignation.AUTHENTICATION, 59 ) 60 false_policy = DummyPolicy.objects.create( 61 name="dummy2-policy", result=False, wait_min=1, wait_max=2 62 ) 63 64 FlowStageBinding.objects.create( 65 target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 66 ) 67 binding2 = FlowStageBinding.objects.create( 68 target=flow, 69 stage=DummyStage.objects.create(name="dummy2"), 70 order=1, 71 re_evaluate_policies=True, 72 ) 73 74 PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) 75 76 response = self.client.get( 77 reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) 78 ) 79 self.assertEqual(response.status_code, 200) 80 self.assertJSONEqual(response.content, {"diagram": DIAGRAM_EXPECTED}) 81 82 def test_api_background(self): 83 """Test custom background""" 84 user = create_test_admin_user() 85 self.client.force_login(user) 86 87 flow = create_test_flow() 88 response = self.client.get(reverse("authentik_api:flow-detail", kwargs={"slug": flow.slug})) 89 body = loads(response.content.decode()) 90 self.assertEqual(body["background_url"], "/static/dist/assets/images/flow_background.jpg") 91 92 flow.background = "https://goauthentik.io/img/icon.png" 93 flow.save() 94 response = self.client.get(reverse("authentik_api:flow-detail", kwargs={"slug": flow.slug})) 95 body = loads(response.content.decode()) 96 self.assertEqual(body["background"], "https://goauthentik.io/img/icon.png") 97 98 def test_api_diagram_no_stages(self): 99 """Test flow diagram with no stages.""" 100 user = create_test_admin_user() 101 self.client.force_login(user) 102 103 flow = Flow.objects.create( 104 name="test-default-context", 105 slug="test-default-context", 106 designation=FlowDesignation.AUTHENTICATION, 107 ) 108 response = self.client.get( 109 reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) 110 ) 111 self.assertEqual(response.status_code, 200) 112 self.assertJSONEqual(response.content, {"diagram": DIAGRAM_SHORT_EXPECTED}) 113 114 def test_types(self): 115 """Test Stage's types endpoint""" 116 user = create_test_admin_user() 117 self.client.force_login(user) 118 119 response = self.client.get( 120 reverse("authentik_api:stage-types"), 121 ) 122 self.assertEqual(response.status_code, 200) 123 124 def test_execute(self): 125 """Test execute endpoint""" 126 user = create_test_admin_user() 127 self.client.force_login(user) 128 129 flow = Flow.objects.create( 130 name=generate_id(), 131 slug=generate_id(), 132 designation=FlowDesignation.AUTHENTICATION, 133 ) 134 FlowStageBinding.objects.create( 135 target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 136 ) 137 response = self.client.get( 138 reverse("authentik_api:flow-execute", kwargs={"slug": flow.slug}) 139 ) 140 self.assertEqual(response.status_code, 200)
DIAGRAM_EXPECTED =
'graph TD\nflow_start[["Flow\ntest-default-context"]]\n--> stage_0(["Stage (Dummy Stage)\ndummy1"])\nstage_1_policy_0 --Policy passed--> stage_1(["Stage (Dummy Stage)\ndummy2"])\nstage_0 --> stage_1_policy_0{{"Policy (Dummy Policy)\ndummy2-policy"}}\nstage_1 --> done[["End of the flow"]]'
DIAGRAM_SHORT_EXPECTED =
'graph TD\nflow_start[["Flow\ntest-default-context"]]\nflow_start --> done[["End of the flow"]]'
class
TestFlowsAPI(rest_framework.test.APITestCase):
33class TestFlowsAPI(APITestCase): 34 """API tests""" 35 36 def test_models(self): 37 """Test that ui_user_settings returns none""" 38 self.assertIsNone(Stage().ui_user_settings()) 39 40 def test_api_serializer(self): 41 """Test that stage serializer returns the correct type""" 42 obj = DummyStage() 43 self.assertEqual(StageSerializer().get_component(obj), "ak-stage-dummy-form") 44 self.assertEqual(StageSerializer().get_verbose_name(obj), "Dummy Stage") 45 46 def test_api_viewset(self): 47 """Test that stage serializer returns the correct type""" 48 dummy = DummyStage.objects.create() 49 self.assertIn(dummy, StageViewSet().get_queryset()) 50 51 def test_api_diagram(self): 52 """Test flow diagram.""" 53 user = create_test_admin_user() 54 self.client.force_login(user) 55 56 flow = Flow.objects.create( 57 name="test-default-context", 58 slug="test-default-context", 59 designation=FlowDesignation.AUTHENTICATION, 60 ) 61 false_policy = DummyPolicy.objects.create( 62 name="dummy2-policy", result=False, wait_min=1, wait_max=2 63 ) 64 65 FlowStageBinding.objects.create( 66 target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 67 ) 68 binding2 = FlowStageBinding.objects.create( 69 target=flow, 70 stage=DummyStage.objects.create(name="dummy2"), 71 order=1, 72 re_evaluate_policies=True, 73 ) 74 75 PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) 76 77 response = self.client.get( 78 reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) 79 ) 80 self.assertEqual(response.status_code, 200) 81 self.assertJSONEqual(response.content, {"diagram": DIAGRAM_EXPECTED}) 82 83 def test_api_background(self): 84 """Test custom background""" 85 user = create_test_admin_user() 86 self.client.force_login(user) 87 88 flow = create_test_flow() 89 response = self.client.get(reverse("authentik_api:flow-detail", kwargs={"slug": flow.slug})) 90 body = loads(response.content.decode()) 91 self.assertEqual(body["background_url"], "/static/dist/assets/images/flow_background.jpg") 92 93 flow.background = "https://goauthentik.io/img/icon.png" 94 flow.save() 95 response = self.client.get(reverse("authentik_api:flow-detail", kwargs={"slug": flow.slug})) 96 body = loads(response.content.decode()) 97 self.assertEqual(body["background"], "https://goauthentik.io/img/icon.png") 98 99 def test_api_diagram_no_stages(self): 100 """Test flow diagram with no stages.""" 101 user = create_test_admin_user() 102 self.client.force_login(user) 103 104 flow = Flow.objects.create( 105 name="test-default-context", 106 slug="test-default-context", 107 designation=FlowDesignation.AUTHENTICATION, 108 ) 109 response = self.client.get( 110 reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) 111 ) 112 self.assertEqual(response.status_code, 200) 113 self.assertJSONEqual(response.content, {"diagram": DIAGRAM_SHORT_EXPECTED}) 114 115 def test_types(self): 116 """Test Stage's types endpoint""" 117 user = create_test_admin_user() 118 self.client.force_login(user) 119 120 response = self.client.get( 121 reverse("authentik_api:stage-types"), 122 ) 123 self.assertEqual(response.status_code, 200) 124 125 def test_execute(self): 126 """Test execute endpoint""" 127 user = create_test_admin_user() 128 self.client.force_login(user) 129 130 flow = Flow.objects.create( 131 name=generate_id(), 132 slug=generate_id(), 133 designation=FlowDesignation.AUTHENTICATION, 134 ) 135 FlowStageBinding.objects.create( 136 target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 137 ) 138 response = self.client.get( 139 reverse("authentik_api:flow-execute", kwargs={"slug": flow.slug}) 140 ) 141 self.assertEqual(response.status_code, 200)
API tests
def
test_models(self):
36 def test_models(self): 37 """Test that ui_user_settings returns none""" 38 self.assertIsNone(Stage().ui_user_settings())
Test that ui_user_settings returns none
def
test_api_serializer(self):
40 def test_api_serializer(self): 41 """Test that stage serializer returns the correct type""" 42 obj = DummyStage() 43 self.assertEqual(StageSerializer().get_component(obj), "ak-stage-dummy-form") 44 self.assertEqual(StageSerializer().get_verbose_name(obj), "Dummy Stage")
Test that stage serializer returns the correct type
def
test_api_viewset(self):
46 def test_api_viewset(self): 47 """Test that stage serializer returns the correct type""" 48 dummy = DummyStage.objects.create() 49 self.assertIn(dummy, StageViewSet().get_queryset())
Test that stage serializer returns the correct type
def
test_api_diagram(self):
51 def test_api_diagram(self): 52 """Test flow diagram.""" 53 user = create_test_admin_user() 54 self.client.force_login(user) 55 56 flow = Flow.objects.create( 57 name="test-default-context", 58 slug="test-default-context", 59 designation=FlowDesignation.AUTHENTICATION, 60 ) 61 false_policy = DummyPolicy.objects.create( 62 name="dummy2-policy", result=False, wait_min=1, wait_max=2 63 ) 64 65 FlowStageBinding.objects.create( 66 target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 67 ) 68 binding2 = FlowStageBinding.objects.create( 69 target=flow, 70 stage=DummyStage.objects.create(name="dummy2"), 71 order=1, 72 re_evaluate_policies=True, 73 ) 74 75 PolicyBinding.objects.create(policy=false_policy, target=binding2, order=0) 76 77 response = self.client.get( 78 reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) 79 ) 80 self.assertEqual(response.status_code, 200) 81 self.assertJSONEqual(response.content, {"diagram": DIAGRAM_EXPECTED})
Test flow diagram.
def
test_api_background(self):
83 def test_api_background(self): 84 """Test custom background""" 85 user = create_test_admin_user() 86 self.client.force_login(user) 87 88 flow = create_test_flow() 89 response = self.client.get(reverse("authentik_api:flow-detail", kwargs={"slug": flow.slug})) 90 body = loads(response.content.decode()) 91 self.assertEqual(body["background_url"], "/static/dist/assets/images/flow_background.jpg") 92 93 flow.background = "https://goauthentik.io/img/icon.png" 94 flow.save() 95 response = self.client.get(reverse("authentik_api:flow-detail", kwargs={"slug": flow.slug})) 96 body = loads(response.content.decode()) 97 self.assertEqual(body["background"], "https://goauthentik.io/img/icon.png")
Test custom background
def
test_api_diagram_no_stages(self):
99 def test_api_diagram_no_stages(self): 100 """Test flow diagram with no stages.""" 101 user = create_test_admin_user() 102 self.client.force_login(user) 103 104 flow = Flow.objects.create( 105 name="test-default-context", 106 slug="test-default-context", 107 designation=FlowDesignation.AUTHENTICATION, 108 ) 109 response = self.client.get( 110 reverse("authentik_api:flow-diagram", kwargs={"slug": flow.slug}) 111 ) 112 self.assertEqual(response.status_code, 200) 113 self.assertJSONEqual(response.content, {"diagram": DIAGRAM_SHORT_EXPECTED})
Test flow diagram with no stages.
def
test_types(self):
115 def test_types(self): 116 """Test Stage's types endpoint""" 117 user = create_test_admin_user() 118 self.client.force_login(user) 119 120 response = self.client.get( 121 reverse("authentik_api:stage-types"), 122 ) 123 self.assertEqual(response.status_code, 200)
Test Stage's types endpoint
def
test_execute(self):
125 def test_execute(self): 126 """Test execute endpoint""" 127 user = create_test_admin_user() 128 self.client.force_login(user) 129 130 flow = Flow.objects.create( 131 name=generate_id(), 132 slug=generate_id(), 133 designation=FlowDesignation.AUTHENTICATION, 134 ) 135 FlowStageBinding.objects.create( 136 target=flow, stage=DummyStage.objects.create(name=generate_id()), order=0 137 ) 138 response = self.client.get( 139 reverse("authentik_api:flow-execute", kwargs={"slug": flow.slug}) 140 ) 141 self.assertEqual(response.status_code, 200)
Test execute endpoint