openedx_authz.models package#

Submodules#

openedx_authz.models.authz_migration module#

Models for tracking migration runs between legacy and AuthZ systems.

class openedx_authz.models.authz_migration.AuthzCourseAuthoringMigrationRun(*args, **kwargs)

Bases: Model

Track the status of course authoring migration tasks.

This model is used to track async migrations between the legacy CourseAccessRole system and the new AuthZ system.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

completed_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod create_running(migration_type, scope_type, scope_key, metadata=None) AuthzCourseAuthoringMigrationRun

Create a migration run in running state.

classmethod create_skipped(migration_type, scope_type, scope_key, metadata=None) AuthzCourseAuthoringMigrationRun

Create a migration run in skipped state.

created_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

get_migration_type_display(*, field=<django.db.models.fields.CharField: migration_type>)
get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)
get_next_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=True, **kwargs)
get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)
get_previous_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=False, **kwargs)
get_scope_type_display(*, field=<django.db.models.fields.CharField: scope_type>)
get_status_display(*, field=<django.db.models.fields.CharField: status>)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

mark_completed(*, metadata_updates=None) AuthzCourseAuthoringMigrationRun

Mark the migration run as completed.

mark_failed(*, exception=None) AuthzCourseAuthoringMigrationRun

Mark the migration run as failed.

mark_partial_success(*, metadata_updates=None) AuthzCourseAuthoringMigrationRun

Mark the migration run as partially successful.

metadata

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

migration_type

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>
save(*args, **kwargs) AuthzCourseAuthoringMigrationRun

Enforce at most one RUNNING record per (scope_type, scope_key).

MySQL does not support partial unique indexes, so this check is done at the application level. select_for_update() is used to reduce (but not fully eliminate) the race-condition window on concurrent inserts.

scope_key

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

scope_type

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

status

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

updated_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class openedx_authz.models.authz_migration.MigrationType(*values)

Bases: TextChoices

Direction of migration.

FORWARD = 'forward'
ROLLBACK = 'rollback'
class openedx_authz.models.authz_migration.ScopeType(*values)

Bases: TextChoices

Type of scope being migrated.

COURSE = 'course'
ORG = 'org'
class openedx_authz.models.authz_migration.Status(*values)

Bases: TextChoices

Status of the migration task.

COMPLETED = 'completed'
FAILED = 'failed'
PARTIAL_SUCCESS = 'partial_success'
RUNNING = 'running'
SKIPPED = 'skipped'

openedx_authz.models.core module#

Core models for the authorization framework.

These models will be used to store additional data about roles and permissions that are not natively supported by Casbin, so as to avoid modifying the Casbin schema that focuses on the core authorization logic.

class openedx_authz.models.core.BaseRegistryModel(*args, **kwargs)

Bases: Model

Base model that supports automatic subclass registration.

This model provides a registry mechanism for its subclasses, allowing dynamic retrieval of subclasses based on a namespace identifier.

Subclasses should define a NAMESPACE class attribute (e.g., ‘user’ for users) and implement get_or_create_for_external_key() classmethod.

class Meta

Bases: object

abstract = False
NAMESPACE: ClassVar[str] = None
classmethod get_registry() dict[str, type[BaseRegistryModel]]

Get the registry of subclasses.

Returns:

A dictionary mapping namespace strings to subclass types.

Return type:

dict

class openedx_authz.models.core.ExtendedCasbinRule(*args, **kwargs)

Bases: Model

Extended model for Casbin rules to store additional metadata.

This model extends the CasbinRule model provided by the casbin_adapter package to include additional fields for storing metadata about each rule.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

casbin_rule

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

casbin_rule_id
casbin_rule_key

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

classmethod create_based_on_policy(subject, role, scope, adapter)

Helper method to create an ExtendedCasbinRule based on policy components.

Parameters:
  • subject – SubjectData object with namespaced_key and external_key

  • role – RoleData object with namespaced_key and external_key

  • scope – ScopeData object with namespaced_key and external_key

  • adapter – The Casbin adapter instance.

Returns:

The created ExtendedCasbinRule instance.

Return type:

ExtendedCasbinRule

created_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

description

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

