Skip to content

Commit

Permalink
When groups are enabled and the user can publish group private posts,
Browse files Browse the repository at this point in the history
the publish/unpublish button is shown to post authors and admins/moderators

The question and answer controls snippets for publishin/unpublishing are suitable for caching.
That is, the chaching of this snippet does not need to be disabled when groups are enabled.

Modifie files:
* askbot/jinja2/question/answer_controls.html
* askbot/jinja2/question/question_controls.html
* askbot/models/__init__.py
 - adds a method User.can_publish_group_private_post
* askbot/views/commands.py:publish_post
 - adds a check for User.can_publish_group_private_post
  • Loading branch information
evgenyfadeev committed Jul 15, 2024
1 parent 65d7c5d commit 50cde79
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 26 deletions.
7 changes: 6 additions & 1 deletion askbot/jinja2/question/answer_controls.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
>
{% if answer.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}
</span>
{% if request.user.is_authenticated and request.user.is_post_moderator(answer) %}
{% if settings.GROUPS_ENABLED %}
{% set is_published=(answer.id in published_answer_ids) %}
<span
id="js-post-publish-btn-{{answer.id}}"
Expand All @@ -24,6 +24,11 @@
{% trans %}publish{% endtrans %}</a>
{% endif %}
</span>
{% if request.user.is_anonymous or not request.user.can_publish_group_private_post(question) %}
<script type="text/javascript">
document.getElementById("js-post-publish-btn-" + '{{answer.pk}}').remove();
</script>
{% endif %}
{% endif %}
<a class="action-link with-link-icon"
href="{{ answer.get_absolute_url(question_post=question) }}"
Expand Down
12 changes: 1 addition & 11 deletions askbot/jinja2/question/head_javascript.html
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
if (vote === -1){
var downvoteBtn = document.getElementById('js-post-downvote-btn-' + postId);
downvoteBtn.className += ' js-active';
}
}
if (vote === 1){
var upvoteBtn = document.getElementById('js-post-upvote-btn-' + postId);
upvoteBtn.className += ' js-active';
Expand Down Expand Up @@ -161,15 +161,6 @@
}
}

function hidePublishPostLinks() {
if (data['userIsThreadModerator'] === false) {
document.querySelectorAll('.js-publish-post')
.forEach(function(el) { el.remove(); });
document.querySelectorAll('.js-unpublish-post')
.forEach(function(el) { el.remove(); });
}
}

function removeCommentControls(postId) {
var post = document.getElementById('js-post-' + postId);
var editLinks = findChildrenByClassName(post, 'js-comment-edit-btn');
Expand Down Expand Up @@ -339,6 +330,5 @@
askbot['functions']['renderAddAnswerButton'] = renderAddAnswerButton;
askbot['functions']['hideConvertLinks'] = hideConvertLinks;
askbot['functions']['hideConvertAnswerLinks'] = hideConvertAnswerLinks;
askbot['functions']['hidePublishPostLinks'] = hidePublishPostLinks;
})();
</script>
10 changes: 7 additions & 3 deletions askbot/jinja2/question/question_controls.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class="action-link js-edit with-edit-icon"
>{% trans %}edit{% endtrans %}</span>
{{ macros.post_flag_buttons(question) }}
{% if request.user.is_authenticated and request.user.is_post_moderator(question) %}
{% if settings.GROUPS_ENABLED %}
{% set is_published=(not question.is_private()) %}
<span
id="js-post-publish-btn-{{question.pk}}"
Expand All @@ -17,6 +17,11 @@
{% trans %}publish{% endtrans %}</a>
{% endif %}
</span>
{% if request.user.is_anonymous or not request.user.can_publish_group_private_post(question) %}
<script type="text/javascript">
document.getElementById("js-post-publish-btn-" + '{{question.pk}}').remove();
</script>
{% endif %}
{% endif %}
{% if thread.closed %}
<a id="js-question-close-btn-{{question.id}}"
Expand All @@ -29,7 +34,7 @@
href="{{ url('close', question.id ) }}"
>{% trans %}close{% endtrans %}</a>
{% endif %}
<a
<a
id="js-question-merge-btn-{{question.id}}"
class="action-link js-question-merge-btn with-merge-icon"
>{% trans %}merge{% endtrans %}</a>
Expand All @@ -40,6 +45,5 @@
>{% if question.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}</a>
<script type="text/javascript">
askbot.functions.renderPostControls('{{question.id}}'{{ ', true' if question.wiki }});
askbot.functions.hidePublishPostLinks();
</script>
</div>
25 changes: 25 additions & 0 deletions askbot/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2994,6 +2994,30 @@ def user_can_make_group_private_posts(self):
return (self.get_primary_group() != None)


