From 52fdb05db240ffac8ecc05e5684f517edc4071c1 Mon Sep 17 00:00:00 2001 From: Pami Ketolainen Date: Thu, 13 Mar 2014 10:06:06 +0200 Subject: Add CSRF protection to comment_to_answer view --- askbot/templates/macros.html | 5 +++-- askbot/templates/question/answer_comments.html | 3 ++- askbot/templates/question/question_comments.html | 3 ++- askbot/views/writers.py | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/askbot/templates/macros.html b/askbot/templates/macros.html index a17c808e..d6c3f7e8 100644 --- a/askbot/templates/macros.html +++ b/askbot/templates/macros.html @@ -388,7 +388,8 @@ for the purposes of the AJAX comment editor #} show_comment = None, show_comment_position = None, user=None, - max_comments=None + max_comments=None, + csrf_token=None ) -%} {% spaceless %} @@ -451,7 +452,7 @@ for the purposes of the AJAX comment editor #} accept-charset="utf-8" class='convert-comment' > - {% csrf_token %} + diff --git a/askbot/templates/question/answer_comments.html b/askbot/templates/question/answer_comments.html index e6b5e1c5..c0a0dfd8 100644 --- a/askbot/templates/question/answer_comments.html +++ b/askbot/templates/question/answer_comments.html @@ -5,6 +5,7 @@ show_comment = show_comment, show_comment_position = show_comment_position, user = request.user, - max_comments = settings.MAX_COMMENTS_TO_SHOW + max_comments = settings.MAX_COMMENTS_TO_SHOW, + csrf_token = csrf_token ) }} diff --git a/askbot/templates/question/question_comments.html b/askbot/templates/question/question_comments.html index e9d3f724..a05f6328 100644 --- a/askbot/templates/question/question_comments.html +++ b/askbot/templates/question/question_comments.html @@ -5,6 +5,7 @@ show_comment = show_comment, show_comment_position = show_comment_position, user = request.user, - max_comments = settings.MAX_COMMENTS_TO_SHOW + max_comments = settings.MAX_COMMENTS_TO_SHOW, + csrf_token = csrf_token ) }} diff --git a/askbot/views/writers.py b/askbot/views/writers.py index 9234c37f..28060b41 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -850,6 +850,7 @@ def delete_comment(request): ) @decorators.post_only +@csrf.csrf_protect def comment_to_answer(request): try: -- cgit v1.2.3-1-g7c22 From 0d9ec22a1faf15f4338eabe3fe41191110898785 Mon Sep 17 00:00:00 2001 From: Pami Ketolainen Date: Fri, 14 Mar 2014 14:39:32 +0200 Subject: Check that user can convert comments or answers --- askbot/models/__init__.py | 18 +++++++++++++++++- askbot/views/writers.py | 6 +++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 09d10f3f..fc29f8fa 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -834,6 +834,20 @@ def user_assert_can_edit_comment(self, comment = None): ) raise django_exceptions.PermissionDenied(error_message) +def user_assert_can_convert_post(self, post = None): + """raises exceptions.PermissionDenied if user is not allowed to convert the + post to another type (comment -> answer, answer -> comment) + + only owners, moderators or admins can convert posts + """ + if self.is_administrator() or self.is_moderator() or post.author == self: + return + + error_message = _( + 'Sorry, but only post owners or moderators convert posts' + ) + raise django_exceptions.PermissionDenied(error_message) + def user_can_post_comment(self, parent_post = None): """a simplified method to test ability to comment @@ -1372,7 +1386,7 @@ def user_repost_comment_as_answer(self, comment): parent question""" #todo: add assertion - #self.assert_can_repost_comment_as_answer(comment) + self.assert_can_convert_post(comment) comment.post_type = 'answer' old_parent = comment.parent @@ -2977,6 +2991,8 @@ User.add_to_class('assert_can_delete_post', user_assert_can_delete_post) User.add_to_class('assert_can_restore_post', user_assert_can_restore_post) User.add_to_class('assert_can_delete_comment', user_assert_can_delete_comment) User.add_to_class('assert_can_edit_comment', user_assert_can_edit_comment) +User.add_to_class('assert_can_convert_post', user_assert_can_convert_post) + User.add_to_class('assert_can_delete_answer', user_assert_can_delete_answer) User.add_to_class('assert_can_delete_question', user_assert_can_delete_question) User.add_to_class('assert_can_accept_best_answer', user_assert_can_accept_best_answer) diff --git a/askbot/views/writers.py b/askbot/views/writers.py index 28060b41..70b8f093 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -882,12 +882,16 @@ def repost_answer_as_comment(request, destination=None): ) answer_id = request.POST.get('answer_id') if answer_id: - answer_id = int(answer_id) + try: + answer_id = int(answer_id) + except (ValueError, TypeError): + raise Http404 answer = get_object_or_404(models.Post, post_type = 'answer', id=answer_id) if askbot_settings.READ_ONLY_MODE_ENABLED: return HttpResponseRedirect(answer.get_absolute_url()) + request.user.assert_can_convert_post(post=answer) if destination == 'comment_under_question': destination_post = answer.thread._question_post() -- cgit v1.2.3-1-g7c22 From ca05358f9f7a423bbd5c57ef272ea22d2170c348 Mon Sep 17 00:00:00 2001 From: Pami Ketolainen Date: Mon, 17 Mar 2014 10:56:44 +0200 Subject: Require loggedin user on answer/comment convert --- askbot/views/writers.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/askbot/views/writers.py b/askbot/views/writers.py index 70b8f093..3d558a9e 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -852,6 +852,11 @@ def delete_comment(request): @decorators.post_only @csrf.csrf_protect def comment_to_answer(request): + if request.user.is_anonymous(): + msg = _('Sorry, only logged in users can convert comments to answers. ' + 'Please sign in.') % \ + {'sign_in_url': url_utils.get_login_url()} + raise exceptions.PermissionDenied(msg) try: comment_id = int(request.POST.get('comment_id')) @@ -880,6 +885,11 @@ def repost_answer_as_comment(request, destination=None): 'comment_under_previous_answer' ) ) + if request.user.is_anonymous(): + msg = _('Sorry, only logged in users can convert answers to comments. ' + 'Please sign in.') % \ + {'sign_in_url': url_utils.get_login_url()} + raise exceptions.PermissionDenied(msg) answer_id = request.POST.get('answer_id') if answer_id: try: -- cgit v1.2.3-1-g7c22 From 09e39545c5c5cd0319cfdc603e951a5ae42f063f Mon Sep 17 00:00:00 2001 From: Pami Ketolainen Date: Wed, 26 Mar 2014 10:36:15 +0200 Subject: Add CSRF token in comments loaded via Javascript --- askbot/media/js/utils.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/askbot/media/js/utils.js b/askbot/media/js/utils.js index 64932ccd..ef4309bd 100644 --- a/askbot/media/js/utils.js +++ b/askbot/media/js/utils.js @@ -277,6 +277,19 @@ var notify = function() { }; }(); +/* + * CSRF token extractor + */ +var getCSRFToken = function() { + var re = /_csrf=([^;]*)/; + var match = re.exec(document.cookie); + if(match) + return match[1]; + else + return '' +} + + /* **************************************************** */ // Search query-string manipulation utils /* **************************************************** */ @@ -1374,6 +1387,12 @@ CommentConvertLink.prototype.createDom = function(){ hidden_input.attr('id', 'id_comment_id'); element.append(hidden_input); + var csrf_token = this.makeElement('input'); + csrf_token.attr('type', 'hidden'); + csrf_token.attr('name', 'csrfmiddlewaretoken'); + csrf_token.attr('value', getCSRFToken()); + element.append(csrf_token); + var submit = this.makeElement('input'); submit.attr('type', 'submit'); submit.attr('value', gettext('convert to answer')); -- cgit v1.2.3-1-g7c22