* Security fix: filter search by category groups * use pre-filtered querysets in all search types * don't filter by category groups for superusers * display hit count as success message

---
This commit is contained in:
JensDiemer 2012-09-24 14:18:16 +03:00
parent 5a462351c6
commit d27719803d

View file

@ -131,14 +131,18 @@ def search(request):
context = {}
#FIXME: show_user for anonymous raise exception,
#django bug http://code.djangoproject.com/changeset/14087 :|
groups = request.user.groups.all() or [] #removed after django > 1.2.3 release
topics = Topic.objects.filter(
Q(forum__category__groups__in=groups) | \
Q(forum__category__groups__isnull=True))
# Create 'user viewable' pre-filtered topics/posts querysets
viewable_category = Category.objects.all()
topics = Topic.objects.all().order_by("-last_post__created")
posts = Post.objects.all().order_by('-created')
user = request.user
if not user.is_superuser:
user_groups = user.groups.all() or [] # need 'or []' for anonymous user otherwise: 'EmptyManager' object is not iterable
viewable_category = viewable_category.filter(Q(groups__in=user_groups) | Q(groups__isnull=True))
topics = Topic.objects.filter(forum__category__in=viewable_category)
posts = Post.objects.filter(topic__forum__category__in=viewable_category)
base_url = None
_generic_context = True
@ -146,7 +150,6 @@ def search(request):
if action == 'show_24h':
date = datetime.now() - timedelta(days=1)
if show_as_posts:
posts = Post.objects.filter(topic__in=topics).order_by('-created')
context["posts"] = posts.filter(Q(created__gte=date) | Q(updated__gte=date))
else:
context["topics"] = topics.filter(Q(last_post__created__gte=date) | Q(last_post__updated__gte=date))
@ -161,7 +164,6 @@ def search(request):
if last_read:
if show_as_posts:
posts = Post.objects.filter(topic__in=topics).order_by('-created')
context["posts"] = posts.filter(Q(created__gte=last_read) | Q(updated__gte=last_read))
else:
context["topics"] = topics.filter(Q(last_post__created__gte=last_read) | Q(last_post__updated__gte=last_read))
@ -188,10 +190,10 @@ def search(request):
user_id = user.id
if show_as_posts:
posts = Post.objects.filter(user__id=user_id)
posts = posts.filter(user__id=user_id)
else:
# show as topic
topics = Topic.objects.filter(posts__user__id=user_id).order_by("-last_post__created").distinct()
topics = topics.filter(posts__user__id=user_id).order_by("-last_post__created").distinct()
base_url = "?action=show_user&user_id=%s&show_as=" % user_id
elif action == 'search':
@ -222,11 +224,6 @@ def search(request):
elif search_in == 'topic':
query = query.filter(topic=keywords)
# add exlusions for categories user does not have access too
for category in Category.objects.all():
if not category.has_access(user):
query = query.exclude(category=category)
order = {'0': 'created',
'1': 'author',
'2': 'topic',
@ -243,8 +240,10 @@ def search(request):
# Info: If whoosh backend used, setup HAYSTACK_ITERATOR_LOAD_PER_QUERY
# to a higher number to speed up
post_pks = posts.values_list("pk", flat=True)
context["topics"] = Topic.objects.filter(posts__in=post_pks).distinct()
context["topics"] = topics.filter(posts__in=post_pks).distinct()
else:
# FIXME: How to use the pre-filtered query from above?
posts = posts.filter(topic__forum__category__in=viewable_category)
context["posts"] = posts
get_query_dict = request.GET.copy()
@ -254,7 +253,7 @@ def search(request):
if _generic_context:
if show_as_posts:
context["posts"] = Post.objects.filter(topic__in=topics).order_by('-created')
context["posts"] = posts.filter(topic__in=topics).order_by('-created')
else:
context["topics"] = topics
@ -263,8 +262,12 @@ def search(request):
if show_as_posts:
context["as_topic_url"] = base_url + "topics"
post_count = context["posts"].count()
messages.success(request, _("Found %i posts.") % post_count)
else:
context["as_post_url"] = base_url + "posts"
topic_count = context["topics"].count()
messages.success(request, _("Found %i topics.") % topic_count)
return render(request, template_name, context)