From f6b850e7a40ad0c3dc48c6cd60582f5938ba3301 Mon Sep 17 00:00:00 2001
From: Sam <sam.saffron@gmail.com>
Date: Tue, 2 Jul 2013 12:22:56 +1000
Subject: [PATCH] allow skipping the validations on creation if its an api call
 AND skip_validations is specified this allows wordpress plugin to post very
 very short titles or titles that would otherwise be disallowed

---
 app/controllers/posts_controller.rb  | 31 ++++++++++++++++++----------
 app/models/topic.rb                  |  3 +--
 lib/post_creator.rb                  |  2 +-
 lib/topic_creator.rb                 |  2 +-
 spec/components/post_creator_spec.rb |  8 +++++++
 5 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index d431d92dfd9..ab74df97998 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -189,18 +189,27 @@ class PostsController < ApplicationController
   private
 
     def create_params
-      params.require(:raw)
-      params.permit(
-          :raw, 
-          :topic_id, 
-          :title, 
-          :archetype, 
-          :category, 
-          :target_usernames, 
-          :reply_to_post_number, 
-          :image_sizes, 
+      permitted = [
+          :raw,
+          :topic_id,
+          :title,
+          :archetype,
+          :category,
+          :target_usernames,
+          :reply_to_post_number,
+          :image_sizes,
           :auto_close_days
-        ).tap do |whitelisted|
+      ]
+
+      if api_key_valid?
+        # php seems to be sending this incorrectly, don't fight with it
+        params[:skip_validations] = params[:skip_validations].to_s == "true"
+        permitted << :skip_validations
+      end
+
+      params.require(:raw)
+      params.permit(*permitted).tap do |whitelisted|
+          # TODO this does not feel right, we should name what meta_data is allowed
           whitelisted[:meta_data] = params[:meta_data]
       end
     end
diff --git a/app/models/topic.rb b/app/models/topic.rb
index 0f76257a880..771fc1cb972 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -35,8 +35,6 @@ class Topic < ActiveRecord::Base
   rate_limit :limit_topics_per_day
   rate_limit :limit_private_messages_per_day
 
-  before_validation :sanitize_title
-
   validates :title, :presence => true,
                     :topic_title_length => true,
                     :quality_title => { :unless => :private_message? },
@@ -47,6 +45,7 @@ class Topic < ActiveRecord::Base
                                         :collection => Proc.new{ Topic.listable_topics } }
 
   before_validation do
+    self.sanitize_title
     self.title = TextCleaner.clean_title(TextSentinel.title_sentinel(title).text) if errors[:title].empty?
   end
 
diff --git a/lib/post_creator.rb b/lib/post_creator.rb
index eb14c4b8e35..09852b105f9 100644
--- a/lib/post_creator.rb
+++ b/lib/post_creator.rb
@@ -208,7 +208,7 @@ class PostCreator
   end
 
   def save_post
-    unless @post.save
+    unless @post.save(validate: !@opts[:skip_validations])
       @errors = @post.errors
       raise ActiveRecord::Rollback.new
     end
diff --git a/lib/topic_creator.rb b/lib/topic_creator.rb
index 8ac5d19c7bf..107952e1399 100644
--- a/lib/topic_creator.rb
+++ b/lib/topic_creator.rb
@@ -56,7 +56,7 @@ class TopicCreator
   end
 
   def save_topic
-    unless @topic.save
+    unless @topic.save(validate: !@opts[:skip_validations])
       @errors = @topic.errors
       raise ActiveRecord::Rollback.new
     end
diff --git a/spec/components/post_creator_spec.rb b/spec/components/post_creator_spec.rb
index 84c2a64e860..8dd8c069832 100644
--- a/spec/components/post_creator_spec.rb
+++ b/spec/components/post_creator_spec.rb
@@ -341,5 +341,13 @@ describe PostCreator do
       post.created_at.should be_within(10.seconds).of(created_at)
     end
   end
+
+  context 'disable validations' do
+    it 'can save a post' do
+      creator = PostCreator.new(user, raw: 'q', title: 'q', skip_validations: true)
+      post = creator.create
+      creator.errors.should be_nil
+    end
+  end
 end