use escape html everywhere and only send discussion data relavent
This commit is contained in:
@@ -55,7 +55,7 @@ def ajax_content_response(request, course_id, content, template_name):
|
||||
annotated_content_info = utils.get_annotated_content_info(course_id, content, request.user, user_info)
|
||||
return JsonResponse({
|
||||
'html': html,
|
||||
'content': content,
|
||||
'content': utils.safe_content(content),
|
||||
'annotated_content_info': annotated_content_info,
|
||||
})
|
||||
|
||||
@@ -78,7 +78,7 @@ def create_thread(request, course_id, commentable_id):
|
||||
if request.is_ajax():
|
||||
return ajax_content_response(request, course_id, thread.to_dict(), 'discussion/ajax_create_thread.html')
|
||||
else:
|
||||
return JsonResponse(thread.to_dict())
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -90,7 +90,7 @@ def update_thread(request, course_id, thread_id):
|
||||
if request.is_ajax():
|
||||
return ajax_content_response(request, course_id, thread.to_dict(), 'discussion/ajax_update_thread.html')
|
||||
else:
|
||||
return JsonResponse(thread.to_dict())
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
def _create_comment(request, course_id, thread_id=None, parent_id=None):
|
||||
post = request.POST
|
||||
@@ -109,7 +109,7 @@ def _create_comment(request, course_id, thread_id=None, parent_id=None):
|
||||
if request.is_ajax():
|
||||
return ajax_content_response(request, course_id, comment.to_dict(), 'discussion/ajax_create_comment.html')
|
||||
else:
|
||||
return JsonResponse(comment.to_dict())
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -126,7 +126,7 @@ def create_comment(request, course_id, thread_id):
|
||||
def delete_thread(request, course_id, thread_id):
|
||||
thread = cc.Thread.find(thread_id)
|
||||
thread.delete()
|
||||
return JsonResponse(thread.to_dict())
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -138,7 +138,7 @@ def update_comment(request, course_id, comment_id):
|
||||
if request.is_ajax():
|
||||
return ajax_content_response(request, course_id, comment.to_dict(), 'discussion/ajax_update_comment.html')
|
||||
else:
|
||||
return JsonResponse(comment.to_dict()),
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -147,7 +147,7 @@ def endorse_comment(request, course_id, comment_id):
|
||||
comment = cc.Comment.find(comment_id)
|
||||
comment.endorsed = request.POST.get('endorsed', 'false').lower() == 'true'
|
||||
comment.save()
|
||||
return JsonResponse(comment.to_dict())
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -158,7 +158,7 @@ def openclose_thread(request, course_id, thread_id):
|
||||
thread.save()
|
||||
thread = thread.to_dict()
|
||||
return JsonResponse({
|
||||
'content': thread,
|
||||
'content': utils.safe_content(thread),
|
||||
'ability': utils.get_ability(course_id, thread, request.user),
|
||||
})
|
||||
|
||||
@@ -177,7 +177,7 @@ def create_sub_comment(request, course_id, comment_id):
|
||||
def delete_comment(request, course_id, comment_id):
|
||||
comment = cc.Comment.find(comment_id)
|
||||
comment.delete()
|
||||
return JsonResponse(comment.to_dict())
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -186,7 +186,7 @@ def vote_for_comment(request, course_id, comment_id, value):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
comment = cc.Comment.find(comment_id)
|
||||
user.vote(comment, value)
|
||||
return JsonResponse(comment.to_dict())
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -195,7 +195,7 @@ def undo_vote_for_comment(request, course_id, comment_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
comment = cc.Comment.find(comment_id)
|
||||
user.unvote(comment)
|
||||
return JsonResponse(comment.to_dict())
|
||||
return JsonResponse(utils.safe_content(comment.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -204,7 +204,7 @@ def vote_for_thread(request, course_id, thread_id, value):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
thread = cc.Thread.find(thread_id)
|
||||
user.vote(thread, value)
|
||||
return JsonResponse(thread.to_dict())
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
@require_POST
|
||||
@login_required
|
||||
@@ -213,7 +213,7 @@ def undo_vote_for_thread(request, course_id, thread_id):
|
||||
user = cc.User.from_django_user(request.user)
|
||||
thread = cc.Thread.find(thread_id)
|
||||
user.unvote(thread)
|
||||
return JsonResponse(thread.to_dict())
|
||||
return JsonResponse(utils.safe_content(thread.to_dict()))
|
||||
|
||||
|
||||
@require_POST
|
||||
|
||||
@@ -83,7 +83,7 @@ def render_discussion(request, course_id, threads, *args, **kwargs):
|
||||
'base_url': base_url,
|
||||
'query_params': strip_blank(strip_none(extract(query_params, ['page', 'sort_key', 'sort_order', 'tags', 'text']))),
|
||||
'annotated_content_info': json.dumps(annotated_content_info),
|
||||
'discussion_data': json.dumps({ (discussion_id or user_id): threads })
|
||||
'discussion_data': json.dumps({ (discussion_id or user_id): map(utils.safe_content, threads) })
|
||||
}
|
||||
context = dict(context.items() + query_params.items())
|
||||
return render_to_string(template, context)
|
||||
@@ -128,7 +128,7 @@ def inline_discussion(request, course_id, discussion_id):
|
||||
|
||||
return utils.JsonResponse({
|
||||
'html': html,
|
||||
'discussionData': threads,
|
||||
'discussion_data': map(utils.safe_content, threads),
|
||||
})
|
||||
|
||||
def render_search_bar(request, course_id, discussion_id=None, text=''):
|
||||
@@ -149,7 +149,7 @@ def forum_form_discussion(request, course_id):
|
||||
if request.is_ajax():
|
||||
return utils.JsonResponse({
|
||||
'html': content,
|
||||
'discussionData': threads,
|
||||
'discussion_data': map(utils.safe_content, threads),
|
||||
})
|
||||
else:
|
||||
recent_active_threads = cc.search_recent_active_threads(
|
||||
@@ -186,7 +186,7 @@ def render_single_thread(request, discussion_id, course_id, thread_id):
|
||||
'annotated_content_info': json.dumps(annotated_content_info),
|
||||
'course_id': course_id,
|
||||
'request': request,
|
||||
'discussion_data': json.dumps({ discussion_id: [thread] }),
|
||||
'discussion_data': json.dumps({ discussion_id: [utils.safe_content(thread)] }),
|
||||
}
|
||||
return render_to_string('discussion/_single_thread.html', context)
|
||||
|
||||
@@ -202,7 +202,7 @@ def single_thread(request, course_id, discussion_id, thread_id):
|
||||
|
||||
return utils.JsonResponse({
|
||||
'html': html,
|
||||
'content': thread.to_dict(),
|
||||
'content': utils.safe_content(thread.to_dict()),
|
||||
'annotated_content_info': annotated_content_info,
|
||||
})
|
||||
|
||||
@@ -252,7 +252,7 @@ def user_profile(request, course_id, user_id):
|
||||
if request.is_ajax():
|
||||
return utils.JsonResponse({
|
||||
'html': content,
|
||||
'discussionData': threads,
|
||||
'discussion_data': map(utils.safe_content, threads),
|
||||
})
|
||||
else:
|
||||
context = {
|
||||
|
||||
@@ -219,3 +219,17 @@ def extend_content(content):
|
||||
'permalink': permalink(content),
|
||||
}
|
||||
return merge_dict(content, content_info)
|
||||
|
||||
def safe_content(content):
|
||||
fields = [
|
||||
'id', 'body', 'course_id', 'anonymous', 'endorsed',
|
||||
'parent_id', 'thread_id', 'votes', 'closed',
|
||||
'created_at', 'updated_at', 'depth', 'type',
|
||||
'commentable_id', 'comments_count', 'at_position_list',
|
||||
'children', 'highlighted_title', 'highlighted_body',
|
||||
]
|
||||
|
||||
if content.get('anonymous') is False:
|
||||
fields += ['username', 'user_id']
|
||||
|
||||
return strip_none(extract(content, fields))
|
||||
|
||||
@@ -48,7 +48,7 @@ if Backbone?
|
||||
$parent = @$el.parent()
|
||||
@$el.replaceWith(response.html)
|
||||
$discussion = $parent.find("section.discussion")
|
||||
@model.reset(response.discussionData, { silent: false })
|
||||
@model.reset(response.discussion_data, { silent: false })
|
||||
view = new DiscussionView el: $discussion[0], model: @model
|
||||
DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info)
|
||||
$("html, body").animate({ scrollTop: 0 }, 0)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</%def>
|
||||
|
||||
<%def name="render_content_with_comments(content, *args, **kwargs)">
|
||||
<div class="${content['type']}${helpers.show_if(' endorsed', content.get('endorsed'))}" _id="${content['id']}" _discussion_id="${content.get('commentable_id', '')}" _author_id="${helpers.show_if(content['user_id'], not content.get('anonymous'))}">
|
||||
<div class="${content['type'] | h}${helpers.show_if(' endorsed', content.get('endorsed')) | h}" _id="${content['id'] | h}" _discussion_id="${content.get('commentable_id', '') | h}" _author_id="${helpers.show_if(content['user_id'], not content.get('anonymous')) | h}">
|
||||
${render_content(content, *args, **kwargs)}
|
||||
${render_comments(content.get('children', []), *args, **kwargs)}
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="discussion-module">
|
||||
<a class="discussion-show control-button" href="javascript:void(0)" discussion_id="${discussion_id}">Show Discussion</a>
|
||||
<a class="discussion-show control-button" href="javascript:void(0)" discussion_id="${discussion_id | h}">Show Discussion</a>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%namespace name="renderer" file="_content_renderer.html"/>
|
||||
|
||||
<section class="discussion forum-discussion" _id="${discussion_id}">
|
||||
<section class="discussion forum-discussion" _id="${discussion_id | h}">
|
||||
|
||||
<div class="discussion-non-content local">
|
||||
<div class="search-wrapper">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%namespace name="renderer" file="_content_renderer.html"/>
|
||||
|
||||
<section class="discussion inline-discussion" _id="${discussion_id}">
|
||||
<section class="discussion inline-discussion" _id="${discussion_id | h}">
|
||||
|
||||
<div class="discussion-non-content local"></div>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
%>
|
||||
|
||||
<%def name="link_to_page(_page, text)">
|
||||
<a class="discussion-page-link" href="javascript:void(0)" page-url="${url_for_page(_page)}">${text}</a>
|
||||
<a class="discussion-page-link" href="javascript:void(0)" page-url="${url_for_page(_page) | h}">${text}</a>
|
||||
</%def>
|
||||
|
||||
<%def name="div_page(_page)">
|
||||
@@ -36,7 +36,7 @@
|
||||
% endfor
|
||||
</%def>
|
||||
|
||||
<div class="discussion-${discussion_type}-paginator discussion-paginator local">
|
||||
<div class="discussion-${discussion_type | h}-paginator discussion-paginator local">
|
||||
<div class="prev-page">
|
||||
% if page > 1:
|
||||
${link_to_page(page - 1, "< Previous page")}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</header>
|
||||
<ol class="discussion-sidebar-following-list">
|
||||
% for thread in recent_active_threads:
|
||||
<li><a href="${helpers.permalink(thread)}"><span class="sidebar-following-name">${thread['title']}</span> <span class="sidebar-vote-count">${thread['votes']['point']}</span></a></li>
|
||||
<li><a href="${helpers.permalink(thread) | h}"><span class="sidebar-following-name">${thread['title'] | h}</span> <span class="sidebar-vote-count">${thread['votes']['point'] | h}</span></a></li>
|
||||
% endfor
|
||||
<ol>
|
||||
</article>
|
||||
|
||||
@@ -10,9 +10,9 @@ def base_url_for_search():
|
||||
|
||||
<form action="${base_url_for_search()}" method="get" class="discussion-search-form">
|
||||
% if query_params.get('tags', None):
|
||||
<input class="search-input" type="text" value="[${tags}]${text}" id="keywords" autocomplete="off"/>
|
||||
<input class="search-input" type="text" value="[${tags | h}]${text | h}" id="keywords" autocomplete="off"/>
|
||||
% else:
|
||||
<input class="search-input" type="text" value="${text}" id="keywords" autocomplete="off"/>
|
||||
<input class="search-input" type="text" value="${text | h}" id="keywords" autocomplete="off"/>
|
||||
% endif
|
||||
<div class="discussion-link discussion-search-link" href="javascript:void(0)">Search posts</div>
|
||||
</form>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<a class="hide-similar-posts" href="javascript:void(0)">Hide</a>
|
||||
<div class="new-post-similar-posts">
|
||||
% for thread in threads:
|
||||
<a class="similar-post" href="${thread['permalink']}">${thread['title']}</a>
|
||||
<a class="similar-post" href="${thread['permalink'] | h}">${thread['title'] | h}</a>
|
||||
% endfor
|
||||
</div>
|
||||
% endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%namespace name="renderer" file="_content_renderer.html"/>
|
||||
|
||||
<section class="discussion" _id="${discussion_id}">
|
||||
<section class="discussion" _id="${discussion_id | h}">
|
||||
<a class="discussion-title" href="javascript:void(0)">Discussion</a>
|
||||
<div class="threads">
|
||||
${renderer.render_content_with_comments(thread)}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
else:
|
||||
return base_url + '?' + urlencode(merge(query_params, {'page': 1, 'sort_key': key, 'sort_order': order}))
|
||||
%>
|
||||
<a class="discussion-sort-link ${cls}" href="javascript:void(0)" sort-url="${url_for_sort(key, order)}">${title}</a>
|
||||
<a class="discussion-sort-link ${cls | h}" href="javascript:void(0)" sort-url="${url_for_sort(key, order) | h}">${title}</a>
|
||||
</%def>
|
||||
|
||||
<div class="discussion-sort local">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</header>
|
||||
<ol class="discussion-sidebar-tags-list">
|
||||
% for tag, count in trending_tags:
|
||||
<li><a href="${helpers.url_for_tags(course.id, tag)}" class="thread-tag">${tag}</a><span class="sidebar-tag-count">×${count}</span></li>
|
||||
<li><a href="${helpers.url_for_tags(course.id, tag) | h}" class="thread-tag">${tag | h}</a><span class="sidebar-tag-count">×${count | h}</span></li>
|
||||
% endfor
|
||||
<ol>
|
||||
</article>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<%namespace name="renderer" file="_content_renderer.html"/>
|
||||
|
||||
<section class="discussion user-active-discussion" _id="${user_id}">
|
||||
<section class="discussion user-active-discussion" _id="${user_id | h}">
|
||||
|
||||
<div class="discussion-non-content local"></div>
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
<%
|
||||
role_names = sorted(map(attrgetter('name'), django_user.roles.all()))
|
||||
%>
|
||||
<div class="sidebar-username">${django_user.username}</div>
|
||||
<div class="sidebar-username">${django_user.username | h}</div>
|
||||
<div class="sidebar-user-roles">
|
||||
${", ".join(role_names)}
|
||||
</div>
|
||||
<div class="sidebar-threads-count"><span>${profiled_user['threads_count']}</span> ${pluralize('discussion', profiled_user['threads_count'])} started</div>
|
||||
<div class="sidebar-comments-count"><span>${profiled_user['comments_count']}</span> ${pluralize('comment', profiled_user['comments_count'])}</div>
|
||||
<div class="sidebar-threads-count"><span>${profiled_user['threads_count'] | h}</span> ${pluralize('discussion', profiled_user['threads_count']) | h} started</div>
|
||||
<div class="sidebar-comments-count"><span>${profiled_user['comments_count'] | h}</span> ${pluralize('comment', profiled_user['comments_count']) | h}</div>
|
||||
% if check_permissions_by_view(user, course.id, content=None, name='update_moderator_status'):
|
||||
% if "Moderator" in role_names:
|
||||
<a href="javascript:void(0)" class="sidebar-toggle-moderator-button sidebar-revoke-moderator-button">Revoke Moderator provileges</a>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<%inherit file="../main.html" />
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%block name="bodyclass">discussion</%block>
|
||||
<%block name="title"><title>Discussion – ${course.number}</title></%block>
|
||||
<%block name="title"><title>Discussion – ${course.number | h}</title></%block>
|
||||
|
||||
<%block name="headextra">
|
||||
<%static:css group='course'/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<%inherit file="../main.html" />
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%block name="bodyclass">discussion</%block>
|
||||
<%block name="title"><title>Discussion – ${course.number}</title></%block>
|
||||
<%block name="title"><title>Discussion – ${course.number | h}</title></%block>
|
||||
|
||||
<%block name="headextra">
|
||||
<%static:css group='course'/>
|
||||
|
||||
Reference in New Issue
Block a user