From 65f3650b4bea01ba73f7626e77cb0ec0c51b3c72 Mon Sep 17 00:00:00 2001 From: David O Neill Date: Sat, 27 Jul 2024 00:12:04 +0100 Subject: [PATCH] Enable/Disable authentication maps --- ...013_add_authenticationmap_enabled_field.py | 18 +++++++++++ .../models/authenticator_map.py | 5 ++++ ansible_base/authentication/utils/claims.py | 10 +++++-- .../tests/authentication/utils/test_claims.py | 30 +++++++++---------- test_app/tests/conftest.py | 1 + 5 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 ansible_base/authentication/migrations/0013_add_authenticationmap_enabled_field.py diff --git a/ansible_base/authentication/migrations/0013_add_authenticationmap_enabled_field.py b/ansible_base/authentication/migrations/0013_add_authenticationmap_enabled_field.py new file mode 100644 index 000000000..c70839bc7 --- /dev/null +++ b/ansible_base/authentication/migrations/0013_add_authenticationmap_enabled_field.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.11 on 2024-06-06 17:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dab_authentication', '0012_alter_authenticatormap_map_type'), + ] + + operations = [ + migrations.AddField( + model_name='authenticatormap', + name='enabled', + field=models.BooleanField(default=True, help_text='Enables or disables this authentication map', null=False), + ), + ] diff --git a/ansible_base/authentication/models/authenticator_map.py b/ansible_base/authentication/models/authenticator_map.py index e2f7192b5..cea275265 100644 --- a/ansible_base/authentication/models/authenticator_map.py +++ b/ansible_base/authentication/models/authenticator_map.py @@ -88,3 +88,8 @@ class Meta: ) ), ) + enabled = models.BooleanField( + null=False, + default=True, + help_text=_("Enables or disables this authentication map"), + ) diff --git a/ansible_base/authentication/utils/claims.py b/ansible_base/authentication/utils/claims.py index 9b6007d35..f38eddc9d 100644 --- a/ansible_base/authentication/utils/claims.py +++ b/ansible_base/authentication/utils/claims.py @@ -62,9 +62,13 @@ def create_claims(authenticator: Authenticator, username: str, attrs: dict, grou trigger_result = TriggerResult.SKIP allowed_keys = TRIGGER_DEFINITION.keys() invalid_keys = set(auth_map.triggers.keys()) - set(allowed_keys) + + if auth_map.enabled is False: + logger.info(f"The AuthenticatorMap {auth_map.id} is disabled") + if invalid_keys: logger.warning(f"In AuthenticatorMap {auth_map.id} the following trigger keys are invalid: {', '.join(invalid_keys)}, rule will be ignored") - rule_responses.append({auth_map.id: 'invalid'}) + rule_responses.append({auth_map.id: 'invalid', 'enabled': auth_map.enabled}) continue for trigger_type, trigger in auth_map.triggers.items(): @@ -84,7 +88,7 @@ def create_claims(authenticator: Authenticator, username: str, attrs: dict, grou # If the trigger result is still SKIP, this auth map is not applicable to this user => no action needed if trigger_result is TriggerResult.SKIP: - rule_responses.append({auth_map.id: 'skipped'}) + rule_responses.append({auth_map.id: 'skipped', 'enabled': auth_map.enabled}) continue if trigger_result is TriggerResult.ALLOW: @@ -92,7 +96,7 @@ def create_claims(authenticator: Authenticator, username: str, attrs: dict, grou elif trigger_result is TriggerResult.DENY: has_permission = False - rule_responses.append({auth_map.id: has_permission}) + rule_responses.append({auth_map.id: has_permission, 'enabled': auth_map.enabled}) if auth_map.map_type == 'allow' and not has_permission: # If any rule does not allow we don't want to return this to true diff --git a/test_app/tests/authentication/utils/test_claims.py b/test_app/tests/authentication/utils/test_claims.py index ebe3ebb0d..66dc7ac38 100644 --- a/test_app/tests/authentication/utils/test_claims.py +++ b/test_app/tests/authentication/utils/test_claims.py @@ -20,7 +20,7 @@ True, True, {"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}}, - [{1: True}], + [{1: True, 'enabled': True}], id="Set flag 'is_superuser' to True (trigger 'always')", ), pytest.param( @@ -32,7 +32,7 @@ True, False, {"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}}, - [{1: False}], + [{1: False, 'enabled': True}], id="Set flag 'is_superuser' to False (trigger 'never')", ), pytest.param( @@ -44,7 +44,7 @@ True, None, {"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}}, - [{1: "invalid"}], + [{1: "invalid", 'enabled': True}], id="Wrong trigger, thus flag 'is_superuser' is not set, auth. map is ignored", ), pytest.param( @@ -56,7 +56,7 @@ True, None, {"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}}, - [{1: "skipped"}], + [{1: "skipped", 'enabled': True}], id="Define no trigger, thus flag 'is_superuser' is not set", ), pytest.param( @@ -68,7 +68,7 @@ False, None, {"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}}, - [{1: False}], + [{1: False, 'enabled': True}], id="map_type 'allow' with trigger 'never' sets 'access_allowed' to False", ), pytest.param( @@ -84,7 +84,7 @@ "team_membership": {"testorg": {"testteam": True}}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {}, 'teams': {'testteam': {'roles': {'Team Member': True}}}}}}, }, - [{1: True}], + [{1: True, 'enabled': True}], id="Assign 'Team Member' role to team 'testteam'", ), pytest.param( @@ -100,7 +100,7 @@ "team_membership": {"testorg": {"testteam": False}}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {}, 'teams': {'testteam': {'roles': {'Team Member': False}}}}}}, }, - [{1: False}], + [{1: False, 'enabled': True}], id="Remove 'Team Member' role from team 'testteam'", ), pytest.param( @@ -116,7 +116,7 @@ "team_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {'Organization Member': True}, 'teams': {}}}}, }, - [{1: True}], + [{1: True, 'enabled': True}], id="Assign 'Organization Member' role to organization 'testorg'", ), pytest.param( @@ -132,7 +132,7 @@ "team_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {'Organization Member': False}, 'teams': {}}}}, }, - [{1: False}], + [{1: False, 'enabled': True}], id="Remove 'Organization Member' role from organization 'testorg'", ), pytest.param( @@ -148,7 +148,7 @@ "team_membership": {"testorg": {"testteam": True}}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {}, 'teams': {'testteam': {'roles': {'Team Member': True}}}}}}, }, - [{1: True}], + [{1: True, 'enabled': True}], id="Assign 'Team Member' role to team 'testteam' using map_type 'role'", ), pytest.param( @@ -164,7 +164,7 @@ "team_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {'Organization Member': True}, 'teams': {}}}}, }, - [{1: True}], + [{1: True, 'enabled': True}], id="Assign 'Organization Member' role to organization 'testorg' using map_type 'role'", ), pytest.param( @@ -176,7 +176,7 @@ True, None, {"organization_membership": {}, "team_membership": {}, 'rbac_roles': {'system': {'roles': {SYSTEM_ROLE_NAME: True}}, 'organizations': {}}}, - [{1: True}], + [{1: True, 'enabled': True}], id="Assign System role to user", ), pytest.param( @@ -188,7 +188,7 @@ True, None, {"organization_membership": {}, "team_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}}, - [{1: False}], + [{1: False, 'enabled': True}], id="Wrong map type, this auth. map is ignored", ), ], @@ -324,9 +324,9 @@ def test_create_claims_revoke(local_authenticator_map, process_function, trigger assert res["is_superuser"] is granted assert res["claims"] == {"team_membership": {}, "organization_membership": {}, "rbac_roles": default_rbac_roles_claims} if revoke: - assert res["last_login_map_results"] == [{local_authenticator_map.pk: False}] + assert res["last_login_map_results"] == [{local_authenticator_map.pk: False, 'enabled': True}] else: - assert res["last_login_map_results"] == [{local_authenticator_map.pk: "skipped"}] + assert res["last_login_map_results"] == [{local_authenticator_map.pk: "skipped", 'enabled': True}] @pytest.mark.parametrize( diff --git a/test_app/tests/conftest.py b/test_app/tests/conftest.py index 928fe8725..3ae6c536b 100644 --- a/test_app/tests/conftest.py +++ b/test_app/tests/conftest.py @@ -455,6 +455,7 @@ def local_authenticator_map(db, local_authenticator, user, randname): triggers={"always": {}}, organization="testorg", team="testteam", + enabled=True ) return authenticator_map