diff gpp/forums/views/main.py @ 459:9d3bd7304050

Fixing #221. Also combined all permissions checks into a new module, permissions.py. This allows us to cache user, category, and forum groups information since it rarely changes.
author Brian Neal <bgneal@gmail.com>
date Sat, 02 Jul 2011 23:35:45 +0000
parents 72ef6e809f79
children 2ff5f4c1476d
line wrap: on
line diff
--- a/gpp/forums/views/main.py	Sat Jul 02 03:52:43 2011 +0000
+++ b/gpp/forums/views/main.py	Sat Jul 02 23:35:45 2011 +0000
@@ -21,19 +21,21 @@
 from django.utils.text import wrap
 from django.db.models import F
 
+import antispam
+import antispam.utils
+from bio.models import UserProfile, BadgeOwnership
 from core.paginator import DiggPaginator
 from core.functions import email_admins
-from forums.models import Forum, Topic, Post, FlaggedPost, TopicLastVisit, \
-        ForumLastVisit, Attachment
-from forums.forms import NewTopicForm, NewPostForm, PostForm, MoveTopicForm, \
-        SplitTopicForm
-from forums.unread import get_forum_unread_status, get_topic_unread_status, \
-        get_post_unread_status, get_unread_topics
 
-from bio.models import UserProfile, BadgeOwnership
-import antispam
-import antispam.utils
+from forums.models import (Forum, Topic, Post, FlaggedPost, TopicLastVisit,
+        ForumLastVisit, Attachment)
+from forums.forms import (NewTopicForm, NewPostForm, PostForm, MoveTopicForm,
+        SplitTopicForm)
+from forums.unread import (get_forum_unread_status, get_topic_unread_status,
+        get_post_unread_status, get_unread_topics)
+
 from forums.attachments import AttachmentProcessor
+import forums.permissions as perms
 
 #######################################################################
 
@@ -117,7 +119,7 @@
     """
     forum = get_object_or_404(Forum.objects.select_related(), slug=slug)
 
-    if not forum.category.can_access(request.user):
+    if not perms.can_access(forum.category, request.user):
         return HttpResponseForbidden()
 
     feed = None
@@ -141,7 +143,7 @@
     # we do this for the template since it is rendered twice
     page_nav = render_to_string('forums/pagination.html', {'page': page})
 
-    can_moderate = _can_moderate(forum, request.user)
+    can_moderate = perms.can_moderate(forum, request.user)
 
     return render_to_response('forums/forum_index.html', {
         'forum': forum,
@@ -160,7 +162,7 @@
     topic = get_object_or_404(Topic.objects.select_related(
         'forum', 'forum__category', 'last_post'), pk=id)
 
-    if not topic.forum.category.can_access(request.user):
+    if not perms.can_access(topic.forum.category, request.user):
         return HttpResponseForbidden()
 
     topic.view_count = F('view_count') + 1
@@ -222,7 +224,7 @@
     # we do this for the template since it is rendered twice
     page_nav = render_to_string('forums/pagination.html', {'page': page})
 
-    can_moderate = _can_moderate(topic.forum, request.user)
+    can_moderate = perms.can_moderate(topic.forum, request.user)
 
     can_reply = request.user.is_authenticated() and (
         not topic.locked or can_moderate)
@@ -289,7 +291,7 @@
     """
     forum = get_object_or_404(Forum.objects.select_related(), slug=slug)
 
-    if not forum.category.can_access(request.user):
+    if not perms.can_access(forum.category, request.user):
         return HttpResponseForbidden()
 
     if request.method == 'POST':
@@ -338,7 +340,7 @@
 
     form = NewPostForm(request.POST)
     if form.is_valid():
-        if not _can_post_in_topic(form.topic, request.user):
+        if not perms.can_post(form.topic, request.user):
             return HttpResponseForbidden("You don't have permission to post in this topic.")
         if antispam.utils.spam_check(request, form.cleaned_data['body']):
             return HttpResponseForbidden(antispam.BUSTED_MESSAGE)
@@ -352,7 +354,7 @@
 
         return render_to_response('forums/display_post.html', {
             'post': post,
-            'can_moderate': _can_moderate(form.topic.forum, request.user),
+            'can_moderate': perms.can_moderate(form.topic.forum, request.user),
             'can_reply': True,
             },
             context_instance=RequestContext(request))
