Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Change Log
Unreleased
**********

* Register ``CasbinRule`` model in the Django admin.
* Register ``ExtendedCasbinRule`` model in the Django admin as an inline model of ``CasbinRule``.

0.15.0 - 2025-11-11
********************

Expand Down
50 changes: 50 additions & 0 deletions openedx_authz/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Admin configuration for openedx_authz."""

from casbin_adapter.models import CasbinRule
from django import forms
from django.contrib import admin

from openedx_authz.models import ExtendedCasbinRule


class CasbinRuleForm(forms.ModelForm):
"""Custom form for CasbinRule to make v3, v4, v5 fields optional."""

class Meta:
"""Meta class for CasbinRuleForm."""

model = CasbinRule
fields = "__all__"

def __init__(self, *args, **kwargs):
"""Initialize CasbinRuleForm."""
super().__init__(*args, **kwargs)
# Make v2, v3, v4, v5 optional in the form
# These fields are not always required depending on the policy type
self.fields["v2"].required = False
self.fields["v3"].required = False
self.fields["v4"].required = False
self.fields["v5"].required = False


class ExtendedCasbinRuleInline(admin.StackedInline):
"""Inline admin for ExtendedCasbinRule to display additional metadata."""

model = ExtendedCasbinRule
extra = 0
fields = ("casbin_rule_key", "scope", "subject", "description", "metadata", "created_at", "updated_at")
readonly_fields = ("casbin_rule_key", "scope", "subject", "created_at", "updated_at")
can_delete = False


@admin.register(CasbinRule)
class CasbinRuleAdmin(admin.ModelAdmin):
"""Admin for CasbinRule to display additional metadata."""

form = CasbinRuleForm
list_display = ("id", "ptype", "v0", "v1", "v2", "v3", "v4", "v5")
search_fields = ("ptype", "v0", "v1", "v2", "v3", "v4", "v5")
list_filter = ("ptype",)
# TODO: In a future, possibly we should only show an inline for the rules that
# have an extended rule, and show the subject and scope information in detail.
inlines = [ExtendedCasbinRuleInline]
1 change: 1 addition & 0 deletions openedx_authz/models/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def get_registry(cls) -> dict[str, type["BaseRegistryModel"]]:
"""
return cls._registry


class ScopeManager(models.Manager):
"""Custom manager for Scope model that handles polymorphic behavior."""

Expand Down