Skip to content

Commit 79f9bf5

Browse files
committed
feat: allow disabling auto-load policy in AuthzEnforcer based on settings
1 parent 8298d3e commit 79f9bf5

2 files changed

Lines changed: 61 additions & 1 deletion

File tree

openedx_authz/engine/enforcer.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ def _initialize_enforcer() -> SyncedEnforcer:
9393

9494
adapter = ExtendedAdapter()
9595
enforcer = SyncedEnforcer(settings.CASBIN_MODEL, adapter)
96-
enforcer.start_auto_load_policy(settings.CASBIN_AUTO_LOAD_POLICY_INTERVAL)
96+
auto_load_policy_interval = getattr(settings, "CASBIN_AUTO_LOAD_POLICY_INTERVAL", -1)
97+
if auto_load_policy_interval != -1:
98+
enforcer.start_auto_load_policy(auto_load_policy_interval)
9799
enforcer.enable_auto_save(True)
98100

99101
return enforcer

openedx_authz/tests/test_enforcer.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,61 @@ def test_auto_load_policy_detects_changes(self):
520520
# After auto-load, the new role assignment should be loaded
521521
policies_after_auto_load = global_enforcer.get_grouping_policy()
522522
self.assertIn(new_assignment, policies_after_auto_load)
523+
524+
@override_settings(CASBIN_AUTO_LOAD_POLICY_INTERVAL=-1)
525+
def test_auto_load_disabled(self):
526+
"""Test that auto-load can be disabled by setting interval to -1.
527+
528+
This test verifies that when CASBIN_AUTO_LOAD_POLICY_INTERVAL is set to -1,
529+
the enforcer does NOT automatically load policies from the database.
530+
531+
Expected result:
532+
- Policies remain empty after seeding database
533+
- Manual load_policy() is required to load policies
534+
- New policies don't appear without manual reload
535+
"""
536+
global_enforcer = AuthzEnforcer.get_enforcer()
537+
self._seed_database_with_policies()
538+
539+
# Initial policy count should be 0
540+
initial_policy_count = len(global_enforcer.get_policy())
541+
self.assertEqual(initial_policy_count, 0)
542+
543+
# Wait a bit to ensure auto-load would have occurred if enabled
544+
time.sleep(1.0)
545+
546+
# Policies should still be empty since auto-load is disabled
547+
policies_after_wait = global_enforcer.get_policy()
548+
self.assertEqual(len(policies_after_wait), 0)
549+
550+
# Manually load policies
551+
global_enforcer.load_policy()
552+
policies_after_manual_load = global_enforcer.get_policy()
553+
self.assertGreater(len(policies_after_manual_load), 0)
554+
555+
# Add a new policy (which gets auto-saved to DB)
556+
new_policy = [
557+
make_role_key("fake_role"),
558+
make_action_key("fake_action"),
559+
make_scope_key("lib", "*"),
560+
"allow",
561+
]
562+
global_enforcer.add_policy(*new_policy)
563+
564+
# Wait to ensure auto-load would have occurred if enabled
565+
time.sleep(1.0)
566+
567+
# Clear the in-memory policies to simulate a fresh state
568+
policy_count_before_clear = len(global_enforcer.get_policy())
569+
global_enforcer.clear_policy()
570+
571+
# Wait again - auto-load should NOT reload policies
572+
time.sleep(1.0)
573+
policies_after_clear = global_enforcer.get_policy()
574+
self.assertEqual(len(policies_after_clear), 0)
575+
576+
# Manually reload to verify the new policy was saved to DB
577+
global_enforcer.load_policy()
578+
policies_after_reload = global_enforcer.get_policy()
579+
self.assertEqual(len(policies_after_reload), policy_count_before_clear)
580+
self.assertIn(new_policy, policies_after_reload)

0 commit comments

Comments
 (0)