@@ -419,7 +421,7 @@
     """
     post = get_object_or_404(Post.objects.select_related(), pk=id)
 
-    can_moderate = _can_moderate(post.topic.forum, request.user)
+    can_moderate = perms.can_moderate(post.topic.forum, request.user)
     can_edit = can_moderate or request.user == post.user
 
     if not can_edit:
@@ -578,7 +580,7 @@
     to a topic.
     """
     topic = get_object_or_404(Topic.objects.select_related(), pk=topic_id)
-    can_post = _can_post_in_topic(topic, request.user)
+    can_post = perms.can_post(topic, request.user)
 
     if can_post:
         if request.method == 'POST':
@@ -625,7 +627,7 @@
     This view function is for moderators to toggle the sticky status of a topic.
     """
     topic = get_object_or_404(Topic.objects.select_related(), pk=id)
-    if _can_moderate(topic.forum, request.user):
+    if perms.can_moderate(topic.forum, request.user):
         topic.sticky = not topic.sticky
         topic.save()
         return HttpResponseRedirect(topic.get_absolute_url())
@@ -639,7 +641,7 @@
     This view function is for moderators to toggle the locked status of a topic.
     """
     topic = get_object_or_404(Topic.objects.select_related(), pk=id)
-    if _can_moderate(topic.forum, request.user):
+    if perms.can_moderate(topic.forum, request.user):
         topic.locked = not topic.locked
         topic.save()
         return HttpResponseRedirect(topic.get_absolute_url())
@@ -653,7 +655,7 @@
     This view function is for moderators to delete an entire topic.
     """
     topic = get_object_or_404(Topic.objects.select_related(), pk=id)
-    if _can_moderate(topic.forum, request.user):
+    if perms.can_moderate(topic.forum, request.user):
         forum_url = topic.forum.get_absolute_url()
         _delete_topic(topic)
         return HttpResponseRedirect(forum_url)
@@ -667,7 +669,7 @@
     This view function is for moderators to move a topic to a different forum.
     """
     topic = get_object_or_404(Topic.objects.select_related(), pk=id)
-    if not _can_moderate(topic.forum, request.user):
+    if not perms.can_moderate(topic.forum, request.user):
         return HttpResponseForbidden()
 
     if request.method == 'POST':
@@ -696,7 +698,7 @@
     stickying and unstickying, moving, and deleting topics.
     """
     forum = get_object_or_404(Forum.objects.select_related(), slug=slug)
-    if not _can_moderate(forum, request.user):
+    if not perms.can_moderate(forum, request.user):
         return HttpResponseForbidden()
 
     topics = forum.topics.select_related('user', 'last_post', 'last_post__user')
@@ -770,7 +772,7 @@
     """
     forum = get_object_or_404(Forum.objects.select_related(), slug=slug)
 
-    if not forum.category.can_access(request.user):
+    if not perms.can_access(forum.category, request.user):
         return HttpResponseForbidden()
 
     forum.catchup(request.user)
@@ -783,7 +785,7 @@
     This view function allows moderators to split posts off to a new topic.
     """
     topic = get_object_or_404(Topic.objects.select_related(), pk=id)
-    if not _can_moderate(topic.forum, request.user):
+    if not perms.can_moderate(topic.forum, request.user):
         return HttpResponseRedirect(topic.get_absolute_url())
 
     if request.method == "POST":
@@ -930,7 +932,7 @@
     """Displays information about the IP address the post was made from."""
     post = get_object_or_404(Post.objects.select_related(), pk=post_id)
 
-    if not _can_moderate(post.topic.forum, request.user):
+    if not perms.can_moderate(post.topic.forum, request.user):
         return HttpResponseForbidden("You don't have permission for this post.")
 
     ip_users = sorted(set(Post.objects.filter(
@@ -971,23 +973,6 @@
         context_instance=RequestContext(request))
 
 
-def _can_moderate(forum, user):
-    """
-    Determines if a user has permission to moderate a given forum.
-    """
-    return user.is_authenticated() and (
-            user.is_superuser or user in forum.moderators.all())
-
-
-def _can_post_in_topic(topic, user):
-    """
-    This function returns true if the given user can post in the given topic
-    and false otherwise.
-    """
-    return (not topic.locked and topic.forum.category.can_access(user)) or \
-            (user.is_superuser or user in topic.forum.moderators.all())
-
-
 def _bump_post_count(user):
     """
     Increments the forum_post_count for the given user.