1010from unittest import TestCase
1111
1212import casbin
13+ import pytest
1314from ddt import data , ddt , unpack
15+ from django .contrib .auth import get_user_model
1416
1517from openedx_authz import ROOT_DIRECTORY
1618from openedx_authz .constants import roles
19+ from openedx_authz .engine .matcher import is_admin_or_superuser_check
1720from openedx_authz .tests .test_utils import (
1821 make_action_key ,
1922 make_library_key ,
2225 make_user_key ,
2326)
2427
28+ User = get_user_model ()
29+
2530
2631class AuthRequest (TypedDict ):
2732 """
@@ -44,6 +49,7 @@ class AuthRequest(TypedDict):
4449]
4550
4651
52+ @pytest .mark .django_db
4753@ddt
4854class CasbinEnforcementTestCase (TestCase ):
4955 """
@@ -65,6 +71,7 @@ def setUpClass(cls) -> None:
6571 raise FileNotFoundError (f"Model file not found: { model_file } " )
6672
6773 cls .enforcer = casbin .Enforcer (model_file )
74+ cls .enforcer .add_function ("is_staff_or_superuser" , is_admin_or_superuser_check )
6875
6976 def _load_policy (self , policy : list [str ]) -> None :
7077 """
@@ -573,3 +580,84 @@ def test_wildcard_library_access(self, scope: str, expected_result: bool):
573580 "expected_result" : expected_result ,
574581 }
575582 self ._test_enforcement (self .POLICY , request )
583+
584+
585+ @pytest .mark .django_db
586+ @ddt
587+ class StaffSuperuserAccessTests (CasbinEnforcementTestCase ):
588+ """
589+ Tests for staff and superuser automatic permission grants via is_staff_or_superuser.
590+
591+ This test class verifies that staff members and superusers are automatically
592+ granted access to ContentLibrary scopes through the is_admin_or_superuser_check function,
593+ without requiring explicit role assignments.
594+ """
595+
596+ # Empty policy - no role assignments for staff/superuser users
597+ POLICY = []
598+
599+ def setUp (self ) -> None :
600+ """Set up the test environment."""
601+ super ().setUp ()
602+ User .
objects .
create_user (
username = "staff_user" ,
email = "[email protected] " ,
password = "test" ,
is_staff = True )
603+ User .
objects .
create_superuser (
username = "superuser" ,
email = "[email protected] " ,
password = "test" )
604+ User .
objects .
create_user (
username = "regular_user" ,
email = "[email protected] " ,
password = "test" )
605+
606+ @data (
607+ # Staff user has automatic access to any library scope
608+ (
609+ make_user_key ("staff_user" ),
610+ make_action_key ("view_library" ),
611+ make_library_key ("lib:TestOrg:TestLib" ),
612+ True ,
613+ ),
614+ (
615+ make_user_key ("staff_user" ),
616+ make_action_key ("edit_library" ),
617+ make_library_key ("lib:AnyOrg:AnyLib" ),
618+ True ,
619+ ),
620+ # Superuser has automatic access to any library scope
621+ (
622+ make_user_key ("superuser" ),
623+ make_action_key ("view_library" ),
624+ make_library_key ("lib:TestOrg:TestLib" ),
625+ True ,
626+ ),
627+ (
628+ make_user_key ("superuser" ),
629+ make_action_key ("delete_library" ),
630+ make_library_key ("lib:AnyOrg:AnyLib" ),
631+ True ,
632+ ),
633+ # Regular user without role assignment has no access
634+ (
635+ make_user_key ("regular_user" ),
636+ make_action_key ("view_library" ),
637+ make_library_key ("lib:TestOrg:TestLib" ),
638+ False ,
639+ ),
640+ # Non existent library scope access denied
641+ (
642+ make_user_key ("regular_user" ),
643+ make_action_key ("view_library" ),
644+ make_library_key ("lib:NonExistent:NoLib" ),
645+ False ,
646+ ),
647+ )
648+ @unpack
649+ def test_staff_superuser_guaranteed_permissions (self , subject : str , action : str , scope : str , expected_result : bool ):
650+ """Test that staff and superusers have guaranteed permissions for ContentLibrary scopes.
651+
652+ This test validates that:
653+ - Staff users automatically have access to all library scopes without role assignments
654+ - Superusers automatically have access to all library scopes without role assignments
655+ - Regular users require explicit role assignments to access libraries
656+ - Access is granted through the is_staff_or_superuser matcher function
657+
658+ Expected result:
659+ - Staff and superusers can perform any action on any ContentLibrary scope
660+ - Regular users are denied access without role assignments
661+ """
662+ request = {"subject" : subject , "action" : action , "scope" : scope , "expected_result" : expected_result }
663+ self ._test_enforcement (self .POLICY , request )
0 commit comments