openedx_authz package#
Subpackages#
- openedx_authz.api package
- openedx_authz.constants package
- openedx_authz.engine package
- openedx_authz.management package
- openedx_authz.models package
- openedx_authz.rest_api package
- Subpackages
- openedx_authz.rest_api.v1 package
- Submodules
- openedx_authz.rest_api.v1.fields module
- openedx_authz.rest_api.v1.filters module
- openedx_authz.rest_api.v1.paginators module
- openedx_authz.rest_api.v1.permissions module
- openedx_authz.rest_api.v1.serializers module
- openedx_authz.rest_api.v1.urls module
- openedx_authz.rest_api.v1.views module
- Module contents
- openedx_authz.rest_api.v1 package
- Submodules
- openedx_authz.rest_api.data module
- openedx_authz.rest_api.decorators module
- openedx_authz.rest_api.urls module
- openedx_authz.rest_api.utils module
- Module contents
- Subpackages
- openedx_authz.settings package
Submodules#
openedx_authz.admin module#
Admin configuration for openedx_authz.
- class openedx_authz.admin.AuthzCourseAuthoringMigrationRunAdmin(model, admin_site)
Bases:
ModelAdminAdmin for AuthzCourseAuthoringMigrationRun to display additional metadata.
- fields = ('scope_type', 'scope_key', 'migration_type', 'status', 'pretty_metadata', 'completed_at', 'created_at', 'updated_at')
- list_display = ('id', 'scope_type', 'scope_key', 'migration_type', 'status', 'created_at', 'updated_at')
- list_filter = ('scope_type', 'migration_type', 'status')
- property media
- pretty_metadata(obj)
Return formatted JSON for the metadata field.
- readonly_fields = ('scope_type', 'scope_key', 'migration_type', 'status', 'pretty_metadata', 'completed_at', 'created_at', 'updated_at')
- search_fields = ('scope_type', 'scope_key', 'migration_type', 'status')
- class openedx_authz.admin.CasbinRuleAdmin(model, admin_site)
Bases:
ModelAdminAdmin for CasbinRule to display additional metadata.
- form
alias of
CasbinRuleForm
- inlines = [<class 'openedx_authz.admin.ExtendedCasbinRuleInline'>]
- list_display = ('id', 'ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5')
- list_filter = ('ptype',)
- property media
- search_fields = ('ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5')
- class openedx_authz.admin.CasbinRuleForm(*args, **kwargs)
Bases:
ModelFormCustom form for CasbinRule to make v3, v4, v5 fields optional.
- class Meta
Bases:
objectMeta class for CasbinRuleForm.
- fields = '__all__'
- model
alias of
CasbinRule
- base_fields = {'ptype': <django.forms.fields.CharField object>, 'v0': <django.forms.fields.CharField object>, 'v1': <django.forms.fields.CharField object>, 'v2': <django.forms.fields.CharField object>, 'v3': <django.forms.fields.CharField object>, 'v4': <django.forms.fields.CharField object>, 'v5': <django.forms.fields.CharField object>}
- declared_fields = {}
- property media
Return all media required to render the widgets on this form.
- class openedx_authz.admin.ExtendedCasbinRuleInline(parent_model, admin_site)
Bases:
StackedInlineInline admin for ExtendedCasbinRule to display additional metadata.
- can_delete = False
- extra = 0
- fields = ('casbin_rule_key', 'scope', 'subject', 'description', 'metadata', 'created_at', 'updated_at')
- property media
- model
alias of
ExtendedCasbinRule
- readonly_fields = ('casbin_rule_key', 'scope', 'subject', 'created_at', 'updated_at')
- class openedx_authz.admin.RoleAssignmentAuditAdmin(model, admin_site)
Bases:
ModelAdminRead-only admin for the role assignment audit log.
- date_hierarchy = 'timestamp'
- display_role(obj)
Role name without the namespace prefix.
- display_scope(obj)
Scope key without the namespace prefix.
- display_subject(obj)
Subject key without the namespace prefix.
- has_add_permission(request)
Audit records are created by the system only.
- has_change_permission(request, obj=None)
Audit records must not be modified after creation.
- has_delete_permission(request, obj=None)
Audit records must not be deleted through the admin.
- list_display = ('operation', 'display_subject', 'display_role', 'display_scope', 'actor_id', 'timestamp')
- list_filter = ('operation', <class 'openedx_authz.admin.ScopeTypeFilter'>)
- property media
- readonly_fields = ('operation', 'subject', 'role', 'scope', 'actor_id', 'timestamp')
- search_fields = ('subject', 'role', 'scope')
- class openedx_authz.admin.ScopeTypeFilter(request, params, model, model_admin)
Bases:
SimpleListFilterFilter audit records by scope type (content library, course, etc.).
- lookups(request, model_admin)
Return the available scope type choices.
Audit records are independent from live Casbin tables and scope objects: there are no FK references to filter on. The namespace prefix in the stored
scopestring (e.g.lib^,course-v1^) is the only available signal for categorizing records by scope type.
- parameter_name = 'scope_type'
- queryset(request, queryset)
Filter the queryset by scope namespace prefix.
- title = 'scope type'
- openedx_authz.admin.pretty_json(value) str
Return an indented JSON representation of a value.
openedx_authz.apps module#
openedx_authz Django application initialization.
- class openedx_authz.apps.OpenedxAuthzConfig(app_name, app_module)
Bases:
AppConfigConfiguration for the openedx_authz Django application.
- default_auto_field = 'django.db.models.BigAutoField'
- name = 'openedx_authz'
- plugin_app = {'settings_config': {'cms.djangoapp': {'common': {'relative_path': 'settings.common'}, 'production': {'relative_path': 'settings.production'}, 'test': {'relative_path': 'settings.test'}}, 'lms.djangoapp': {'common': {'relative_path': 'settings.common'}, 'production': {'relative_path': 'settings.production'}, 'test': {'relative_path': 'settings.test'}}}, 'url_config': {'cms.djangoapp': {'namespace': 'openedx-authz', 'regex': '^api/', 'relative_path': 'urls'}, 'lms.djangoapp': {'namespace': 'openedx-authz', 'regex': '^api/', 'relative_path': 'urls'}}}
- ready()
Import signal handlers when Django starts.
- verbose_name = 'Open edX AuthZ'
openedx_authz.data module#
Top-level data classes for actions and permissions.
These are defined here (rather than in openedx_authz.api.data) to avoid a circular import between openedx_authz.api.data and openedx_authz.constants.permissions.
- class openedx_authz.data.ActionData(external_key: str = '', namespaced_key: str = '')
Bases:
AuthZDataAn action represents an operation that can be performed in the authorization system.
- NAMESPACE
‘act’ for actions.
- Type:
ClassVar[str]
- external_key
The action identifier (e.g., ‘content_libraries.view_library’).
- Type:
- namespaced_key
The action identifier with namespace (e.g., ‘act^content_libraries.view_library’).
- Type:
Examples
>>> action = ActionData(external_key='content_libraries.delete_library') >>> action.namespaced_key 'act^content_libraries.delete_library' >>> action.name 'Content Libraries > Delete Library'
- property name: str
The human-readable name of the action (e.g., ‘Content Libraries > Delete Library’).
- class openedx_authz.data.AuthZData(external_key: str = '', namespaced_key: str = '')
Bases:
AuthzBaseClassBase class for all authz data classes.
- external_key: str
- namespaced_key: str
- class openedx_authz.data.AuthzBaseClass
Bases:
objectBase class for all authz classes.
- class openedx_authz.data.PermissionData(action: ActionData = None, effect: Literal['allow', 'deny'] = 'allow')
Bases:
objectA permission combines an action with an effect (allow or deny).
- action
The action being permitted or denied (ActionData instance).
- Type:
openedx_authz.data.ActionData
- effect
The effect of the permission, either ‘allow’ or ‘deny’ (default: ‘allow’).
- Type:
Literal[‘allow’, ‘deny’]
Examples
>>> read_action = ActionData(external_key='read') >>> permission = PermissionData(action=read_action, effect='allow') >>> str(permission) 'Read - allow'
- action: ActionData
- effect: Literal['allow', 'deny']
- property identifier: str
Get the permission identifier.
openedx_authz.handlers module#
Signal handlers for the authorization framework.
These handlers ensure proper cleanup and consistency when models are deleted.
- openedx_authz.handlers.create_audit_record_on_role_assignment_change(sender, role_assignment, **kwargs)
Create an audit record when a role assignment is created or deleted.
This handler listens for both creation and deletion of role assignments and logs the changes for auditing purposes.
- Parameters:
sender – The signal class (ROLE_ASSIGNMENT_CREATED or ROLE_ASSIGNMENT_DELETED).
role_assignment – RoleAssignmentEventData carrying the operation, subject, role, scope, and actor.
**kwargs – Additional keyword arguments from the signal.
- openedx_authz.handlers.delete_casbin_rule_on_extended_rule_deletion(sender, instance, **kwargs)
Delete the companion CasbinRule after its ExtendedCasbinRule disappears.
The handler keeps authorization data symmetric with three common flows:
Direct ExtendedCasbinRule deletes (API/UI) trigger removal of the linked CasbinRule.
Cascades from Scope or Subject deletions clear their ExtendedCasbinRule rows and, via this handler, the matching CasbinRule entries.
Cascades initiated from the CasbinRule side (enforcer cleanups) leave the query as a no-op because the row is already gone.
Running on
post_deleteensures database cascades complete before the cleanup runs, so enforcer-driven deletions no longer raise false errors.- Parameters:
sender – The model class (ExtendedCasbinRule).
instance – The ExtendedCasbinRule instance being deleted.
**kwargs – Additional keyword arguments from the signal.
- openedx_authz.handlers.get_effective_state(record: None, global_flag_enabled: bool) bool
Return whether the feature is effectively active for the override and global flag.
An enabled override forces on or off, otherwise the result follows the global flag.
- openedx_authz.handlers.get_excluded_course_ids_for_org_migration(org_id: str, override_choice: str) frozenset[str]
Collect course-level authoring flag overrides for an org that oppose the new org-level state.
When the org flag changes, we need to exclude course ids that have a course-level authoring flag override that opposes the new org-level state.
- openedx_authz.handlers.get_migration_type(current_record: None, previous_record: None, global_flag_enabled: bool) MigrationType | None
Determine the migration type by comparing the effective state before and after the transaction.
This accounts for the global flag state, meaning a transition could be triggered by removing a FORCE_OFF override when the global flag is ON.
- Parameters:
current_record (WaffleOverrideRecord) – The state of the record in the current transaction.
previous_record (WaffleOverrideRecord | None) – The state of the record prior to the current transaction.
global_flag_enabled (bool) – The state of the global flag.
- Returns:
If the flag is newly forced on. MigrationType.ROLLBACK: If the forced-on state is removed. None: If there is no effective change in the flag’s behavior.
- Return type:
MigrationType.FORWARD
- openedx_authz.handlers.handle_course_waffle_flag_change(sender, instance, **kwargs) None
Handle changes to course-level waffle flags.
When the authz.enable_course_authoring flag is changed for a course, trigger the appropriate migration run. Only trigger if automatic migration is enabled in the settings.
- Parameters:
sender – The model class (WaffleFlagCourseOverrideModel)
instance – The flag override instance being saved
**kwargs – Additional keyword arguments from the signal
- openedx_authz.handlers.handle_org_waffle_flag_change(sender, instance, **kwargs) None
Handle changes to organization-level waffle flags.
When the authz.enable_course_authoring flag is changed for an organization, trigger the appropriate migration run. Only trigger if automatic migration is enabled in the settings.
- Parameters:
sender – The model class (WaffleFlagOrgOverrideModel)
instance – The flag override instance being saved
**kwargs – Additional keyword arguments from the signal
- openedx_authz.handlers.trigger_course_authoring_migration(sender: type[None], instance: None, scope_key: str) None
Trigger a migration run in response to a waffle flag change.
Determines the migration direction from the flag state, guards against no-op saves, and delegates execution to
run_course_authoring_migrationwhich handles tracking and concurrent-run protection.- Parameters:
sender – The model class (WaffleOverrideRecord).
instance – The waffle flag instance that triggered the migration.
scope_key (str) – Course ID or organization name.
- openedx_authz.handlers.unassign_roles_on_user_retirement(sender, user, **kwargs)
Unassign roles from a user when they are retired.
This handler is triggered when a user is retired in the LMS. It ensures that any roles assigned to the user are removed, maintaining the integrity of the authorization system.
- Parameters:
sender – The model class (User).
user – The user instance being retired.
**kwargs – Additional keyword arguments from the signal.
openedx_authz.urls module#
Open edX AuthZ API URLs.
openedx_authz.utils module#
General utility functions for Open edX AuthZ.
- openedx_authz.utils.get_user_by_username_or_email(username_or_email: str) User
Retrieve a user by their username or email address.
- Parameters:
username_or_email (str) – The username or email address to search for.
- Returns:
The User object if found and not retired.
- Return type:
User
- Raises:
User.DoesNotExist – If no user matches the provided username or email, or if the user has an associated retirement request.
Module contents#
Open edX AuthZ provides the architecture and foundations of the authorization framework.