def user_can_publish_group_private_post(self, post):
"""
Users not belonging to a non-personal private group
cannot publish group private posts.
Of the users who have private group,
admins/mods and the author of the post can publish/unpublish.
Note: there may be unexpected consequences if the site
has > 1 "private groups".
A private post for one group may be taken over by the admins
of other group.
"""
group = self.get_primary_group()
if not group:
return False

if self.is_administrator_or_moderator():
return True

return post.author_id == self.pk


def user_request_account_termination(self):
"""Notifies admins about user account termination"""
msg_template = _('User %(username)s, id=%(id)s, %(email)s '
Expand Down Expand Up @@ -3718,6 +3742,7 @@ def user_is_group_member(self, group=None):
User.add_to_class('can_post_comment', user_can_post_comment)
User.add_to_class('can_post_question', user_can_post_question)
User.add_to_class('can_make_group_private_posts', user_can_make_group_private_posts)
User.add_to_class('can_publish_group_private_post', user_can_publish_group_private_post)
User.add_to_class('is_administrator', user_is_administrator)
User.add_to_class('is_administrator_or_moderator', user_is_administrator_or_moderator)
User.add_to_class('is_admin_or_mod', user_is_administrator_or_moderator) #shorter version
Expand Down
21 changes: 10 additions & 11 deletions askbot/views/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1413,39 +1413,38 @@ def get_editor(request):
@decorators.post_only
def publish_post(request):
"""will publish or unpublish post"""
denied_msg = _('Sorry, only thread moderators can use this function')
denied_msg = _('Sorry, only thread moderators or post owners can use this function')

if request.user.is_anonymous:
raise exceptions.PermissionDenied(denied_msg)

if request.user.is_authenticated:
if request.user.is_administrator_or_moderator() is False:
raise exceptions.PermissionDenied(denied_msg)
#todo: assert permission
post_id = IntegerField().clean(request.POST['post_id'])
post = models.Post.objects.get(pk=post_id)

if post.thread.has_moderator(request.user) is False:
if not request.user.can_publish_group_private_post(post):
raise exceptions.PermissionDenied(denied_msg)

# there used to be an experiment where questions were asked
# privately to a group - i.e. the question was visible to the
# inquirer and the group only. When the answer was published
# it was shared with the enquirer
# it was shared with the inquirer
# Now the code is switched to a simpler mode -
# "published" === visible to the "everyone" group.
# (and used to be "published" -> visible to the enquirer).
#enquirer = answer.thread._question_post().author
#enquirer_group = enquirer.get_personal_group()
#inquirer = answer.thread._question_post().author
#inquirer_group = enquirer.get_personal_group()

if askbot_settings.GROUPS_ENABLED:
if post.is_private():
#answer.add_to_groups([enquirer_group])
#answer.add_to_groups([inquirer_group])
if post.post_type == 'question':
post.thread.make_public()
else:
post.make_public()

message = _('The post is now published')
else:
#answer.remove_from_groups([enquirer_group])
#answer.remove_from_groups([inquirer_group])
if post.post_type == 'question':
post.thread.make_private(request.user)
else:
Expand Down

0 comments on commit 50cde79

Please sign in to comment.