-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add CourseRolesService model * feat: add CourseRolesRole model * feat: add CourseRolesPermission model * feat: add CourseRolesRolePermissions model * feat: add CourseRolesUserRole model * feat: remove wrong unique_together in CourseRolesUserRole * feat: add coures_roles app to cms and lms common envs * feat: add migrations * feat: delete wrong migration * feat: change many to many relationships to foreign keys * feat: add many to many relationships between role-user and role-permission * feat: add initial migration * docs: add readme file * docs: update readme file * chore: add course_roles in quality matrix CI * feat: remove fields related to custom roles * docs: update docstrings * feat: add minimal string representation change * feat: remove descriptions from role and permission tables * feat: swich the role to service relationship into a many to many relationship * docs: update role docstring * feat: update initial migration * feat: change on_delete for org and coures on UserRole model to cascade * feat: update initial migration * docs: update CourseRolesPermission model docstring
- Loading branch information
1 parent
edc80c2
commit 11f0f79
Showing
7 changed files
with
209 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
Course Roles | ||
############################# | ||
|
||
Status: Development | ||
|
||
Purpose | ||
******* | ||
|
||
The intention of this app is to to make course level roles for users within LMS/CMS more flexible. | ||
|
||
Responsibilities | ||
*************** | ||
|
||
Add models to manage the course roles and their permissions. | ||
Provide a helper to check if a user has a specific permission in a course. |
84 changes: 84 additions & 0 deletions
84
openedx/core/djangoapps/course_roles/migrations/0001_initial.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
# Generated by Django 3.2.20 on 2023-09-12 22:03 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('organizations', '0004_auto_20230727_2054'), | ||
('course_overviews', '0029_alter_historicalcourseoverview_options'), | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='CourseRolesPermission', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.CharField(max_length=255, unique=True)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='CourseRolesRole', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.CharField(max_length=255)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='CourseRolesService', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('name', models.CharField(max_length=255, unique=True)), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='CourseRolesUserRole', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('course', models.ForeignKey(db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='course_overviews.courseoverview')), | ||
('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organizations.organization')), | ||
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course_roles.courserolesrole')), | ||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | ||
], | ||
options={ | ||
'unique_together': {('user', 'role', 'course')}, | ||
}, | ||
), | ||
migrations.CreateModel( | ||
name='CourseRolesRoleService', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course_roles.courserolesrole')), | ||
('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course_roles.courserolesservice')), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='CourseRolesRolePermissions', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course_roles.courserolespermission')), | ||
('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='course_roles.courserolesrole')), | ||
], | ||
), | ||
migrations.AddField( | ||
model_name='courserolesrole', | ||
name='permissions', | ||
field=models.ManyToManyField(through='course_roles.CourseRolesRolePermissions', to='course_roles.CourseRolesPermission'), | ||
), | ||
migrations.AddField( | ||
model_name='courserolesrole', | ||
name='services', | ||
field=models.ManyToManyField(through='course_roles.CourseRolesRoleService', to='course_roles.CourseRolesService'), | ||
), | ||
migrations.AddField( | ||
model_name='courserolesrole', | ||
name='users', | ||
field=models.ManyToManyField(through='course_roles.CourseRolesUserRole', to=settings.AUTH_USER_MODEL), | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
""" | ||
Models for course roles schema | ||
""" | ||
from django.contrib.auth import get_user_model | ||
from django.db import models | ||
|
||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview | ||
from organizations.models import Organization | ||
|
||
User = get_user_model() | ||
|
||
|
||
class CourseRolesRole(models.Model): | ||
""" | ||
Model for a course roles role. | ||
A role is a collection of permissions that can be assigned to a user. | ||
The services field defines for which service UI the role is intended, such as CMS and/or LMS. | ||
""" | ||
name = models.CharField(max_length=255) | ||
services = models.ManyToManyField('CourseRolesService', through='CourseRolesRoleService') | ||
permissions = models.ManyToManyField('CourseRolesPermission', through='CourseRolesRolePermissions') | ||
users = models.ManyToManyField(User, through='CourseRolesUserRole') | ||
|
||
def __str__(self): | ||
return self.name | ||
|
||
|
||
class CourseRolesPermission(models.Model): | ||
""" | ||
Model for a course roles permission. | ||
A permission represents what a user can do. | ||
""" | ||
name = models.CharField(max_length=255, unique=True) | ||
|
||
def __str__(self): | ||
return self.name | ||
|
||
|
||
class CourseRolesRolePermissions(models.Model): | ||
""" | ||
Model for a course roles role permission. | ||
A role permission is a mapping between a role and a permission. | ||
""" | ||
role = models.ForeignKey('CourseRolesRole', on_delete=models.CASCADE) | ||
permission = models.ForeignKey('CourseRolesPermission', on_delete=models.CASCADE) | ||
|
||
def __str__(self): | ||
return f"{self.role} - {self.permission}" | ||
|
||
|
||
class CourseRolesUserRole(models.Model): | ||
""" | ||
Model for a course roles user role. | ||
A user role is a mapping between a user, a role, a course and an organization. | ||
If the course is null, the user role is for the organization. | ||
If the course and the organization are null the role is for the instance. | ||
""" | ||
user = models.ForeignKey(User, on_delete=models.CASCADE) | ||
role = models.ForeignKey('CourseRolesRole', on_delete=models.CASCADE) | ||
course = models.ForeignKey( | ||
CourseOverview, | ||
db_constraint=False, | ||
on_delete=models.CASCADE, | ||
null=True, | ||
) | ||
org = models.ForeignKey(Organization, on_delete=models.CASCADE, null=False) | ||
|
||
class Meta: | ||
unique_together = ('user', 'role', 'course') | ||
|
||
def __str__(self): | ||
return f"{self.user} - {self.course} - {self.role} - {self.org}" | ||
|
||
|
||
class CourseRolesService(models.Model): | ||
""" | ||
Model for a course roles service. | ||
A service is a UI that can be used to assign roles to users. | ||
Such as CMS or LMS. | ||
""" | ||
name = models.CharField(max_length=255, unique=True) | ||
|
||
def __str__(self): | ||
return self.name | ||
|
||
|
||
class CourseRolesRoleService(models.Model): | ||
""" | ||
Model for a course roles role service. | ||
A role service is a mapping between a role and a service. | ||
""" | ||
role = models.ForeignKey('CourseRolesRole', on_delete=models.CASCADE) | ||
service = models.ForeignKey('CourseRolesService', on_delete=models.CASCADE) | ||
|
||
def __str__(self): | ||
return f"{self.role} - {self.service}" |