From 3c5abde2cbca243b53118c5b16ab9235588685ac Mon Sep 17 00:00:00 2001 From: salman2013 Date: Tue, 20 Jan 2026 22:43:08 +0500 Subject: [PATCH 1/9] chore: discussion service to enable permission and access provider --- cms/djangoapps/contentstore/views/preview.py | 2 ++ lms/djangoapps/courseware/block_render.py | 2 ++ .../core/djangoapps/discussions/services.py | 29 +++++++++++++++++++ .../core/djangoapps/xblock/runtime/runtime.py | 3 ++ 4 files changed, 36 insertions(+) create mode 100644 openedx/core/djangoapps/discussions/services.py diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 05fc1705e83e..dd3baa2825d8 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -19,6 +19,7 @@ from xblock.runtime import KvsFieldData from openedx.core.djangoapps.video_config.services import VideoConfigService +from openedx.core.djangoapps.discussions.services import DiscussionConfigService from xmodule.contentstore.django import contentstore from xmodule.exceptions import NotFoundError as XModuleNotFoundError from xmodule.modulestore.django import XBlockI18nService, modulestore @@ -217,6 +218,7 @@ def _prepare_runtime_for_preview(request, block): "cache": CacheService(cache), 'replace_urls': ReplaceURLService, 'video_config': VideoConfigService(), + 'discussion_config': DiscussionConfigService(), } block.runtime.get_block_for_descriptor = partial(_load_preview_block, request) diff --git a/lms/djangoapps/courseware/block_render.py b/lms/djangoapps/courseware/block_render.py index b6e4145e2ecf..275f86e0b581 100644 --- a/lms/djangoapps/courseware/block_render.py +++ b/lms/djangoapps/courseware/block_render.py @@ -43,6 +43,7 @@ from lms.djangoapps.teams.services import TeamsService from openedx.core.djangoapps.video_config.services import VideoConfigService +from openedx.core.djangoapps.discussions.services import DiscussionConfigService from openedx.core.lib.xblock_services.call_to_action import CallToActionService from xmodule.contentstore.django import contentstore from xmodule.exceptions import NotFoundError as XModuleNotFoundError @@ -637,6 +638,7 @@ def inner_get_block(block: XBlock) -> XBlock | None: 'publish': EventPublishingService(user, course_id, track_function), 'enrollments': EnrollmentsService(), 'video_config': VideoConfigService(), + 'discussion_config': DiscussionConfigService(), } runtime.get_block_for_descriptor = inner_get_block diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py new file mode 100644 index 000000000000..22fdeb48516a --- /dev/null +++ b/openedx/core/djangoapps/discussions/services.py @@ -0,0 +1,29 @@ +""" +Discussion Configuration Service for XBlock runtime. + +This service provides discussion-related configuration and feature flags +that are specific to the edx-platform implementation +for the extracted discussion block in xblocks-contrib repository. +""" + +from django.conf import settings +from lms.djangoapps.discussion.django_comment_client.permissions import has_permission +from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, Provider + +class DiscussionConfigService: + + def discussion_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring + return has_permission(user, permission, course_id) + + def is_discussion_visible(self, course_key): + """ + Discussion Xblock does not support new OPEN_EDX provider + """ + provider = DiscussionsConfiguration.get(course_key) + return provider.provider_type == Provider.LEGACY + + def is_discussion_enabled(): + """ + Return True if discussions are enabled; else False + """ + return settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE') diff --git a/openedx/core/djangoapps/xblock/runtime/runtime.py b/openedx/core/djangoapps/xblock/runtime/runtime.py index 2ae4a431bfbe..df3c8958de0a 100644 --- a/openedx/core/djangoapps/xblock/runtime/runtime.py +++ b/openedx/core/djangoapps/xblock/runtime/runtime.py @@ -347,6 +347,9 @@ def service(self, block: XBlock, service_name: str): # Import here to avoid circular dependency from openedx.core.djangoapps.video_config.services import VideoConfigService return VideoConfigService() + elif service_name == 'discussion_config': + from openedx.core.djangoapps.discussions.services import DiscussionConfigService + return DiscussionConfigService() # Otherwise, fall back to the base implementation which loads services # defined in the constructor: From 45239cd91b8dc0a4525391742fcf244ac9b4567b Mon Sep 17 00:00:00 2001 From: salman2013 Date: Wed, 21 Jan 2026 11:19:46 +0500 Subject: [PATCH 2/9] fix: fix quality tests --- openedx/core/djangoapps/discussions/services.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py index 22fdeb48516a..5793264d1dd0 100644 --- a/openedx/core/djangoapps/discussions/services.py +++ b/openedx/core/djangoapps/discussions/services.py @@ -10,6 +10,7 @@ from lms.djangoapps.discussion.django_comment_client.permissions import has_permission from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, Provider + class DiscussionConfigService: def discussion_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring @@ -22,7 +23,7 @@ def is_discussion_visible(self, course_key): provider = DiscussionsConfiguration.get(course_key) return provider.provider_type == Provider.LEGACY - def is_discussion_enabled(): + def is_discussion_enabled(self): """ Return True if discussions are enabled; else False """ From 459406c7441a9e4240b608bb63fb1e5445d520de Mon Sep 17 00:00:00 2001 From: salman2013 Date: Wed, 21 Jan 2026 11:27:49 +0500 Subject: [PATCH 3/9] fix: fix quality tests --- .../core/djangoapps/discussions/services.py | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py index 5793264d1dd0..8e04e47b4e4f 100644 --- a/openedx/core/djangoapps/discussions/services.py +++ b/openedx/core/djangoapps/discussions/services.py @@ -6,15 +6,31 @@ for the extracted discussion block in xblocks-contrib repository. """ +from edx_django_utils.cache import DEFAULT_REQUEST_CACHE +from opaque_keys.edx.keys import CourseKey + from django.conf import settings -from lms.djangoapps.discussion.django_comment_client.permissions import has_permission +from openedx.core.djangoapps.django_comment_common.models import ( + all_permissions_for_user_in_course +) from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, Provider class DiscussionConfigService: def discussion_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring - return has_permission(user, permission, course_id) + assert isinstance(course_id, (type(None), CourseKey)) + request_cache_dict = DEFAULT_REQUEST_CACHE.data + cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format( + user.id, course_id + ) + if cache_key in request_cache_dict: + all_permissions = request_cache_dict[cache_key] + else: + all_permissions = all_permissions_for_user_in_course(user, course_id) + request_cache_dict[cache_key] = all_permissions + + return permission in all_permissions def is_discussion_visible(self, course_key): """ From be10fd9c148ba64c43fe0e22816c6a22bc786854 Mon Sep 17 00:00:00 2001 From: salman2013 Date: Wed, 21 Jan 2026 11:47:51 +0500 Subject: [PATCH 4/9] fix: fix quality tests --- openedx/core/djangoapps/discussions/services.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py index 8e04e47b4e4f..22ec1f1a0315 100644 --- a/openedx/core/djangoapps/discussions/services.py +++ b/openedx/core/djangoapps/discussions/services.py @@ -17,7 +17,10 @@ class DiscussionConfigService: - + """ + Service for providing video-related configuration and feature flags. + """ + def discussion_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring assert isinstance(course_id, (type(None), CourseKey)) request_cache_dict = DEFAULT_REQUEST_CACHE.data From 5a7e7960323583370df809b700ba1cfb6e2e12ef Mon Sep 17 00:00:00 2001 From: salman2013 Date: Wed, 21 Jan 2026 11:51:57 +0500 Subject: [PATCH 5/9] fix: fix quality tests --- openedx/core/djangoapps/discussions/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py index 22ec1f1a0315..239ac640d1b6 100644 --- a/openedx/core/djangoapps/discussions/services.py +++ b/openedx/core/djangoapps/discussions/services.py @@ -20,7 +20,7 @@ class DiscussionConfigService: """ Service for providing video-related configuration and feature flags. """ - + def discussion_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring assert isinstance(course_id, (type(None), CourseKey)) request_cache_dict = DEFAULT_REQUEST_CACHE.data From fb78b42964abbdab283e438f62be6da749ce30ff Mon Sep 17 00:00:00 2001 From: salman2013 Date: Wed, 21 Jan 2026 18:08:02 +0500 Subject: [PATCH 6/9] fix: fix quality tests --- openedx/core/djangoapps/discussions/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py index 239ac640d1b6..8617cbf43d9a 100644 --- a/openedx/core/djangoapps/discussions/services.py +++ b/openedx/core/djangoapps/discussions/services.py @@ -21,7 +21,7 @@ class DiscussionConfigService: Service for providing video-related configuration and feature flags. """ - def discussion_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring + def has_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring assert isinstance(course_id, (type(None), CourseKey)) request_cache_dict = DEFAULT_REQUEST_CACHE.data cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format( From a461a75adde238512c6594920760c3d13941ea3a Mon Sep 17 00:00:00 2001 From: salman2013 Date: Fri, 23 Jan 2026 12:17:02 +0500 Subject: [PATCH 7/9] chore: move discussion permission method's place and use it in service --- .../django_comment_client/base/views.py | 4 +-- .../django_comment_client/permissions.py | 17 +-------- .../discussion/django_comment_client/utils.py | 4 +-- .../discussion/discussion_profile_page.html | 2 +- lms/djangoapps/discussion/views.py | 2 +- .../core/djangoapps/discussions/services.py | 23 +++--------- .../django_comment_common/models.py | 35 +++++++++++++++++++ .../course_bookmarks/course-bookmarks.html | 2 +- xmodule/discussion_block.py | 20 ++++++++--- 9 files changed, 63 insertions(+), 46 deletions(-) diff --git a/lms/djangoapps/discussion/django_comment_client/base/views.py b/lms/djangoapps/discussion/django_comment_client/base/views.py index 14ce9c4b575a..e40ee4ef58bb 100644 --- a/lms/djangoapps/discussion/django_comment_client/base/views.py +++ b/lms/djangoapps/discussion/django_comment_client/base/views.py @@ -25,6 +25,7 @@ import lms.djangoapps.discussion.django_comment_client.settings as cc_settings import openedx.core.djangoapps.django_comment_common.comment_client as cc +from openedx.core.djangoapps.django_comment_common.models import has_permission from common.djangoapps.student.roles import GlobalStaff from common.djangoapps.track import contexts from common.djangoapps.util.file import store_uploaded_file @@ -33,8 +34,7 @@ from lms.djangoapps.courseware.exceptions import CourseAccessRedirect from lms.djangoapps.discussion.django_comment_client.permissions import ( check_permissions_by_view, - get_team, - has_permission + get_team ) from lms.djangoapps.discussion.django_comment_client.utils import ( JsonError, diff --git a/lms/djangoapps/discussion/django_comment_client/permissions.py b/lms/djangoapps/discussion/django_comment_client/permissions.py index 2eeee32fe722..4801a461c608 100644 --- a/lms/djangoapps/discussion/django_comment_client/permissions.py +++ b/lms/djangoapps/discussion/django_comment_client/permissions.py @@ -12,26 +12,11 @@ from openedx.core.djangoapps.django_comment_common.comment_client import Thread from openedx.core.djangoapps.django_comment_common.models import ( CourseDiscussionSettings, - all_permissions_for_user_in_course + has_permission ) from openedx.core.lib.cache_utils import request_cached -def has_permission(user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring - assert isinstance(course_id, (type(None), CourseKey)) - request_cache_dict = DEFAULT_REQUEST_CACHE.data - cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format( - user.id, course_id - ) - if cache_key in request_cache_dict: - all_permissions = request_cache_dict[cache_key] - else: - all_permissions = all_permissions_for_user_in_course(user, course_id) - request_cache_dict[cache_key] = all_permissions - - return permission in all_permissions - - CONDITIONS = ['is_open', 'is_author', 'is_question_author', 'is_team_member_if_applicable'] diff --git a/lms/djangoapps/discussion/django_comment_client/utils.py b/lms/djangoapps/discussion/django_comment_client/utils.py index e26b748270e3..a0bb6b769183 100644 --- a/lms/djangoapps/discussion/django_comment_client/utils.py +++ b/lms/djangoapps/discussion/django_comment_client/utils.py @@ -24,10 +24,10 @@ from lms.djangoapps.discussion.django_comment_client.constants import TYPE_ENTRY, TYPE_SUBCATEGORY from lms.djangoapps.discussion.django_comment_client.permissions import ( check_permissions_by_view, - get_team, - has_permission + get_team ) from lms.djangoapps.discussion.django_comment_client.settings import MAX_COMMENT_DEPTH +from openedx.core.djangoapps.django_comment_common.models import has_permission from openedx.core.djangoapps.course_groups.cohorts import get_cohort_id from openedx.core.djangoapps.discussions.utils import ( get_accessible_discussion_xblocks, diff --git a/lms/djangoapps/discussion/templates/discussion/discussion_profile_page.html b/lms/djangoapps/discussion/templates/discussion/discussion_profile_page.html index f88c33440ce7..90f03999d539 100644 --- a/lms/djangoapps/discussion/templates/discussion/discussion_profile_page.html +++ b/lms/djangoapps/discussion/templates/discussion/discussion_profile_page.html @@ -11,7 +11,7 @@ from django.template.defaultfilters import escapejs from django.urls import reverse -from lms.djangoapps.discussion.django_comment_client.permissions import has_permission +from openedx.core.djangoapps.django_comment_common.models import has_permission from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string %> diff --git a/lms/djangoapps/discussion/views.py b/lms/djangoapps/discussion/views.py index d6f61d209433..bca6cb7768de 100644 --- a/lms/djangoapps/discussion/views.py +++ b/lms/djangoapps/discussion/views.py @@ -28,6 +28,7 @@ import lms.djangoapps.discussion.django_comment_client.utils as utils import openedx.core.djangoapps.django_comment_common.comment_client as cc +from openedx.core.djangoapps.django_comment_common.models import has_permission from common.djangoapps.student.models import CourseEnrollment from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole, GlobalStaff from common.djangoapps.util.json_request import JsonResponse, expect_json @@ -37,7 +38,6 @@ from lms.djangoapps.discussion.config.settings import is_forum_daily_digest_enabled from lms.djangoapps.discussion.django_comment_client.base.views import track_thread_viewed_event from lms.djangoapps.discussion.django_comment_client.constants import TYPE_ENTRY -from lms.djangoapps.discussion.django_comment_client.permissions import has_permission from lms.djangoapps.discussion.django_comment_client.utils import ( add_courseware_context, course_discussion_division_enabled, diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py index 8617cbf43d9a..e9f9c51ffb22 100644 --- a/openedx/core/djangoapps/discussions/services.py +++ b/openedx/core/djangoapps/discussions/services.py @@ -6,13 +6,8 @@ for the extracted discussion block in xblocks-contrib repository. """ -from edx_django_utils.cache import DEFAULT_REQUEST_CACHE -from opaque_keys.edx.keys import CourseKey - from django.conf import settings -from openedx.core.djangoapps.django_comment_common.models import ( - all_permissions_for_user_in_course -) +from openedx.core.djangoapps.django_comment_common.models import has_permission from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, Provider @@ -22,18 +17,10 @@ class DiscussionConfigService: """ def has_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring - assert isinstance(course_id, (type(None), CourseKey)) - request_cache_dict = DEFAULT_REQUEST_CACHE.data - cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format( - user.id, course_id - ) - if cache_key in request_cache_dict: - all_permissions = request_cache_dict[cache_key] - else: - all_permissions = all_permissions_for_user_in_course(user, course_id) - request_cache_dict[cache_key] = all_permissions - - return permission in all_permissions + """ + Return the discussion permission for a user in a given course. + """ + return has_permission(user, permission, course_id) def is_discussion_visible(self, course_key): """ diff --git a/openedx/core/djangoapps/django_comment_common/models.py b/openedx/core/djangoapps/django_comment_common/models.py index bd7b8fe66e67..58e07e00ce8f 100644 --- a/openedx/core/djangoapps/django_comment_common/models.py +++ b/openedx/core/djangoapps/django_comment_common/models.py @@ -14,6 +14,8 @@ from django.utils.translation import gettext_noop from jsonfield.fields import JSONField from opaque_keys.edx.django.models import CourseKeyField +from edx_django_utils.cache import DEFAULT_REQUEST_CACHE +from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.xmodule_django.models import NoneToEmptyManager from openedx.core.lib.cache_utils import request_cached @@ -193,6 +195,39 @@ def all_permissions_for_user_in_course(user, course_id): return permission_names +def has_permission(user, permission, course_id=None): + """ + Check whether a user has a specific discussion permission within a course. + + This function resolves all discussion-related permissions for the given + user and course, caches them for the duration of the request, and verifies + whether the requested permission is present. + + Args: + user (User): Django user whose permissions are being checked. + permission (str): Discussion permission identifier to check for + (e.g., "create_comment", "create_thread"). + course_id (CourseKey): Course context in which to evaluate + the permission + + Returns: + bool: True if the user has the specified permission in the given + course context; False otherwise. + """ + assert isinstance(course_id, (type(None), CourseKey)) + request_cache_dict = DEFAULT_REQUEST_CACHE.data + cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format( + user.id, course_id + ) + if cache_key in request_cache_dict: + all_permissions = request_cache_dict[cache_key] + else: + all_permissions = all_permissions_for_user_in_course(user, course_id) + request_cache_dict[cache_key] = all_permissions + + return permission in all_permissions + + class ForumsConfig(ConfigurationModel): """ Config for the connection to the cs_comments_service forums backend. diff --git a/openedx/features/course_bookmarks/templates/course_bookmarks/course-bookmarks.html b/openedx/features/course_bookmarks/templates/course_bookmarks/course-bookmarks.html index a7038b3bdae6..bda15a7431af 100644 --- a/openedx/features/course_bookmarks/templates/course_bookmarks/course-bookmarks.html +++ b/openedx/features/course_bookmarks/templates/course_bookmarks/course-bookmarks.html @@ -15,7 +15,7 @@ from django.utils.translation import gettext as _ from django.template.defaultfilters import escapejs -from lms.djangoapps.discussion.django_comment_client.permissions import has_permission +from openedx.core.djangoapps.django_comment_common.models import has_permission from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string from openedx.core.djangolib.markup import HTML from openedx.features.course_experience import course_home_page_title diff --git a/xmodule/discussion_block.py b/xmodule/discussion_block.py index aaea2de7bb2a..2158a53e9e2d 100644 --- a/xmodule/discussion_block.py +++ b/xmodule/discussion_block.py @@ -17,7 +17,7 @@ from xblock.utils.studio_editable import StudioEditableXBlockMixin from xblocks_contrib.discussion import DiscussionXBlock as _ExtractedDiscussionXBlock -from lms.djangoapps.discussion.django_comment_client.permissions import has_permission +from openedx.core.djangoapps.django_comment_common.models import has_permission from openedx.core.djangoapps.discussions.models import DiscussionsConfiguration, Provider from openedx.core.djangolib.markup import HTML, Text from openedx.core.lib.xblock_utils import get_css_dependencies, get_js_dependencies @@ -85,6 +85,7 @@ def is_visible(self): """ Discussion Xblock does not support new OPEN_EDX provider """ + provider = DiscussionsConfiguration.get(self.course_key) return provider.provider_type == Provider.LEGACY @@ -282,8 +283,17 @@ def _apply_metadata_and_policy(cls, block, node, runtime): setattr(block, field_name, value) -DiscussionXBlock = ( - _ExtractedDiscussionXBlock if settings.USE_EXTRACTED_DISCUSSION_BLOCK - else _BuiltInDiscussionXBlock -) +DiscussionXBlock = None + + +def reset_class(): + """Reset class as per django settings flag""" + global DiscussionXBlock + DiscussionXBlock = ( + _ExtractedDiscussionXBlock if settings.USE_EXTRACTED_DISCUSSION_BLOCK + else _BuiltInDiscussionXBlock + ) + return DiscussionXBlock + +reset_class() DiscussionXBlock.__name__ = "DiscussionXBlock" From f6d10e5b9dd65e39a5e0baa6ec57598dca052424 Mon Sep 17 00:00:00 2001 From: salman2013 Date: Fri, 23 Jan 2026 15:09:28 +0500 Subject: [PATCH 8/9] fix: quality test --- xmodule/discussion_block.py | 1 - 1 file changed, 1 deletion(-) diff --git a/xmodule/discussion_block.py b/xmodule/discussion_block.py index 2158a53e9e2d..a27cff307118 100644 --- a/xmodule/discussion_block.py +++ b/xmodule/discussion_block.py @@ -85,7 +85,6 @@ def is_visible(self): """ Discussion Xblock does not support new OPEN_EDX provider """ - provider = DiscussionsConfiguration.get(self.course_key) return provider.provider_type == Provider.LEGACY From 67187011358a12cbb9221cbca76277b04604247f Mon Sep 17 00:00:00 2001 From: salman2013 Date: Mon, 26 Jan 2026 13:11:46 +0500 Subject: [PATCH 9/9] fix: remove unecessory warning --- openedx/core/djangoapps/discussions/services.py | 4 ++-- openedx/core/djangoapps/django_comment_common/models.py | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/openedx/core/djangoapps/discussions/services.py b/openedx/core/djangoapps/discussions/services.py index e9f9c51ffb22..8df33c6f3e98 100644 --- a/openedx/core/djangoapps/discussions/services.py +++ b/openedx/core/djangoapps/discussions/services.py @@ -13,10 +13,10 @@ class DiscussionConfigService: """ - Service for providing video-related configuration and feature flags. + Service for providing discussion-related configuration and feature flags. """ - def has_permission(self, user, permission, course_id=None): # lint-amnesty, pylint: disable=missing-function-docstring + def has_permission(self, user, permission, course_id=None): """ Return the discussion permission for a user in a given course. """ diff --git a/openedx/core/djangoapps/django_comment_common/models.py b/openedx/core/djangoapps/django_comment_common/models.py index 58e07e00ce8f..51863c42d472 100644 --- a/openedx/core/djangoapps/django_comment_common/models.py +++ b/openedx/core/djangoapps/django_comment_common/models.py @@ -197,15 +197,13 @@ def all_permissions_for_user_in_course(user, course_id): def has_permission(user, permission, course_id=None): """ - Check whether a user has a specific discussion permission within a course. - This function resolves all discussion-related permissions for the given user and course, caches them for the duration of the request, and verifies whether the requested permission is present. Args: user (User): Django user whose permissions are being checked. - permission (str): Discussion permission identifier to check for + permission (str): Discussion permission identifier (e.g., "create_comment", "create_thread"). course_id (CourseKey): Course context in which to evaluate the permission