Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
54c4db0
feat: implement course authoring migration functionality
BryanttV Apr 10, 2026
50e9366
fix: set default course_id for legacy role migration
BryanttV Apr 15, 2026
fd778ec
refactor: rename 'migrations' module to 'authz_migration'
BryanttV Apr 15, 2026
ff40aad
docs: update comment to reference ADR-0013
BryanttV Apr 15, 2026
88f1670
fix: handle unsupported waffle flag instances in course authoring mig…
BryanttV Apr 15, 2026
06d340f
test: add unit test for handlers
BryanttV Apr 15, 2026
c911f88
test: add unit tests for model
BryanttV Apr 15, 2026
7c1d8e5
test: add no_pii annotation to waffle flag stub models
BryanttV Apr 15, 2026
69ac955
refactor: always return instance
BryanttV Apr 16, 2026
54f9704
test: add unit tests for course authoring migration functionality
BryanttV Apr 16, 2026
5e9fe46
chore: reorder conditions in course authoring migration handler
BryanttV Apr 16, 2026
61131ef
refactor: run migration run save and running guard in one transaction
BryanttV Apr 16, 2026
de7da52
chore: bump version to 1.12.0
BryanttV Apr 16, 2026
5c7311b
refactor: remove indexes from AuthzCourseAuthoringMigrationRun model
BryanttV Apr 16, 2026
0ca8235
refactor: update MigrationErrorReason to use StrEnum
BryanttV Apr 17, 2026
24285df
feat: add course id exclusion logic for org migration based on author…
BryanttV Apr 17, 2026
cf3faff
feat: enhance course authoring migration logic with effective overrid…
BryanttV Apr 17, 2026
fedaeb6
test: add WaffleStubManager and override_choice field to waffle flag …
BryanttV Apr 19, 2026
406603e
test: enhance course authoring migration tests with ddt
BryanttV Apr 19, 2026
4a00968
test: update migration tests to improve error detail handling
BryanttV Apr 20, 2026
f73fc6a
test: add new tests according handlers changes
BryanttV Apr 20, 2026
add438a
docs: remove unexpected identation
BryanttV Apr 20, 2026
20db8d7
test: add migration test to verify skipping of excluded course ids
BryanttV Apr 20, 2026
9dd98b3
chore: update release date for version 1.12.0
BryanttV Apr 20, 2026
7881224
feat: implement migration type determination logic based on current a…
BryanttV Apr 20, 2026
96b2e57
chore: add django-waffle in base requirements
BryanttV Apr 21, 2026
3a7c4b7
feat: add effective state evaluation for waffle flags in migration logic
BryanttV Apr 21, 2026
fb803ac
refactor: update test assertions for waffle flag migration logic
BryanttV Apr 21, 2026
11782ac
docs: clarify docstring for effective state evaluation
BryanttV Apr 21, 2026
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
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ Change Log
Unreleased
**********

1.12.0 - 2026-04-20
*******************

Added
=====

* Add automatic course authoring migration mechanism triggered by the ``authz.enable_course_authoring`` waffle flag when it is toggled at course or organization scope.

1.11.0 - 2026-04-16
*******************

Expand Down
2 changes: 1 addition & 1 deletion openedx_authz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

import os

__version__ = "1.11.0"
__version__ = "1.12.0"

ROOT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
41 changes: 40 additions & 1 deletion openedx_authz/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
"""Admin configuration for openedx_authz."""

import json

from casbin_adapter.models import CasbinRule
from django import forms
from django.contrib import admin
from django.utils.html import format_html

from openedx_authz.models import AuthzCourseAuthoringMigrationRun, ExtendedCasbinRule

from openedx_authz.models import ExtendedCasbinRule

def pretty_json(value) -> str:
"""Return an indented JSON representation of a value."""
if value is None:
return "-"
try:
formatted = json.dumps(value, indent=2, ensure_ascii=False)
except (TypeError, ValueError):
return str(value)
return format_html("<pre>{}</pre>", formatted)


class CasbinRuleForm(forms.ModelForm):
Expand Down Expand Up @@ -48,3 +62,28 @@ class CasbinRuleAdmin(admin.ModelAdmin):
# 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]


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

list_display = ("id", "scope_type", "scope_key", "migration_type", "status", "created_at", "updated_at")
search_fields = ("scope_type", "scope_key", "migration_type", "status")
list_filter = ("scope_type", "migration_type", "status")
readonly_fields = (
"scope_type",
"scope_key",
"migration_type",
"status",
"pretty_metadata",
"completed_at",
"created_at",
"updated_at",
)
fields = readonly_fields

@admin.display(description="Metadata")
def pretty_metadata(self, obj):
"""Return formatted JSON for the metadata field."""
return pretty_json(obj.metadata)
Loading