diff --git a/common/test/acceptance/fixtures/discussion.py b/common/test/acceptance/fixtures/discussion.py index bf98134c71..fad8ac5686 100644 --- a/common/test/acceptance/fixtures/discussion.py +++ b/common/test/acceptance/fixtures/discussion.py @@ -30,6 +30,8 @@ class ContentFactory(factory.Factory): class Thread(ContentFactory): + anonymous = False + anonymous_to_peers = False comments_count = 0 unread_comments_count = 0 title = "dummy thread title" diff --git a/common/test/acceptance/pages/lms/discussion.py b/common/test/acceptance/pages/lms/discussion.py index 7bcb84c52b..fd433fa699 100644 --- a/common/test/acceptance/pages/lms/discussion.py +++ b/common/test/acceptance/pages/lms/discussion.py @@ -267,6 +267,9 @@ class InlineDiscussionThreadPage(DiscussionThreadPage): "Thread expanded" ).fulfill() + def is_thread_anonymous(self): + return not self.q(css=".posted-details > .username").present + class DiscussionUserProfilePage(CoursePage): diff --git a/common/test/acceptance/tests/test_discussion.py b/common/test/acceptance/tests/test_discussion.py index a71f0f9b31..512087f0c8 100644 --- a/common/test/acceptance/tests/test_discussion.py +++ b/common/test/acceptance/tests/test_discussion.py @@ -297,7 +297,8 @@ class InlineDiscussionTest(UniqueCourseTest, DiscussionResponsePaginationTestMix AutoAuthPage(self.browser, course_id=self.course_id).visit() - CoursewarePage(self.browser, self.course_id).visit() + self.courseware_page = CoursewarePage(self.browser, self.course_id) + self.courseware_page.visit() self.discussion_page = InlineDiscussionPage(self.browser, self.discussion_id) def setup_thread_page(self, thread_id): @@ -313,6 +314,21 @@ class InlineDiscussionTest(UniqueCourseTest, DiscussionResponsePaginationTestMix self.discussion_page.expand_discussion() self.assertEqual(self.discussion_page.get_num_displayed_threads(), 0) + def check_anonymous_to_peers(self, is_staff): + thread = Thread(id=uuid4().hex, anonymous_to_peers=True, commentable_id=self.discussion_id) + thread_fixture = SingleThreadViewFixture(thread) + thread_fixture.push() + self.setup_thread_page(thread.get("id")) + self.assertEqual(self.thread_page.is_thread_anonymous(), not is_staff) + + def test_anonymous_to_peers_threads_as_staff(self): + AutoAuthPage(self.browser, course_id=self.course_id, roles="Administrator").visit() + self.courseware_page.visit() + self.check_anonymous_to_peers(True) + + def test_anonymous_to_peers_threads_as_peer(self): + self.check_anonymous_to_peers(False) + class DiscussionUserProfileTest(UniqueCourseTest): """ diff --git a/lms/djangoapps/django_comment_client/forum/views.py b/lms/djangoapps/django_comment_client/forum/views.py index 4ca8fc2baa..fd3c84feb1 100644 --- a/lms/djangoapps/django_comment_client/forum/views.py +++ b/lms/djangoapps/django_comment_client/forum/views.py @@ -148,9 +148,9 @@ def inline_discussion(request, course_id, discussion_id): with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"): annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info) - + is_staff = cached_has_permission(request.user, 'openclose_thread', course.id) return utils.JsonResponse({ - 'discussion_data': map(utils.safe_content, threads), + 'discussion_data': [utils.safe_content(thread, is_staff) for thread in threads], 'user_info': user_info, 'annotated_content_info': annotated_content_info, 'page': query_params['page'], @@ -172,7 +172,8 @@ def forum_form_discussion(request, course_id): try: unsafethreads, query_params = get_threads(request, course_id) # This might process a search query - threads = [utils.safe_content(thread) for thread in unsafethreads] + is_staff = cached_has_permission(request.user, 'openclose_thread', course.id) + threads = [utils.safe_content(thread, is_staff) for thread in unsafethreads] except cc.utils.CommentClientMaintenanceError: log.warning("Forum is in maintenance mode") return render_to_response('discussion/maintenance.html', {}) @@ -248,10 +249,11 @@ def single_thread(request, course_id, discussion_id, thread_id): raise Http404 raise + is_staff = cached_has_permission(request.user, 'openclose_thread', course.id) if request.is_ajax(): with newrelic.agent.FunctionTrace(nr_transaction, "get_annotated_content_infos"): annotated_content_info = utils.get_annotated_content_infos(course_id, thread, request.user, user_info=user_info) - content = utils.safe_content(thread.to_dict()) + content = utils.safe_content(thread.to_dict(), is_staff) with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"): add_courseware_context([content], course) return utils.JsonResponse({ @@ -274,7 +276,7 @@ def single_thread(request, course_id, discussion_id, thread_id): if not "pinned" in thread: thread["pinned"] = False - threads = [utils.safe_content(thread) for thread in threads] + threads = [utils.safe_content(thread, is_staff) for thread in threads] with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"): annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info) @@ -331,8 +333,9 @@ def user_profile(request, course_id, user_id): annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info) if request.is_ajax(): + is_staff = cached_has_permission(request.user, 'openclose_thread', course.id) return utils.JsonResponse({ - 'discussion_data': map(utils.safe_content, threads), + 'discussion_data': [utils.safe_content(thread, is_staff) for thread in threads], 'page': query_params['page'], 'num_pages': query_params['num_pages'], 'annotated_content_info': _attr_safe_json(annotated_content_info), @@ -380,9 +383,10 @@ def followed_threads(request, course_id, user_id): with newrelic.agent.FunctionTrace(nr_transaction, "get_metadata_for_threads"): annotated_content_info = utils.get_metadata_for_threads(course_id, threads, request.user, user_info) if request.is_ajax(): + is_staff = cached_has_permission(request.user, 'openclose_thread', course.id) return utils.JsonResponse({ 'annotated_content_info': annotated_content_info, - 'discussion_data': map(utils.safe_content, threads), + 'discussion_data': [utils.safe_content(thread, is_staff) for thread in threads], 'page': query_params['page'], 'num_pages': query_params['num_pages'], }) diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index 6d4ec4a02c..d1147e548c 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -360,7 +360,7 @@ def add_courseware_context(content_list, course): content.update({"courseware_url": url, "courseware_title": title}) -def safe_content(content): +def safe_content(content, is_staff=False): fields = [ 'id', 'title', 'body', 'course_id', 'anonymous', 'anonymous_to_peers', 'endorsed', 'parent_id', 'thread_id', 'votes', 'closed', 'created_at', @@ -372,7 +372,7 @@ def safe_content(content): ] - if (content.get('anonymous') is False) and (content.get('anonymous_to_peers') is False): + if (content.get('anonymous') is False) and ((content.get('anonymous_to_peers') is False) or is_staff): fields += ['username', 'user_id'] if 'children' in content: