Skip to content

Commit 7c71771

Browse files
authored
Enable/Disable authentication maps (ansible#530)
1 parent 3adf499 commit 7c71771

File tree

5 files changed

+63
-19
lines changed

5 files changed

+63
-19
lines changed

ansible_base/authentication/migrations/0015_alter_authenticator_category_and_more.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,9 @@ class Migration(migrations.Migration):
149149
name='revoke',
150150
field=models.BooleanField(default=False, help_text='Revoke the permission if a user does not meet this rule.'),
151151
),
152+
migrations.AddField(
153+
model_name='authenticatormap',
154+
name='enabled',
155+
field=models.BooleanField(default=True, help_text='Enables or disables this authenticator map'),
156+
),
152157
]

ansible_base/authentication/models/authenticator_map.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,8 @@ class Meta:
8888
)
8989
),
9090
)
91+
enabled = models.BooleanField(
92+
null=False,
93+
default=True,
94+
help_text=_("Enables or disables this authenticator map"),
95+
)

ansible_base/authentication/utils/claims.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,29 @@ def create_claims(authenticator: Authenticator, username: str, attrs: dict, grou
5656
logger.debug(f"{username}'s attrs: {attrs}")
5757

5858
# load the maps
59+
logger.debug(f"Authenticator ID: {authenticator.id}")
60+
maps = AuthenticatorMap.objects.order_by("order")
61+
logger.debug(maps)
5962
maps = AuthenticatorMap.objects.filter(authenticator=authenticator.id).order_by("order")
63+
logger.debug("==============================================================")
64+
logger.debug(maps)
65+
6066
for auth_map in maps:
67+
logger.debug(auth_map)
68+
logger.debug("++++")
6169
has_permission = None
6270
trigger_result = TriggerResult.SKIP
6371
allowed_keys = TRIGGER_DEFINITION.keys()
6472
invalid_keys = set(auth_map.triggers.keys()) - set(allowed_keys)
73+
74+
if auth_map.enabled is False:
75+
logger.info(f"Skipping AuthenticatorMap {auth_map.id} because it is disabled")
76+
rule_responses.append({auth_map.id: 'skipped', 'enabled': auth_map.enabled})
77+
continue
78+
6579
if invalid_keys:
6680
logger.warning(f"In AuthenticatorMap {auth_map.id} the following trigger keys are invalid: {', '.join(invalid_keys)}, rule will be ignored")
67-
rule_responses.append({auth_map.id: 'invalid'})
81+
rule_responses.append({auth_map.id: 'invalid', 'enabled': auth_map.enabled})
6882
continue
6983

7084
for trigger_type, trigger in auth_map.triggers.items():
@@ -84,15 +98,15 @@ def create_claims(authenticator: Authenticator, username: str, attrs: dict, grou
8498

8599
# If the trigger result is still SKIP, this auth map is not applicable to this user => no action needed
86100
if trigger_result is TriggerResult.SKIP:
87-
rule_responses.append({auth_map.id: 'skipped'})
101+
rule_responses.append({auth_map.id: 'skipped', 'enabled': auth_map.enabled})
88102
continue
89103

90104
if trigger_result is TriggerResult.ALLOW:
91105
has_permission = True
92106
elif trigger_result is TriggerResult.DENY:
93107
has_permission = False
94108

95-
rule_responses.append({auth_map.id: has_permission})
109+
rule_responses.append({auth_map.id: has_permission, 'enabled': auth_map.enabled})
96110

97111
if auth_map.map_type == 'allow' and not has_permission:
98112
# If any rule does not allow we don't want to return this to true

test_app/tests/authentication/utils/test_claims.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pytest
44
from django.db import connection
55

6-
from ansible_base.authentication.models import AuthenticatorUser
6+
from ansible_base.authentication.models import AuthenticatorMap, AuthenticatorUser
77
from ansible_base.authentication.utils import claims
88
from test_app.tests.authentication.conftest import SYSTEM_ROLE_NAME
99

@@ -20,7 +20,7 @@
2020
True,
2121
True,
2222
{"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}},
23-
[{1: True}],
23+
[{1: True, 'enabled': True}],
2424
id="Set flag 'is_superuser' to True (trigger 'always')",
2525
),
2626
pytest.param(
@@ -32,7 +32,7 @@
3232
True,
3333
False,
3434
{"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}},
35-
[{1: False}],
35+
[{1: False, 'enabled': True}],
3636
id="Set flag 'is_superuser' to False (trigger 'never')",
3737
),
3838
pytest.param(
@@ -44,7 +44,7 @@
4444
True,
4545
None,
4646
{"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}},
47-
[{1: "invalid"}],
47+
[{1: "invalid", 'enabled': True}],
4848
id="Wrong trigger, thus flag 'is_superuser' is not set, auth. map is ignored",
4949
),
5050
pytest.param(
@@ -56,7 +56,7 @@
5656
True,
5757
None,
5858
{"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}},
59-
[{1: "skipped"}],
59+
[{1: "skipped", 'enabled': True}],
6060
id="Define no trigger, thus flag 'is_superuser' is not set",
6161
),
6262
pytest.param(
@@ -68,7 +68,7 @@
6868
False,
6969
None,
7070
{"team_membership": {}, "organization_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}},
71-
[{1: False}],
71+
[{1: False, 'enabled': True}],
7272
id="map_type 'allow' with trigger 'never' sets 'access_allowed' to False",
7373
),
7474
pytest.param(
@@ -84,7 +84,7 @@
8484
"team_membership": {"testorg": {"testteam": True}},
8585
'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {}, 'teams': {'testteam': {'roles': {'Team Member': True}}}}}},
8686
},
87-
[{1: True}],
87+
[{1: True, 'enabled': True}],
8888
id="Assign 'Team Member' role to team 'testteam'",
8989
),
9090
pytest.param(
@@ -100,7 +100,7 @@
100100
"team_membership": {"testorg": {"testteam": False}},
101101
'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {}, 'teams': {'testteam': {'roles': {'Team Member': False}}}}}},
102102
},
103-
[{1: False}],
103+
[{1: False, 'enabled': True}],
104104
id="Remove 'Team Member' role from team 'testteam'",
105105
),
106106
pytest.param(
@@ -116,7 +116,7 @@
116116
"team_membership": {},
117117
'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {'Organization Member': True}, 'teams': {}}}},
118118
},
119-
[{1: True}],
119+
[{1: True, 'enabled': True}],
120120
id="Assign 'Organization Member' role to organization 'testorg'",
121121
),
122122
pytest.param(
@@ -132,7 +132,7 @@
132132
"team_membership": {},
133133
'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {'Organization Member': False}, 'teams': {}}}},
134134
},
135-
[{1: False}],
135+
[{1: False, 'enabled': True}],
136136
id="Remove 'Organization Member' role from organization 'testorg'",
137137
),
138138
pytest.param(
@@ -148,7 +148,7 @@
148148
"team_membership": {"testorg": {"testteam": True}},
149149
'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {}, 'teams': {'testteam': {'roles': {'Team Member': True}}}}}},
150150
},
151-
[{1: True}],
151+
[{1: True, 'enabled': True}],
152152
id="Assign 'Team Member' role to team 'testteam' using map_type 'role'",
153153
),
154154
pytest.param(
@@ -164,7 +164,7 @@
164164
"team_membership": {},
165165
'rbac_roles': {'system': {'roles': {}}, 'organizations': {'testorg': {'roles': {'Organization Member': True}, 'teams': {}}}},
166166
},
167-
[{1: True}],
167+
[{1: True, 'enabled': True}],
168168
id="Assign 'Organization Member' role to organization 'testorg' using map_type 'role'",
169169
),
170170
pytest.param(
@@ -176,7 +176,7 @@
176176
True,
177177
None,
178178
{"organization_membership": {}, "team_membership": {}, 'rbac_roles': {'system': {'roles': {SYSTEM_ROLE_NAME: True}}, 'organizations': {}}},
179-
[{1: True}],
179+
[{1: True, 'enabled': True}],
180180
id="Assign System role to user",
181181
),
182182
pytest.param(
@@ -188,7 +188,7 @@
188188
True,
189189
None,
190190
{"organization_membership": {}, "team_membership": {}, 'rbac_roles': {'system': {'roles': {}}, 'organizations': {}}},
191-
[{1: False}],
191+
[{1: False, 'enabled': True}],
192192
id="Wrong map type, this auth. map is ignored",
193193
),
194194
],
@@ -324,9 +324,9 @@ def test_create_claims_revoke(local_authenticator_map, process_function, trigger
324324
assert res["is_superuser"] is granted
325325
assert res["claims"] == {"team_membership": {}, "organization_membership": {}, "rbac_roles": default_rbac_roles_claims}
326326
if revoke:
327-
assert res["last_login_map_results"] == [{local_authenticator_map.pk: False}]
327+
assert res["last_login_map_results"] == [{local_authenticator_map.pk: False, 'enabled': True}]
328328
else:
329-
assert res["last_login_map_results"] == [{local_authenticator_map.pk: "skipped"}]
329+
assert res["last_login_map_results"] == [{local_authenticator_map.pk: "skipped", 'enabled': True}]
330330

331331

332332
@pytest.mark.parametrize(
@@ -772,3 +772,22 @@ def test_update_user_claims_groups(user, local_authenticator_map):
772772
assert local_authenticator_map.authenticator == authenticator_user.provider # sanity check
773773
result = claims.update_user_claims(user, authenticator, ["foo"])
774774
assert result is user
775+
776+
777+
@pytest.mark.parametrize("enabled", [True, False])
778+
def test_create_claims_with_map_enabled_or_disabled(enabled, local_authenticator):
779+
# Create an AuthenticatorMap object with the parameterized "enabled" value
780+
AuthenticatorMap.objects.create(
781+
authenticator=local_authenticator,
782+
triggers={"always": {}},
783+
map_type="is_superuser",
784+
enabled=enabled,
785+
)
786+
787+
result = claims.create_claims(local_authenticator, "testuser", {}, [])
788+
789+
# Assert based on the "enabled" value
790+
if enabled:
791+
assert result["is_superuser"] is not None, "Claim should be present when enabled is True"
792+
else:
793+
assert result["is_superuser"] is None, "Claim should be None when enabled is False"

test_app/tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ def local_authenticator_map(db, local_authenticator, user, randname):
465465
triggers={"always": {}},
466466
organization="testorg",
467467
team="testteam",
468+
enabled=True,
468469
)
469470
return authenticator_map
470471

0 commit comments

Comments
 (0)