CSRF protection. #361
authorEevee <git@veekun.com>
Mon, 8 Nov 2010 07:29:02 +0000 (23:29 -0800)
committerEevee <git@veekun.com>
Mon, 8 Nov 2010 07:29:02 +0000 (23:29 -0800)
splinext/forum/__init__.py
splinext/forum/controllers/forum.py
splinext/forum/templates/forum/lib.mako

index 974e29e..806795a 100644 (file)
@@ -9,14 +9,17 @@ import splinext.forum.controllers.forum
 
 def add_routes_hook(map, *args, **kwargs):
     """Hook to inject some of our behavior into the routes configuration."""
+    require_GET = dict(conditions=dict(method=['GET']))
     require_POST = dict(conditions=dict(method=['POST']))
 
     map.connect('/forums', controller='forum', action='forums')
     map.connect(r'/forums/{forum_id:\d+}', controller='forum', action='threads')
     map.connect(r'/forums/{forum_id:\d+}/threads/{thread_id:\d+}', controller='forum', action='posts')
 
-    map.connect(r'/forums/{forum_id:\d+}/write', controller='forum', action='write_thread')
-    map.connect(r'/forums/{forum_id:\d+}/threads/{thread_id:\d+}/write', controller='forum', action='write')
+    map.connect(r'/forums/{forum_id:\d+}/write', controller='forum', action='write_thread', **require_GET)
+    map.connect(r'/forums/{forum_id:\d+}/write', controller='forum', action='write_thread_commit', **require_POST)
+    map.connect(r'/forums/{forum_id:\d+}/threads/{thread_id:\d+}/write', controller='forum', action='write', **require_GET)
+    map.connect(r'/forums/{forum_id:\d+}/threads/{thread_id:\d+}/write', controller='forum', action='write_commit', **require_POST)
 
 
 class ForumPlugin(PluginBase):
index 5b5ecf9..f2eb476 100644 (file)
@@ -4,6 +4,7 @@ import math
 
 from pylons import cache, config, request, response, session, tmpl_context as c, url
 from pylons.controllers.util import abort, redirect
+from pylons.decorators.secure import authenticate_form
 from routes import request_config
 from sqlalchemy.orm import joinedload
 from sqlalchemy.orm.exc import NoResultFound
@@ -200,11 +201,25 @@ class ForumController(BaseController):
             abort(404)
 
         c.write_thread_form = WriteThreadForm(request.params)
+        return render('/forum/write_thread.mako')
 
-        if request.method != 'POST' or not c.write_thread_form.validate():
-            # Failure or initial request; show the form
-            return render('/forum/write_thread.mako')
+    @authenticate_form
+    def write_thread_commit(self, forum_id):
+        """Posts a new thread."""
+        if not c.user.can('forum:create-thread'):
+            abort(403)
+
+        try:
+            c.forum = meta.Session.query(forum_model.Forum) \
+                .filter_by(id=forum_id).one()
+        except NoResultFound:
+            abort(404)
 
+        c.write_thread_form = WriteThreadForm(request.params)
+
+        # Reshow the form on failure
+        if not c.write_thread_form.validate():
+            return render('/forum/write_thread.mako')
 
         # Otherwise, add the post.
         c.forum = meta.Session.query(forum_model.Forum) \
@@ -249,11 +264,25 @@ class ForumController(BaseController):
             abort(404)
 
         c.write_post_form = WritePostForm(request.params)
+        return render('/forum/write.mako')
 
-        if request.method != 'POST' or not c.write_post_form.validate():
-            # Failure or initial request; show the form
-            return render('/forum/write.mako')
+    @authenticate_form
+    def write_commit(self, forum_id, thread_id):
+        """Post to a thread."""
+        if not c.user.can('forum:create-post'):
+            abort(403)
+
+        try:
+            c.thread = meta.Session.query(forum_model.Thread) \
+                .filter_by(id=thread_id, forum_id=forum_id).one()
+        except NoResultFound:
+            abort(404)
 
+        c.write_post_form = WritePostForm(request.params)
+
+        # Reshow the form on failure
+        if not c.write_post_form.validate():
+            return render('/forum/write.mako')
 
         # Otherwise, add the post.
         c.thread = meta.Session.query(forum_model.Thread) \
index c82a8b2..71d0d64 100644 (file)
@@ -69,7 +69,7 @@
 <%def name="write_thread_form(forum)">
 % if forum.can_create_thread(c.user):
 <h1>Create new thread</h1>
-${h.form(url(controller='forum', action='write_thread', forum_id=forum.id))}
+${h.secure_form(url(controller='forum', action='write_thread_commit', forum_id=forum.id))}
 <dl class="standard-form">
     ${lib.field('subject', form=c.write_thread_form)}
     ${lib.field('content', form=c.write_thread_form, rows=12, cols=80)}
@@ -83,7 +83,7 @@ ${h.end_form()}
 <%def name="write_post_form(thread)">
 % if thread.can_create_post(c.user):
 <h1>Reply</h1>
-${h.form(url(controller='forum', action='write', forum_id=thread.forum.id, thread_id=thread.id))}
+${h.secure_form(url(controller='forum', action='write_commit', forum_id=thread.forum.id, thread_id=thread.id))}
 <dl class="standard-form">
     ${lib.field('content', form=c.write_post_form, rows=12, cols=80)}