Skip to content

Commit 96923be

Browse files
refactor: move scope-type filtering to RoleAssignmentAuditQuerySet
Add a `for_scope_namespace` queryset method so scope-type filtering is available both in the admin and in API-level querysets, without duplicating the namespace-prefix logic. The admin `ScopeTypeFilter` now delegates to this method instead of building the `scope__startswith` lookup directly.
1 parent 67b9589 commit 96923be

2 files changed

Lines changed: 20 additions & 4 deletions

File tree

openedx_authz/admin.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from django.contrib import admin
66

77
from openedx_authz.api.data import ContentLibraryData, CourseOverviewData
8-
from openedx_authz.constants import AUTHZ_POLICY_ATTRIBUTES_SEPARATOR
98
from openedx_authz.models import ExtendedCasbinRule
109
from openedx_authz.models.core import RoleAssignmentAudit
1110

@@ -75,9 +74,7 @@ def lookups(self, request, model_admin):
7574
def queryset(self, request, queryset):
7675
"""Filter the queryset by scope namespace prefix."""
7776
if self.value():
78-
return queryset.filter(
79-
scope__startswith=f"{self.value()}{AUTHZ_POLICY_ATTRIBUTES_SEPARATOR}"
80-
)
77+
return queryset.for_scope_namespace(self.value())
8178
return queryset
8279

8380

openedx_authz/models/core.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,23 @@ def create_based_on_policy(
237237
return extended_rule
238238

239239

240+
class RoleAssignmentAuditQuerySet(models.QuerySet):
241+
"""QuerySet for RoleAssignmentAudit with scope-based filtering."""
242+
243+
def for_scope_namespace(self, namespace: str) -> "RoleAssignmentAuditQuerySet":
244+
"""Return records whose scope starts with the given namespace prefix.
245+
246+
Args:
247+
namespace: The namespace to filter by (e.g. ``'lib'``, ``'course-v1'``).
248+
Use the NAMESPACE class attribute from the corresponding ScopeData
249+
subclass (e.g. ``ContentLibraryData.NAMESPACE``).
250+
251+
Returns:
252+
Queryset filtered to records matching the scope type.
253+
"""
254+
return self.filter(scope__startswith=f"{namespace}{AUTHZ_POLICY_ATTRIBUTES_SEPARATOR}")
255+
256+
240257
class RoleAssignmentAudit(models.Model):
241258
"""Model to audit role assignments and unassignments.
242259
@@ -247,6 +264,8 @@ class RoleAssignmentAudit(models.Model):
247264
role assignments over time.
248265
"""
249266

267+
objects = RoleAssignmentAuditQuerySet.as_manager()
268+
250269
class Operations(NamedTuple):
251270
created: str = "created"
252271
deleted: str = "deleted"

0 commit comments

Comments
 (0)