Skip to content

Commit

Permalink
feat: add has_course_author_access to CourseHomeMetadataView response
Browse files Browse the repository at this point in the history
Cherry-picked from openedx#35313
  • Loading branch information
0x29a committed Sep 9, 2024
1 parent 10aec43 commit bc10352
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 7 deletions.
14 changes: 8 additions & 6 deletions common/djangoapps/student/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def user_has_role(user, role):
return False


def get_user_permissions(user, course_key, org=None):
def get_user_permissions(user, course_key, org=None, service_variant=None):
"""
Get the bitmask of permissions that this user has in the given course context.
Can also set course_key=None and pass in an org to get the user's
Expand Down Expand Up @@ -103,7 +103,7 @@ def get_user_permissions(user, course_key, org=None):
# the LMS and Studio permissions will be separated as a part of this project. Once this is done (and this code is
# not removed during its implementation), we can replace the Limited Staff permissions with more granular ones.
if course_key and user_has_role(user, CourseLimitedStaffRole(course_key)):
if settings.SERVICE_VARIANT == 'lms':
if (service_variant or settings.SERVICE_VARIANT) == 'lms':
return STUDIO_EDIT_CONTENT
else:
return STUDIO_NO_PERMISSIONS
Expand All @@ -119,7 +119,7 @@ def get_user_permissions(user, course_key, org=None):
return STUDIO_NO_PERMISSIONS


def has_studio_write_access(user, course_key):
def has_studio_write_access(user, course_key, service_variant=None):
"""
Return True if user has studio write access to the given course.
Note that the CMS permissions model is with respect to courses.
Expand All @@ -131,15 +131,17 @@ def has_studio_write_access(user, course_key):
:param user:
:param course_key: a CourseKey
:param service_variant: the variant of the service (lms or cms). Permissions may differ between the two,
see the comment in get_user_permissions for more details.
"""
return bool(STUDIO_EDIT_CONTENT & get_user_permissions(user, course_key))
return bool(STUDIO_EDIT_CONTENT & get_user_permissions(user, course_key, service_variant=service_variant))


def has_course_author_access(user, course_key):
def has_course_author_access(user, course_key, service_variant=None):
"""
Old name for has_studio_write_access
"""
return has_studio_write_access(user, course_key)
return has_studio_write_access(user, course_key, service_variant)


def has_studio_advanced_settings_access(user):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ class CourseHomeMetadataSerializer(VerifiedModeSerializer):
can_view_certificate = serializers.BooleanField()
course_modes = CourseModeSerrializer(many=True)
is_new_discussion_sidebar_view_enabled = serializers.BooleanField()
has_course_author_access = serializers.BooleanField()
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@

from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.student.models import CourseEnrollment
from common.djangoapps.student.roles import CourseInstructorRole
from common.djangoapps.student.roles import (
CourseBetaTesterRole,
CourseInstructorRole,
CourseLimitedStaffRole,
CourseStaffRole
)
from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.course_home_api.tests.utils import BaseCourseHomeTests
from lms.djangoapps.courseware.toggles import (
Expand Down Expand Up @@ -248,3 +253,32 @@ def test_discussion_tab_visible(self, visible):
assert 'discussion' in tab_ids
else:
assert 'discussion' not in tab_ids

@ddt.data(
{
'course_team_role': None,
'has_course_author_access': False
},
{
'course_team_role': CourseBetaTesterRole,
'has_course_author_access': False
},
{
'course_team_role': CourseStaffRole,
'has_course_author_access': True
},
{
'course_team_role': CourseLimitedStaffRole,
'has_course_author_access': False
},
)
@ddt.unpack
def test_has_course_author_access_for_staff_roles(self, course_team_role, has_course_author_access):
CourseEnrollment.enroll(self.user, self.course.id, CourseMode.VERIFIED)

if course_team_role:
course_team_role(self.course.id).add_users(self.user)

response = self.client.get(self.url)
assert response.status_code == 200
assert response.data['has_course_author_access'] == has_course_author_access
7 changes: 7 additions & 0 deletions lms/djangoapps/course_home_api/course_metadata/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from openedx.core.djangoapps.courseware_api.utils import get_celebrations_dict

from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.student.auth import has_course_author_access
from common.djangoapps.student.models import CourseEnrollment
from lms.djangoapps.course_api.api import course_detail
from lms.djangoapps.course_goals.models import UserActivity
Expand Down Expand Up @@ -139,6 +140,12 @@ def get(self, request, *args, **kwargs):
'can_view_certificate': certificates_viewable_for_course(course),
'course_modes': course_modes,
'is_new_discussion_sidebar_view_enabled': new_discussion_sidebar_view_is_enabled(course_key),
# We check the course author access in the context of CMS here because this field is used
# to determine whether the user can access the course authoring tools in the CMS.
# This is a temporary solution until the course author role is split into "Course Author" and
# "Course Editor" as described in the permission matrix here:
# https://github.com/openedx/platform-roadmap/issues/246
'has_course_author_access': has_course_author_access(request.user, course_key, 'cms'),
}
context = self.get_serializer_context()
context['course'] = course
Expand Down

0 comments on commit bc10352

Please sign in to comment.