get_next_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=True, **kwargs)
get_next_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=True, **kwargs)
get_previous_by_created_at(*, field=<django.db.models.fields.DateTimeField: created_at>, is_next=False, **kwargs)
get_previous_by_updated_at(*, field=<django.db.models.fields.DateTimeField: updated_at>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

metadata

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>
scope

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

scope_id
subject

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

subject_id
updated_at

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class openedx_authz.models.core.RoleAssignmentAudit(*args, **kwargs)

Bases: Model

Model to audit role assignments and unassignments.

This model captures the history of role assignments and unassignments for subjects within specific scopes. It can be used for auditing purposes to track changes in role assignments over time.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

OPERATIONS = ('created', 'deleted')
class Operations(created, deleted)

Bases: NamedTuple

created: str

Alias for field number 0

deleted: str

Alias for field number 1

actor_id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

get_next_by_timestamp(*, field=<django.db.models.fields.DateTimeField: timestamp>, is_next=True, **kwargs)
get_operation_display(*, field=<django.db.models.fields.CharField: operation>)
get_previous_by_timestamp(*, field=<django.db.models.fields.DateTimeField: timestamp>, is_next=False, **kwargs)
id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.ManagerFromRoleAssignmentAuditQuerySet object>
operation

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

role

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

property role_display: str

Role name without the namespace prefix (e.g. library_admin for role^library_admin).

scope

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

property scope_display: str

Scope key without the namespace prefix (e.g. lib:Org1:lib1 for lib^lib:Org1:lib1).

subject

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

property subject_display: str

Subject key without the namespace prefix (e.g. john_doe for user^john_doe).

timestamp

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

class openedx_authz.models.core.RoleAssignmentAuditQuerySet(model=None, query=None, using=None, hints=None)

Bases: QuerySet

QuerySet for RoleAssignmentAudit with scope-based filtering.

for_scope_namespace(namespace: str) RoleAssignmentAuditQuerySet

Return records whose scope starts with the given namespace prefix.

Parameters:

namespace – The namespace to filter by (e.g. 'lib', 'course-v1'). Use the NAMESPACE class attribute from the corresponding ScopeData subclass (e.g. ContentLibraryData.NAMESPACE).

Returns:

Queryset filtered to records matching the scope type.

class openedx_authz.models.core.Scope(*args, **kwargs)

Bases: BaseRegistryModel

Model representing a scope in the authorization system.

This model can be extended to represent different types of scopes, such as courses or content libraries.

Subclasses should define a NAMESPACE class attribute (e.g., ‘lib’ for content libraries) and implement get_or_create_for_external_key() classmethod.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

casbin_rules

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

contentlibraryscope

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

coursescope

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <openedx_authz.models.core.ScopeManager object>
class openedx_authz.models.core.ScopeManager(*args, **kwargs)

Bases: Manager

Custom manager for Scope model that handles polymorphic behavior.

get_or_create_for_external_key(scope_data)

Get or create a Scope instance for the given scope data.

This method determines the appropriate subclass based on the namespace in the scope_data and delegates to that subclass’s get_or_create_for_external_key.

Parameters:

scope_data – The scope (ScopeData) object with NAMESPACE class attribute

Returns:

The Scope instance

Return type:

Scope

Raises:

ValueError – If the namespace is not registered

class openedx_authz.models.core.Subject(*args, **kwargs)

Bases: BaseRegistryModel

Model representing a subject in the authorization system.

This model can be extended to represent different types of subjects, such as users or groups.

Subclasses should define a NAMESPACE class attribute (e.g., ‘user’ for users) and implement get_or_create_for_external_key() classmethod.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

casbin_rules

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <openedx_authz.models.core.SubjectManager object>
usersubject

Accessor to the related object on the reverse side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

class openedx_authz.models.core.SubjectManager(*args, **kwargs)

Bases: Manager

Custom manager for Subject model that handles polymorphic behavior.

get_or_create_for_external_key(subject_data)

Get or create a Subject instance for the given subject data.

This method determines the appropriate subclass based on the namespace in the subject_data and delegates to that subclass’s get_or_create_for_external_key.

Parameters:

subject_data – The subject (SubjectData) object with NAMESPACE class attribute

Returns:

The Subject instance

Return type:

Subject

Raises:

ValueError – If the namespace is not registered

openedx_authz.models.engine module#

Models for the authorization engine.

class openedx_authz.models.engine.PolicyCacheControl(*args, **kwargs)

Bases: Model

Model to control policy cache invalidation.

This model can be used to trigger cache invalidation for authorization policies by changing the version. Whenever this model is updated, the authorization engine should invalidate its cached policies.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

classmethod get()

Get the singleton instance of the model.

classmethod get_version()

Get the version for policy cache control.

Returns:

The version of the last update.

Return type:

UUID

id

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

objects = <django.db.models.manager.Manager object>
save(*args, **kwargs)

Override save to ensure a single instance.

classmethod set_version(version: UUID)

Update the cache version.

This method updates the cache version, which can be used to signal that the policy cache should be invalidated.

version

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

openedx_authz.models.scopes module#

Models for ContentLibrary scopes in the authorization framework.

These models extend the base Scope model to represent content library scopes, which are used to define permissions and roles related to content libraries within the Open edX platform.

class openedx_authz.models.scopes.ContentLibraryScope(*args, **kwargs)

Bases: Scope

Scope representing a content library in the authorization system.

exception DoesNotExist

Bases: DoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

NAMESPACE: ClassVar[str] = 'lib'
content_library

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

content_library_id
classmethod get_or_create_for_external_key(scope) ContentLibraryScope

Get or create a ContentLibraryScope for the given external key.

Parameters:

scope – ScopeData object with an external_key attribute containing a LibraryLocatorV2-compatible string.

Returns:

The Scope instance for the given ContentLibrary,

or None if the scope is a glob pattern (contains wildcard).

Return type:

ContentLibraryScope

scope_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

scope_ptr_id
class openedx_authz.models.scopes.CourseScope(*args, **kwargs)

Bases: Scope

Scope representing a course in the authorization system.

exception DoesNotExist

Bases: DoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

NAMESPACE: ClassVar[str] = 'course-v1'
course_overview

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

course_overview_id
classmethod get_or_create_for_external_key(scope) CourseScope

Get or create a CourseScope for the given external key.

Parameters:

scope – ScopeData object with an external_key attribute containing a CourseKey string.

Returns:

The Scope instance for the given CourseOverview,

or None if the scope is a glob pattern (contains wildcard).

Return type:

CourseScope

scope_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

scope_ptr_id
openedx_authz.models.scopes.get_content_library_model()

Return the ContentLibrary model class specified by settings.

The setting OPENEDX_AUTHZ_CONTENT_LIBRARY_MODEL should be an app_label.ModelName string (e.g. ‘content_libraries.ContentLibrary’).

openedx_authz.models.scopes.get_course_overview_model()

Return the CourseOverview model class specified by settings.

The setting OPENEDX_AUTHZ_COURSE_OVERVIEW_MODEL should be an app_label.ModelName string (e.g. ‘course_overviews.CourseOverview’).

openedx_authz.models.subjects module#

Models for User subjects in the authorization framework.

These models extend the base Subject model to represent user subjects, which are used to define permissions and roles related to users within the Open edX platform.

class openedx_authz.models.subjects.UserSubject(*args, **kwargs)

Bases: Subject

Subject representing a user in the authorization system.

exception DoesNotExist

Bases: DoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

NAMESPACE: ClassVar[str] = 'user'
classmethod get_or_create_for_external_key(subject)

Get or create a UserSubject for the given external key.

Parameters:

subject_external_key – Username string

Returns:

The Subject instance for the given User

Return type:

UserSubject

subject_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example:

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

subject_ptr_id
user

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

user_id

Module contents#

Database models for the authorization framework.

These models will be used to store additional data about roles and permissions that are not natively supported by Casbin, so as to avoid modifying the Casbin schema that focuses on the core authorization logic.

For example, we may want to store metadata about roles, such as a description or the date it was created.

This model is transversal to the implementation of the public API for authorization, which is defined in openedx_authz.api. So it can be used by various functions in the API to store and retrieve additional data about roles and permissions. That’s why we avoid coupling this model to too specific concepts and also importing too specific classes from the API to avoid circular dependencies.