Commit 8dc84bec by Matjaz Gregoric

Enable discussions on CCX courses.

Discussion is restricted to the CCX course (there is no sharing of
discussions with the parent course or other CCX instances).
parent 2251097c
......@@ -46,7 +46,14 @@ def assign_default_role(course_id, user):
"""
Assign forum default role 'Student' to user
"""
role, __ = Role.objects.get_or_create(course_id=course_id, name=FORUM_ROLE_STUDENT)
assign_role(course_id, user, FORUM_ROLE_STUDENT)
def assign_role(course_id, user, rolename):
"""
Assign forum role `rolename` to user
"""
role, __ = Role.objects.get_or_create(course_id=course_id, name=rolename)
user.roles.add(role)
......
from django_comment_common.models import Role
"""
Common comment client utility functions.
"""
from django_comment_common.models import Role, FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, \
FORUM_ROLE_COMMUNITY_TA, FORUM_ROLE_STUDENT
class ThreadContext(object):
......@@ -7,14 +12,14 @@ class ThreadContext(object):
COURSE = 'course'
_STUDENT_ROLE_PERMISSIONS = ["vote", "update_thread", "follow_thread", "unfollow_thread",
"update_comment", "create_sub_comment", "unvote", "create_thread",
"follow_commentable", "unfollow_commentable", "create_comment", ]
STUDENT_ROLE_PERMISSIONS = ["vote", "update_thread", "follow_thread", "unfollow_thread",
"update_comment", "create_sub_comment", "unvote", "create_thread",
"follow_commentable", "unfollow_commentable", "create_comment", ]
_MODERATOR_ROLE_PERMISSIONS = ["edit_content", "delete_thread", "openclose_thread",
"endorse_comment", "delete_comment", "see_all_cohorts"]
MODERATOR_ROLE_PERMISSIONS = ["edit_content", "delete_thread", "openclose_thread",
"endorse_comment", "delete_comment", "see_all_cohorts"]
_ADMINISTRATOR_ROLE_PERMISSIONS = ["manage_moderator"]
ADMINISTRATOR_ROLE_PERMISSIONS = ["manage_moderator"]
def _save_forum_role(course_key, name):
......@@ -34,18 +39,18 @@ def seed_permissions_roles(course_key):
"""
Create and assign permissions for forum roles
"""
administrator_role = _save_forum_role(course_key, "Administrator")
moderator_role = _save_forum_role(course_key, "Moderator")
community_ta_role = _save_forum_role(course_key, "Community TA")
student_role = _save_forum_role(course_key, "Student")
administrator_role = _save_forum_role(course_key, FORUM_ROLE_ADMINISTRATOR)
moderator_role = _save_forum_role(course_key, FORUM_ROLE_MODERATOR)
community_ta_role = _save_forum_role(course_key, FORUM_ROLE_COMMUNITY_TA)
student_role = _save_forum_role(course_key, FORUM_ROLE_STUDENT)
for per in _STUDENT_ROLE_PERMISSIONS:
for per in STUDENT_ROLE_PERMISSIONS:
student_role.add_permission(per)
for per in _MODERATOR_ROLE_PERMISSIONS:
for per in MODERATOR_ROLE_PERMISSIONS:
moderator_role.add_permission(per)
for per in _ADMINISTRATOR_ROLE_PERMISSIONS:
for per in ADMINISTRATOR_ROLE_PERMISSIONS:
administrator_role.add_permission(per)
moderator_role.inherit_permissions(student_role)
......@@ -62,21 +67,21 @@ def are_permissions_roles_seeded(course_id):
the database
"""
try:
administrator_role = Role.objects.get(name="Administrator", course_id=course_id)
moderator_role = Role.objects.get(name="Moderator", course_id=course_id)
student_role = Role.objects.get(name="Student", course_id=course_id)
administrator_role = Role.objects.get(name=FORUM_ROLE_ADMINISTRATOR, course_id=course_id)
moderator_role = Role.objects.get(name=FORUM_ROLE_MODERATOR, course_id=course_id)
student_role = Role.objects.get(name=FORUM_ROLE_STUDENT, course_id=course_id)
except:
return False
for per in _STUDENT_ROLE_PERMISSIONS:
for per in STUDENT_ROLE_PERMISSIONS:
if not student_role.has_permission(per):
return False
for per in _MODERATOR_ROLE_PERMISSIONS + _STUDENT_ROLE_PERMISSIONS:
for per in MODERATOR_ROLE_PERMISSIONS + STUDENT_ROLE_PERMISSIONS:
if not moderator_role.has_permission(per):
return False
for per in _ADMINISTRATOR_ROLE_PERMISSIONS + _MODERATOR_ROLE_PERMISSIONS + _STUDENT_ROLE_PERMISSIONS:
for per in ADMINISTRATOR_ROLE_PERMISSIONS + MODERATOR_ROLE_PERMISSIONS + STUDENT_ROLE_PERMISSIONS:
if not administrator_role.has_permission(per):
return False
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import logging
from ccx_keys.locator import CCXLocator
from courseware.courses import get_course_by_id
from django.db import migrations
from django.http import Http404
from django_comment_common.models import FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, \
FORUM_ROLE_COMMUNITY_TA, FORUM_ROLE_STUDENT
from django_comment_common.utils import STUDENT_ROLE_PERMISSIONS, MODERATOR_ROLE_PERMISSIONS, \
ADMINISTRATOR_ROLE_PERMISSIONS
log = logging.getLogger("edx.ccx")
def seed_forum_roles_for_existing_ccx(apps, schema_editor):
"""
Seed forum roles and make CCX coach forum admin for respective CCX(s).
Arguments:
apps (Applications): Apps in edX platform.
schema_editor (SchemaEditor): For editing database schema i.e create, delete field (column)
"""
CustomCourseForEdX = apps.get_model("ccx", "CustomCourseForEdX")
Role = apps.get_model("django_comment_common", "Role")
Permission = apps.get_model("django_comment_common", "Permission")
db_alias = schema_editor.connection.alias
# This will need to be changed if ccx gets moved out of the default db for some reason.
if db_alias != 'default':
log.info("Skipping CCX migration on non-default database.")
return
for ccx in CustomCourseForEdX.objects.all():
if not ccx.course_id or ccx.course_id.deprecated:
# prevent migration for deprecated course ids or invalid ids.
log.warning(
"Skipping CCX %s due to invalid or deprecated course_id: %s.",
ccx.id,
ccx.course_id
)
continue
ccx_locator = CCXLocator.from_course_locator(ccx.course_id, unicode(ccx.id))
# Create forum roles.
admin_role, _ = Role.objects.get_or_create(name=FORUM_ROLE_ADMINISTRATOR, course_id=ccx_locator)
moderator_role, _ = Role.objects.get_or_create(name=FORUM_ROLE_MODERATOR, course_id=ccx_locator)
community_ta_role, _ = Role.objects.get_or_create(name=FORUM_ROLE_COMMUNITY_TA, course_id=ccx_locator)
student_role, _ = Role.objects.get_or_create(name=FORUM_ROLE_STUDENT, course_id=ccx_locator)
# Add permissions for each role.
for name in ADMINISTRATOR_ROLE_PERMISSIONS:
admin_role.permissions.add(Permission.objects.get_or_create(name=name)[0])
for name in MODERATOR_ROLE_PERMISSIONS:
moderator_role.permissions.add(Permission.objects.get_or_create(name=name)[0])
for name in STUDENT_ROLE_PERMISSIONS:
student_role.permissions.add(Permission.objects.get_or_create(name=name)[0])
for permission in student_role.permissions.all():
moderator_role.permissions.add(permission)
for permission in moderator_role.permissions.all():
community_ta_role.permissions.add(permission)
for permission in moderator_role.permissions.all():
admin_role.permissions.add(permission)
# Make CCX coach forum admin.
ccx.coach.roles.add(admin_role)
log.info("Seeded forum permissions for CCX %s", ccx_locator)
class Migration(migrations.Migration):
dependencies = [
('ccx', '0003_add_master_course_staff_in_ccx'),
('django_comment_common', '0002_forumsconfig'),
]
operations = [
migrations.RunPython(code=seed_forum_roles_for_existing_ccx, reverse_code=migrations.RunPython.noop)
]
......@@ -17,6 +17,9 @@ from courseware.tests.factories import StudentModuleFactory
from courseware.tests.helpers import LoginEnrollmentTestCase
from courseware.tabs import get_course_tab_list
from courseware.testutils import FieldOverrideTestMixin
from django_comment_client.utils import has_forum_access
from django_comment_common.models import FORUM_ROLE_ADMINISTRATOR
from django_comment_common.utils import are_permissions_roles_seeded
from instructor.access import (
allow_access,
list_with_level,
......@@ -423,6 +426,10 @@ class TestCoachDashboard(CcxTestCase, LoginEnrollmentTestCase):
list_staff_master_course = list_with_level(self.course, 'staff')
list_instructor_master_course = list_with_level(self.course, 'instructor')
# assert that forum roles are seeded
self.assertTrue(are_permissions_roles_seeded(course_key))
self.assertTrue(has_forum_access(self.coach.username, course_key, FORUM_ROLE_ADMINISTRATOR))
with ccx_course(course_key) as course_ccx:
list_staff_ccx_course = list_with_level(course_ccx, 'staff')
self.assertEqual(len(list_staff_master_course), len(list_staff_ccx_course))
......
......@@ -30,6 +30,8 @@ from courseware.access import has_access
from courseware.courses import get_course_by_id
from courseware.field_overrides import disable_overrides
from django_comment_common.models import FORUM_ROLE_ADMINISTRATOR, assign_role
from django_comment_common.utils import seed_permissions_roles
from edxmako.shortcuts import render_to_response
from lms.djangoapps.grades.course_grades import iterate_grades_for
from opaque_keys.edx.keys import CourseKey
......@@ -220,6 +222,11 @@ def create_ccx(request, course, ccx=None):
ccx_id = CCXLocator.from_course_locator(course.id, unicode(ccx.id))
# Create forum roles
seed_permissions_roles(ccx_id)
# Assign administrator forum role to CCX coach
assign_role(ccx_id, request.user, FORUM_ROLE_ADMINISTRATOR)
url = reverse('ccx_coach_dashboard', kwargs={'course_id': ccx_id})
# Enroll the coach in the course
......
......@@ -14,7 +14,6 @@ import pystache_custom as pystache
from opaque_keys.edx.locations import i4xEncoder
from opaque_keys.edx.keys import CourseKey
from xmodule.modulestore.django import modulestore
from lms.djangoapps.ccx.overrides import get_current_ccx
from django_comment_common.models import Role, FORUM_ROLE_STUDENT
from django_comment_client.permissions import check_permissions_by_view, has_permission, get_team
......@@ -806,11 +805,8 @@ def is_commentable_cohorted(course_key, commentable_id):
def is_discussion_enabled(course_id):
"""
Return True if Discussion is enabled for a course; else False
Return True if discussions are enabled; else False
"""
if settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
if get_current_ccx(course_id):
return False
return settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment