summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/models/__init__.py1
-rw-r--r--askbot/models/post.py12
-rw-r--r--askbot/models/question.py41
-rw-r--r--askbot/tests/thread_model_tests.py44
4 files changed, 90 insertions, 8 deletions
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index 9a4121c1..acd279f7 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -1852,6 +1852,7 @@ def user_post_answer(
is_private = is_private,
by_email = by_email
)
+ #add to the answerer's group
answer_post.add_to_groups([self.get_personal_group()])
answer_post.thread.invalidate_cached_data()
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 25e51b50..7fac40bc 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -220,7 +220,11 @@ class PostManager(BaseQuerySetManager):
post.last_edited_at = added_at
post.wikified_at = added_at
- post.parse_and_save(author=author, is_private = is_private)
+ #possibly modify the is_private, if one of the groups
+ #mandates explicit publishing of the posts
+ is_private = is_private or thread.requires_response_moderation(author)
+
+ post.parse_and_save(author=author, is_private=is_private)
post.add_revision(
author = author,
@@ -507,6 +511,10 @@ class Post(models.Model):
self.add_to_groups(groups)
elif is_private or group_id:
self.make_private(author, group_id = group_id)
+ elif self.thread_id:#is connected to thread
+ #inherit privacy scope from thread
+ thread_groups = self.thread.groups.all()
+ self.add_to_groups(thread_groups)
else:
self.make_public()
@@ -647,7 +655,7 @@ class Post(models.Model):
recipients=notify_sets['for_email'],
)
- def make_private(self, user, group_id = None):
+ def make_private(self, user, group_id=None):
"""makes post private within user's groups
todo: this is a copy-paste in thread and post
"""
diff --git a/askbot/models/question.py b/askbot/models/question.py
index adf8a631..fa5c345a 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -146,7 +146,7 @@ class ThreadManager(BaseQuerySetManager):
)
author_group = author.get_personal_group()
- thread.add_to_groups([author_group])
+ thread.add_to_groups([author_group], visibility=ThreadToGroup.SHOW_PUBLISHED_RESPONSES)
question.add_to_groups([author_group])
if is_private or group_id:#add groups to thread and question
@@ -575,10 +575,19 @@ class Thread(models.Model):
def get_groups_shared_with(self, max_count=None):
"""returns query set of groups with whom thread is shared"""
- groups = self.groups.exclude(name__startswith='_internal_')
+ thread_groups = ThreadToGroup.objects.filter(
+ models.Q(
+ thread=self,
+ visibility=ThreadToGroup.SHOW_ALL_RESPONSES
+ ) & ~models.Q(
+ group__name__startswith='_internal_'
+ )
+ )
if max_count:
- groups = groups[:max_count]
- return groups
+ thread_groups = thread_groups[:max_count]
+
+ group_ids = thread_groups.values_list('group_id', flat=True)
+ return Group.objects.filter(id__in=group_ids)
def update_favorite_count(self):
self.favourite_count = FavoriteQuestion.objects.filter(thread=self).count()
@@ -666,6 +675,17 @@ class Thread(models.Model):
#use len to cache the queryset
return len(self.get_answers_by_user(user)) > 0
+ def requires_response_moderation(self, author):
+ """true, if answers by a given author must be moderated
+ before publishing to the enquirers"""
+ author_groups = author.get_groups()
+ thread_groups = self.get_groups_shared_with()
+ for group in set(author_groups) & set(thread_groups):
+ if group.moderate_answers_to_enquirers:
+ return True
+
+ return False
+
def tagname_meta_generator(self):
return u','.join([unicode(tag) for tag in self.get_tag_names()])
@@ -909,13 +929,22 @@ class Thread(models.Model):
tag__id__in=group_ids
).delete()
- def add_to_groups(self, groups, recursive=False):
+ def add_to_groups(
+ self, groups, visibility=ThreadToGroup.SHOW_ALL_RESPONSES, recursive=False
+ ):
"""adds thread to a list of groups
``groups`` argument may be any iterable of groups
"""
for group in groups:
#todo: change to bulk create when django 1.3 goes out of use
- ThreadToGroup.objects.get_or_create(thread=self, group=group)
+ thread_group, created = ThreadToGroup.objects.get_or_create(
+ thread=self,
+ group=group
+ )
+
+ if thread_group.visibility != visibility:
+ thread_group.visibility = visibility
+ thread_group.save()
if recursive == True:
#comments are taken care of automatically
diff --git a/askbot/tests/thread_model_tests.py b/askbot/tests/thread_model_tests.py
index 13b32547..c8085655 100644
--- a/askbot/tests/thread_model_tests.py
+++ b/askbot/tests/thread_model_tests.py
@@ -1,6 +1,7 @@
from askbot.tests.utils import AskbotTestCase
from askbot.conf import settings as askbot_settings
from askbot import models
+from askbot.models.tag import get_global_group
import django.core.mail
class ThreadModelTestsWithGroupsEnabled(AskbotTestCase):
@@ -57,3 +58,46 @@ class ThreadModelTestsWithGroupsEnabled(AskbotTestCase):
self.assertEqual(len(django.core.mail.outbox), 1)
user = self.reload_object(self.user)
self.assertEqual(user.new_response_count, 1)
+
+ def test_answer_to_private_question_is_not_globally_visible(self):
+ question = self.post_question(user=self.admin, is_private=True)
+ answer = self.post_answer(question=question, user=self.admin, is_private=False)
+ global_group = get_global_group()
+ self.assertEqual(
+ global_group in set(answer.groups.all()),
+ False
+ )
+
+ def test_answer_to_group_question_is_not_globally_visible(self):
+ #ask into group where user is not a member
+ question = self.post_question(user=self.user, group_id=self.group.id)
+ #answer posted by a group member
+ answer = self.post_answer(question=question, user=self.admin, is_private=False)
+ global_group = get_global_group()
+ self.assertEqual(
+ global_group in set(answer.groups.all()),
+ False
+ )
+
+
+ def test_restrictive_response_publishing(self):
+ self.group.moderate_answers_to_enquirers = True
+ self.group.save()
+ question = self.post_question(user=self.user, group_id=self.group.id)
+ answer = self.post_answer(question=question, user=self.admin)
+
+ #answer and the user don't have groups in common
+ answer_groups = set(answer.groups.all())
+ user_groups = set(self.user.get_groups())
+ self.assertEqual(len(answer_groups & user_groups), 0)
+
+ def test_permissive_response_publishing(self):
+ self.group.moderate_answers_to_enquirers = False
+ self.group.save()
+ question = self.post_question(user=self.user, group_id=self.group.id)
+ answer = self.post_answer(question=question, user=self.admin)
+
+ #answer and user have one group in common
+ answer_groups = set(answer.groups.all())
+ user_groups = set(self.user.get_groups())
+ self.assertEqual(len(answer_groups & user_groups), 1)