summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-05-14 01:36:38 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-05-14 01:36:38 -0300
commit5ca8a04794d35e2f9b6955a2c45d9a3cc925cd4f (patch)
tree71641d9648fda88861618d1f02c60e27c020d492
parentd3f23e60c7137ba5e8aa7d8869099627ff26e4de (diff)
parent09e39545c5c5cd0319cfdc603e951a5ae42f063f (diff)
downloadaskbot-5ca8a04794d35e2f9b6955a2c45d9a3cc925cd4f.tar.gz
askbot-5ca8a04794d35e2f9b6955a2c45d9a3cc925cd4f.tar.bz2
askbot-5ca8a04794d35e2f9b6955a2c45d9a3cc925cd4f.zip
Merge pull request #217 from keto/protect-convert-views
CSRF protection and user checks for answer and comment converting views
-rw-r--r--askbot/media/js/utils.js19
-rw-r--r--askbot/models/__init__.py18
-rw-r--r--askbot/templates/macros.html5
-rw-r--r--askbot/templates/question/answer_comments.html3
-rw-r--r--askbot/templates/question/question_comments.html3
-rw-r--r--askbot/views/writers.py17
6 files changed, 59 insertions, 6 deletions
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'));
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index 4156bb0c..5dace35c 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -837,6 +837,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
@@ -1385,7 +1399,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
@@ -2998,6 +3012,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/templates/macros.html b/askbot/templates/macros.html
index 699bd7f3..7ceb4eab 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 %}
+ <input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<input type="hidden" value="{{comment.id}}" name="comment_id" id="id_comment_id">
<input type="submit" value="{% trans %}convert to answer{% endtrans %}">
</form>
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 88e5e0cf..04103d50 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -852,7 +852,13 @@ def delete_comment(request):
@login_required
@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 <a href="%(sign_in_url)s">sign in</a>.') % \
+ {'sign_in_url': url_utils.get_login_url()}
+ raise exceptions.PermissionDenied(msg)
form = forms.ProcessCommentForm(request.POST)
if form.is_valid() == False:
@@ -879,14 +885,23 @@ 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 <a href="%(sign_in_url)s">sign in</a>.') % \
+ {'sign_in_url': url_utils.get_login_url()}
+ raise exceptions.PermissionDenied(msg)
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()