authentik.blueprints.tests.test_v1
Test blueprints v1
1"""Test blueprints v1""" 2 3from os import chmod, environ, unlink, write 4from tempfile import mkstemp 5 6from django.test import TransactionTestCase 7 8from authentik.blueprints.tests import apply_blueprint 9from authentik.blueprints.v1.exporter import FlowExporter 10from authentik.blueprints.v1.importer import Importer, transaction_rollback 11from authentik.core.models import Group 12from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding 13from authentik.lib.generators import generate_id 14from authentik.lib.tests.utils import load_fixture 15from authentik.policies.expression.models import ExpressionPolicy 16from authentik.policies.models import PolicyBinding 17from authentik.sources.oauth.models import OAuthSource 18from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage 19from authentik.stages.user_login.models import UserLoginStage 20 21 22class TestBlueprintsV1(TransactionTestCase): 23 """Test Blueprints""" 24 25 def test_blueprint_invalid_format(self): 26 """Test blueprint with invalid format""" 27 importer = Importer.from_string('{"version": 3}') 28 self.assertFalse(importer.validate()[0]) 29 importer = Importer.from_string( 30 '{"version": 1,"entries":[{"identifiers":{},"attrs":{},' 31 '"model": "authentik_core.User"}]}' 32 ) 33 self.assertFalse(importer.validate()[0]) 34 importer = Importer.from_string( 35 '{"version": 1, "entries": [{"attrs": {"name": "test"}, ' 36 '"identifiers": {}, ' 37 '"model": "authentik_core.Group"}]}' 38 ) 39 self.assertFalse(importer.validate()[0]) 40 41 def test_validated_import_dict_identifiers(self): 42 """Test importing blueprints with dict identifiers.""" 43 Group.objects.filter(name__istartswith="test").delete() 44 45 Group.objects.create( 46 name="test1", 47 attributes={ 48 "key": ["value"], 49 "other_key": ["a_value", "other_value"], 50 }, 51 ) 52 Group.objects.create( 53 name="test2", 54 attributes={ 55 "key": ["value"], 56 "other_key": ["diff_value", "other_diff_value"], 57 }, 58 ) 59 60 importer = Importer.from_string( 61 '{"version": 1, "entries": [{"attrs": {"name": "test999", "attributes": ' 62 '{"key": ["updated_value"]}}, "identifiers": {"attributes": {"other_key": ' 63 '["other_value"]}}, "model": "authentik_core.Group"}]}' 64 ) 65 self.assertTrue(importer.validate()[0]) 66 self.assertTrue(importer.apply()) 67 self.assertTrue( 68 Group.objects.filter( 69 name="test2", 70 attributes={ 71 "key": ["value"], 72 "other_key": ["diff_value", "other_diff_value"], 73 }, 74 ) 75 ) 76 self.assertTrue( 77 Group.objects.filter( 78 name="test999", 79 # All attributes used as identifiers are kept and merged with the 80 # new attributes declared in the blueprint 81 attributes={"key": ["updated_value"], "other_key": ["other_value"]}, 82 ) 83 ) 84 self.assertFalse(Group.objects.filter(name="test1")) 85 86 def test_export_validate_import(self): 87 """Test export and validate it""" 88 flow_slug = generate_id() 89 with transaction_rollback(): 90 login_stage = UserLoginStage.objects.create(name=generate_id()) 91 92 flow = Flow.objects.create( 93 slug=flow_slug, 94 designation=FlowDesignation.AUTHENTICATION, 95 name=generate_id(), 96 title=generate_id(), 97 ) 98 FlowStageBinding.objects.update_or_create( 99 target=flow, 100 stage=login_stage, 101 order=0, 102 ) 103 104 exporter = FlowExporter(flow) 105 export = exporter.export() 106 self.assertEqual(len(export.entries), 3) 107 export_yaml = exporter.export_to_string() 108 109 importer = Importer.from_string(export_yaml) 110 self.assertTrue(importer.validate()[0]) 111 self.assertTrue(importer.apply()) 112 113 self.assertTrue(Flow.objects.filter(slug=flow_slug).exists()) 114 115 def test_export_validate_import_re_import(self): 116 """Test export and import it twice""" 117 count_initial = Prompt.objects.filter(field_key="username").count() 118 119 importer = Importer.from_string(load_fixture("fixtures/static_prompt_export.yaml")) 120 self.assertTrue(importer.validate()[0]) 121 self.assertTrue(importer.apply()) 122 123 count_before = Prompt.objects.filter(field_key="username").count() 124 self.assertEqual(count_initial + 1, count_before) 125 126 importer = Importer.from_string(load_fixture("fixtures/static_prompt_export.yaml")) 127 self.assertTrue(importer.apply()) 128 129 self.assertEqual(Prompt.objects.filter(field_key="username").count(), count_before) 130 131 @apply_blueprint("system/providers-oauth2.yaml") 132 def test_import_yaml_tags(self): 133 """Test some yaml tags""" 134 ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").delete() 135 Group.objects.filter(name="test").delete() 136 environ["foo"] = generate_id() 137 file, file_name = mkstemp() 138 write(file, b"foo") 139 _, file_default_name = mkstemp() 140 chmod(file_default_name, 0o000) # Remove all permissions so we can't read the file 141 importer = Importer.from_string( 142 load_fixture( 143 "fixtures/tags.yaml", 144 file_name=file_name, 145 file_default_name=file_default_name, 146 ), 147 {"bar": "baz"}, 148 ) 149 self.assertTrue(importer.validate()[0]) 150 self.assertTrue(importer.apply()) 151 policy = ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").first() 152 self.assertTrue(policy) 153 group = Group.objects.filter(name="test").first() 154 self.assertIsNotNone(group) 155 self.assertEqual( 156 group.attributes, 157 { 158 "policy_pk1": str(policy.pk) + "-suffix", 159 "policy_pk2": str(policy.pk) + "-suffix", 160 "boolAnd": True, 161 "boolNand": False, 162 "boolOr": True, 163 "boolNor": False, 164 "boolXor": True, 165 "boolXnor": False, 166 "boolComplex": True, 167 "if_true_complex": { 168 "dictionary": { 169 "with": {"keys": "and_values"}, 170 "and_nested_custom_tags": "foo-bar", 171 } 172 }, 173 "if_false_complex": ["list", "with", "items", "foo-bar"], 174 "if_true_simple": True, 175 "if_short": True, 176 "if_false_simple": 2, 177 "enumerate_mapping_to_mapping": { 178 "prefix-key1": "other-prefix-value", 179 "prefix-key2": "other-prefix-2", 180 }, 181 "enumerate_mapping_to_sequence": [ 182 "prefixed-pair-key1-value", 183 "prefixed-pair-key2-2", 184 ], 185 "enumerate_sequence_to_sequence": [ 186 "prefixed-items-0-foo", 187 "prefixed-items-1-bar", 188 ], 189 "enumerate_sequence_to_mapping": {"index: 0": "foo", "index: 1": "bar"}, 190 "nested_complex_enumeration": { 191 "0": { 192 "key1": [ 193 ["prefixed-f", "prefixed-o", "prefixed-o"], 194 { 195 "outer_value": "foo", 196 "outer_index": 0, 197 "middle_value": "value", 198 "middle_index": "key1", 199 }, 200 ], 201 "key2": [ 202 ["prefixed-f", "prefixed-o", "prefixed-o"], 203 { 204 "outer_value": "foo", 205 "outer_index": 0, 206 "middle_value": 2, 207 "middle_index": "key2", 208 }, 209 ], 210 }, 211 "1": { 212 "key1": [ 213 ["prefixed-b", "prefixed-a", "prefixed-r"], 214 { 215 "outer_value": "bar", 216 "outer_index": 1, 217 "middle_value": "value", 218 "middle_index": "key1", 219 }, 220 ], 221 "key2": [ 222 ["prefixed-b", "prefixed-a", "prefixed-r"], 223 { 224 "outer_value": "bar", 225 "outer_index": 1, 226 "middle_value": 2, 227 "middle_index": "key2", 228 }, 229 ], 230 }, 231 }, 232 "nested_context": "context-nested-value", 233 "env_null": None, 234 "file_content": "foo", 235 "file_default": "default", 236 "file_non_existent": None, 237 "json_parse": {"foo": "bar"}, 238 "at_index_sequence": "foo", 239 "at_index_sequence_default": "non existent", 240 "at_index_mapping": 2, 241 "at_index_mapping_default": "non existent", 242 "find_object": "goauthentik.io/providers/oauth2/scope-openid", 243 }, 244 ) 245 self.assertTrue( 246 OAuthSource.objects.filter( 247 slug="test", 248 consumer_key=environ["foo"], 249 ) 250 ) 251 unlink(file_name) 252 unlink(file_default_name) 253 254 def test_export_validate_import_policies(self): 255 """Test export and validate it""" 256 flow_slug = generate_id() 257 stage_name = generate_id() 258 with transaction_rollback(): 259 flow_policy = ExpressionPolicy.objects.create( 260 name=generate_id(), 261 expression="return True", 262 ) 263 flow = Flow.objects.create( 264 slug=flow_slug, 265 designation=FlowDesignation.AUTHENTICATION, 266 name=generate_id(), 267 title=generate_id(), 268 ) 269 PolicyBinding.objects.create(policy=flow_policy, target=flow, order=0) 270 271 user_login = UserLoginStage.objects.create(name=stage_name) 272 fsb = FlowStageBinding.objects.create(target=flow, stage=user_login, order=0) 273 PolicyBinding.objects.create(policy=flow_policy, target=fsb, order=0) 274 275 exporter = FlowExporter(flow) 276 export_yaml = exporter.export_to_string() 277 278 importer = Importer.from_string(export_yaml) 279 self.assertTrue(importer.validate()[0]) 280 self.assertTrue(importer.apply()) 281 self.assertTrue(UserLoginStage.objects.filter(name=stage_name).exists()) 282 self.assertTrue(Flow.objects.filter(slug=flow_slug).exists()) 283 284 def test_export_validate_import_prompt(self): 285 """Test export and validate it""" 286 with transaction_rollback(): 287 # First stage fields 288 username_prompt = Prompt.objects.create( 289 name=generate_id(), 290 field_key="username", 291 label="Username", 292 order=0, 293 type=FieldTypes.TEXT, 294 ) 295 password = Prompt.objects.create( 296 name=generate_id(), 297 field_key="password", 298 label="Password", 299 order=1, 300 type=FieldTypes.PASSWORD, 301 ) 302 password_repeat = Prompt.objects.create( 303 name=generate_id(), 304 field_key="password_repeat", 305 label="Password (repeat)", 306 order=2, 307 type=FieldTypes.PASSWORD, 308 ) 309 310 # Stages 311 first_stage = PromptStage.objects.create(name=generate_id()) 312 first_stage.fields.set([username_prompt, password, password_repeat]) 313 first_stage.save() 314 315 flow = Flow.objects.create( 316 name=generate_id(), 317 slug=generate_id(), 318 designation=FlowDesignation.ENROLLMENT, 319 title=generate_id(), 320 ) 321 322 FlowStageBinding.objects.create(target=flow, stage=first_stage, order=0) 323 324 exporter = FlowExporter(flow) 325 export_yaml = exporter.export_to_string() 326 327 importer = Importer.from_string(export_yaml) 328 329 self.assertTrue(importer.validate()[0]) 330 self.assertTrue(importer.apply())
class
TestBlueprintsV1(django.test.testcases.TransactionTestCase):
23class TestBlueprintsV1(TransactionTestCase): 24 """Test Blueprints""" 25 26 def test_blueprint_invalid_format(self): 27 """Test blueprint with invalid format""" 28 importer = Importer.from_string('{"version": 3}') 29 self.assertFalse(importer.validate()[0]) 30 importer = Importer.from_string( 31 '{"version": 1,"entries":[{"identifiers":{},"attrs":{},' 32 '"model": "authentik_core.User"}]}' 33 ) 34 self.assertFalse(importer.validate()[0]) 35 importer = Importer.from_string( 36 '{"version": 1, "entries": [{"attrs": {"name": "test"}, ' 37 '"identifiers": {}, ' 38 '"model": "authentik_core.Group"}]}' 39 ) 40 self.assertFalse(importer.validate()[0]) 41 42 def test_validated_import_dict_identifiers(self): 43 """Test importing blueprints with dict identifiers.""" 44 Group.objects.filter(name__istartswith="test").delete() 45 46 Group.objects.create( 47 name="test1", 48 attributes={ 49 "key": ["value"], 50 "other_key": ["a_value", "other_value"], 51 }, 52 ) 53 Group.objects.create( 54 name="test2", 55 attributes={ 56 "key": ["value"], 57 "other_key": ["diff_value", "other_diff_value"], 58 }, 59 ) 60 61 importer = Importer.from_string( 62 '{"version": 1, "entries": [{"attrs": {"name": "test999", "attributes": ' 63 '{"key": ["updated_value"]}}, "identifiers": {"attributes": {"other_key": ' 64 '["other_value"]}}, "model": "authentik_core.Group"}]}' 65 ) 66 self.assertTrue(importer.validate()[0]) 67 self.assertTrue(importer.apply()) 68 self.assertTrue( 69 Group.objects.filter( 70 name="test2", 71 attributes={ 72 "key": ["value"], 73 "other_key": ["diff_value", "other_diff_value"], 74 }, 75 ) 76 ) 77 self.assertTrue( 78 Group.objects.filter( 79 name="test999", 80 # All attributes used as identifiers are kept and merged with the 81 # new attributes declared in the blueprint 82 attributes={"key": ["updated_value"], "other_key": ["other_value"]}, 83 ) 84 ) 85 self.assertFalse(Group.objects.filter(name="test1")) 86 87 def test_export_validate_import(self): 88 """Test export and validate it""" 89 flow_slug = generate_id() 90 with transaction_rollback(): 91 login_stage = UserLoginStage.objects.create(name=generate_id()) 92 93 flow = Flow.objects.create( 94 slug=flow_slug, 95 designation=FlowDesignation.AUTHENTICATION, 96 name=generate_id(), 97 title=generate_id(), 98 ) 99 FlowStageBinding.objects.update_or_create( 100 target=flow, 101 stage=login_stage, 102 order=0, 103 ) 104 105 exporter = FlowExporter(flow) 106 export = exporter.export() 107 self.assertEqual(len(export.entries), 3) 108 export_yaml = exporter.export_to_string() 109 110 importer = Importer.from_string(export_yaml) 111 self.assertTrue(importer.validate()[0]) 112 self.assertTrue(importer.apply()) 113 114 self.assertTrue(Flow.objects.filter(slug=flow_slug).exists()) 115 116 def test_export_validate_import_re_import(self): 117 """Test export and import it twice""" 118 count_initial = Prompt.objects.filter(field_key="username").count() 119 120 importer = Importer.from_string(load_fixture("fixtures/static_prompt_export.yaml")) 121 self.assertTrue(importer.validate()[0]) 122 self.assertTrue(importer.apply()) 123 124 count_before = Prompt.objects.filter(field_key="username").count() 125 self.assertEqual(count_initial + 1, count_before) 126 127 importer = Importer.from_string(load_fixture("fixtures/static_prompt_export.yaml")) 128 self.assertTrue(importer.apply()) 129 130 self.assertEqual(Prompt.objects.filter(field_key="username").count(), count_before) 131 132 @apply_blueprint("system/providers-oauth2.yaml") 133 def test_import_yaml_tags(self): 134 """Test some yaml tags""" 135 ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").delete() 136 Group.objects.filter(name="test").delete() 137 environ["foo"] = generate_id() 138 file, file_name = mkstemp() 139 write(file, b"foo") 140 _, file_default_name = mkstemp() 141 chmod(file_default_name, 0o000) # Remove all permissions so we can't read the file 142 importer = Importer.from_string( 143 load_fixture( 144 "fixtures/tags.yaml", 145 file_name=file_name, 146 file_default_name=file_default_name, 147 ), 148 {"bar": "baz"}, 149 ) 150 self.assertTrue(importer.validate()[0]) 151 self.assertTrue(importer.apply()) 152 policy = ExpressionPolicy.objects.filter(name="foo-bar-baz-qux").first() 153 self.assertTrue(policy) 154 group = Group.objects.filter(name="test").first() 155 self.assertIsNotNone(group) 156 self.assertEqual( 157 group.attributes, 158 { 159 "policy_pk1": str(policy.pk) + "-suffix", 160 "policy_pk2": str(policy.pk) + "-suffix", 161 "boolAnd": True, 162 "boolNand": False, 163 "boolOr": True, 164 "boolNor": False, 165 "boolXor": True, 166 "boolXnor": False, 167 "boolComplex": True, 168 "if_true_complex": { 169 "dictionary": { 170 "with": {"keys": "and_values"}, 171 "and_nested_custom_tags": "foo-bar", 172 } 173 }, 174 "if_false_complex": ["list", "with", "items", "foo-bar"], 175 "if_true_simple": True, 176 "if_short": True, 177 "if_false_simple": 2, 178 "enumerate_mapping_to_mapping": { 179 "prefix-key1": "other-prefix-value", 180 "prefix-key2": "other-prefix-2", 181 }, 182 "enumerate_mapping_to_sequence": [ 183 "prefixed-pair-key1-value", 184 "prefixed-pair-key2-2", 185 ], 186 "enumerate_sequence_to_sequence": [ 187 "prefixed-items-0-foo", 188 "prefixed-items-1-bar", 189 ], 190 "enumerate_sequence_to_mapping": {"index: 0": "foo", "index: 1": "bar"}, 191 "nested_complex_enumeration": { 192 "0": { 193 "key1": [ 194 ["prefixed-f", "prefixed-o", "prefixed-o"], 195 { 196 "outer_value": "foo", 197 "outer_index": 0, 198 "middle_value": "value", 199 "middle_index": "key1", 200 }, 201 ], 202 "key2": [ 203 ["prefixed-f", "prefixed-o", "prefixed-o"], 204 { 205 "outer_value": "foo", 206 "outer_index": 0, 207 "middle_value": 2, 208 "middle_index": "key2", 209 }, 210 ], 211 }, 212 "1": { 213 "key1": [ 214 ["prefixed-b", "prefixed-a", "prefixed-r"], 215 { 216 "outer_value": "bar", 217 "outer_index": 1, 218 "middle_value": "value", 219 "middle_index": "key1", 220 }, 221 ], 222 "key2": [ 223 ["prefixed-b", "prefixed-a", "prefixed-r"], 224 { 225 "outer_value": "bar", 226 "outer_index": 1, 227 "middle_value": 2, 228 "middle_index": "key2", 229 }, 230 ], 231 }, 232 }, 233 "nested_context": "context-nested-value", 234 "env_null": None, 235 "file_content": "foo", 236 "file_default": "default", 237 "file_non_existent": None, 238 "json_parse": {"foo": "bar"}, 239 "at_index_sequence": "foo", 240 "at_index_sequence_default": "non existent", 241 "at_index_mapping": 2, 242 "at_index_mapping_default": "non existent", 243 "find_object": "goauthentik.io/providers/oauth2/scope-openid", 244 }, 245 ) 246 self.assertTrue( 247 OAuthSource.objects.filter( 248 slug="test", 249 consumer_key=environ["foo"], 250 ) 251 ) 252 unlink(file_name) 253 unlink(file_default_name) 254 255 def test_export_validate_import_policies(self): 256 """Test export and validate it""" 257 flow_slug = generate_id() 258 stage_name = generate_id() 259 with transaction_rollback(): 260 flow_policy = ExpressionPolicy.objects.create( 261 name=generate_id(), 262 expression="return True", 263 ) 264 flow = Flow.objects.create( 265 slug=flow_slug, 266 designation=FlowDesignation.AUTHENTICATION, 267 name=generate_id(), 268 title=generate_id(), 269 ) 270 PolicyBinding.objects.create(policy=flow_policy, target=flow, order=0) 271 272 user_login = UserLoginStage.objects.create(name=stage_name) 273 fsb = FlowStageBinding.objects.create(target=flow, stage=user_login, order=0) 274 PolicyBinding.objects.create(policy=flow_policy, target=fsb, order=0) 275 276 exporter = FlowExporter(flow) 277 export_yaml = exporter.export_to_string() 278 279 importer = Importer.from_string(export_yaml) 280 self.assertTrue(importer.validate()[0]) 281 self.assertTrue(importer.apply()) 282 self.assertTrue(UserLoginStage.objects.filter(name=stage_name).exists()) 283 self.assertTrue(Flow.objects.filter(slug=flow_slug).exists()) 284 285 def test_export_validate_import_prompt(self): 286 """Test export and validate it""" 287 with transaction_rollback(): 288 # First stage fields 289 username_prompt = Prompt.objects.create( 290 name=generate_id(), 291 field_key="username", 292 label="Username", 293 order=0, 294 type=FieldTypes.TEXT, 295 ) 296 password = Prompt.objects.create( 297 name=generate_id(), 298 field_key="password", 299 label="Password", 300 order=1, 301 type=FieldTypes.PASSWORD, 302 ) 303 password_repeat = Prompt.objects.create( 304 name=generate_id(), 305 field_key="password_repeat", 306 label="Password (repeat)", 307 order=2, 308 type=FieldTypes.PASSWORD, 309 ) 310 311 # Stages 312 first_stage = PromptStage.objects.create(name=generate_id()) 313 first_stage.fields.set([username_prompt, password, password_repeat]) 314 first_stage.save() 315 316 flow = Flow.objects.create( 317 name=generate_id(), 318 slug=generate_id(), 319 designation=FlowDesignation.ENROLLMENT, 320 title=generate_id(), 321 ) 322 323 FlowStageBinding.objects.create(target=flow, stage=first_stage, order=0) 324 325 exporter = FlowExporter(flow) 326 export_yaml = exporter.export_to_string() 327 328 importer = Importer.from_string(export_yaml) 329 330 self.assertTrue(importer.validate()[0]) 331 self.assertTrue(importer.apply())
Test Blueprints
def
test_blueprint_invalid_format(self):
26 def test_blueprint_invalid_format(self): 27 """Test blueprint with invalid format""" 28 importer = Importer.from_string('{"version": 3}') 29 self.assertFalse(importer.validate()[0]) 30 importer = Importer.from_string( 31 '{"version": 1,"entries":[{"identifiers":{},"attrs":{},' 32 '"model": "authentik_core.User"}]}' 33 ) 34 self.assertFalse(importer.validate()[0]) 35 importer = Importer.from_string( 36 '{"version": 1, "entries": [{"attrs": {"name": "test"}, ' 37 '"identifiers": {}, ' 38 '"model": "authentik_core.Group"}]}' 39 ) 40 self.assertFalse(importer.validate()[0])
Test blueprint with invalid format
def
test_validated_import_dict_identifiers(self):
42 def test_validated_import_dict_identifiers(self): 43 """Test importing blueprints with dict identifiers.""" 44 Group.objects.filter(name__istartswith="test").delete() 45 46 Group.objects.create( 47 name="test1", 48 attributes={ 49 "key": ["value"], 50 "other_key": ["a_value", "other_value"], 51 }, 52 ) 53 Group.objects.create( 54 name="test2", 55 attributes={ 56 "key": ["value"], 57 "other_key": ["diff_value", "other_diff_value"], 58 }, 59 ) 60 61 importer = Importer.from_string( 62 '{"version": 1, "entries": [{"attrs": {"name": "test999", "attributes": ' 63 '{"key": ["updated_value"]}}, "identifiers": {"attributes": {"other_key": ' 64 '["other_value"]}}, "model": "authentik_core.Group"}]}' 65 ) 66 self.assertTrue(importer.validate()[0]) 67 self.assertTrue(importer.apply()) 68 self.assertTrue( 69 Group.objects.filter( 70 name="test2", 71 attributes={ 72 "key": ["value"], 73 "other_key": ["diff_value", "other_diff_value"], 74 }, 75 ) 76 ) 77 self.assertTrue( 78 Group.objects.filter( 79 name="test999", 80 # All attributes used as identifiers are kept and merged with the 81 # new attributes declared in the blueprint 82 attributes={"key": ["updated_value"], "other_key": ["other_value"]}, 83 ) 84 ) 85 self.assertFalse(Group.objects.filter(name="test1"))
Test importing blueprints with dict identifiers.
def
test_export_validate_import(self):
87 def test_export_validate_import(self): 88 """Test export and validate it""" 89 flow_slug = generate_id() 90 with transaction_rollback(): 91 login_stage = UserLoginStage.objects.create(name=generate_id()) 92 93 flow = Flow.objects.create( 94 slug=flow_slug, 95 designation=FlowDesignation.AUTHENTICATION, 96 name=generate_id(), 97 title=generate_id(), 98 ) 99 FlowStageBinding.objects.update_or_create( 100 target=flow, 101 stage=login_stage, 102 order=0, 103 ) 104 105 exporter = FlowExporter(flow) 106 export = exporter.export() 107 self.assertEqual(len(export.entries), 3) 108 export_yaml = exporter.export_to_string() 109 110 importer = Importer.from_string(export_yaml) 111 self.assertTrue(importer.validate()[0]) 112 self.assertTrue(importer.apply()) 113 114 self.assertTrue(Flow.objects.filter(slug=flow_slug).exists())
Test export and validate it
def
test_export_validate_import_re_import(self):
116 def test_export_validate_import_re_import(self): 117 """Test export and import it twice""" 118 count_initial = Prompt.objects.filter(field_key="username").count() 119 120 importer = Importer.from_string(load_fixture("fixtures/static_prompt_export.yaml")) 121 self.assertTrue(importer.validate()[0]) 122 self.assertTrue(importer.apply()) 123 124 count_before = Prompt.objects.filter(field_key="username").count() 125 self.assertEqual(count_initial + 1, count_before) 126 127 importer = Importer.from_string(load_fixture("fixtures/static_prompt_export.yaml")) 128 self.assertTrue(importer.apply()) 129 130 self.assertEqual(Prompt.objects.filter(field_key="username").count(), count_before)
Test export and import it twice
def
test_export_validate_import_policies(self):
255 def test_export_validate_import_policies(self): 256 """Test export and validate it""" 257 flow_slug = generate_id() 258 stage_name = generate_id() 259 with transaction_rollback(): 260 flow_policy = ExpressionPolicy.objects.create( 261 name=generate_id(), 262 expression="return True", 263 ) 264 flow = Flow.objects.create( 265 slug=flow_slug, 266 designation=FlowDesignation.AUTHENTICATION, 267 name=generate_id(), 268 title=generate_id(), 269 ) 270 PolicyBinding.objects.create(policy=flow_policy, target=flow, order=0) 271 272 user_login = UserLoginStage.objects.create(name=stage_name) 273 fsb = FlowStageBinding.objects.create(target=flow, stage=user_login, order=0) 274 PolicyBinding.objects.create(policy=flow_policy, target=fsb, order=0) 275 276 exporter = FlowExporter(flow) 277 export_yaml = exporter.export_to_string() 278 279 importer = Importer.from_string(export_yaml) 280 self.assertTrue(importer.validate()[0]) 281 self.assertTrue(importer.apply()) 282 self.assertTrue(UserLoginStage.objects.filter(name=stage_name).exists()) 283 self.assertTrue(Flow.objects.filter(slug=flow_slug).exists())
Test export and validate it
def
test_export_validate_import_prompt(self):
285 def test_export_validate_import_prompt(self): 286 """Test export and validate it""" 287 with transaction_rollback(): 288 # First stage fields 289 username_prompt = Prompt.objects.create( 290 name=generate_id(), 291 field_key="username", 292 label="Username", 293 order=0, 294 type=FieldTypes.TEXT, 295 ) 296 password = Prompt.objects.create( 297 name=generate_id(), 298 field_key="password", 299 label="Password", 300 order=1, 301 type=FieldTypes.PASSWORD, 302 ) 303 password_repeat = Prompt.objects.create( 304 name=generate_id(), 305 field_key="password_repeat", 306 label="Password (repeat)", 307 order=2, 308 type=FieldTypes.PASSWORD, 309 ) 310 311 # Stages 312 first_stage = PromptStage.objects.create(name=generate_id()) 313 first_stage.fields.set([username_prompt, password, password_repeat]) 314 first_stage.save() 315 316 flow = Flow.objects.create( 317 name=generate_id(), 318 slug=generate_id(), 319 designation=FlowDesignation.ENROLLMENT, 320 title=generate_id(), 321 ) 322 323 FlowStageBinding.objects.create(target=flow, stage=first_stage, order=0) 324 325 exporter = FlowExporter(flow) 326 export_yaml = exporter.export_to_string() 327 328 importer = Importer.from_string(export_yaml) 329 330 self.assertTrue(importer.validate()[0]) 331 self.assertTrue(importer.apply())
Test export and validate it