FIX: dupe protection is API only now

make optional later on (was introduced for wordpress plugin)
This commit is contained in:
Sam
2014-07-14 15:59:58 +10:00
parent d4cd2f1ebf
commit 6618358586
3 changed files with 71 additions and 24 deletions

View File

@ -49,22 +49,20 @@ class PostsController < ApplicationController
key = params_key(params) key = params_key(params)
error_json = nil error_json = nil
if (is_api?)
payload = DistributedMemoizer.memoize(key, 120) do payload = DistributedMemoizer.memoize(key, 120) do
post_creator = PostCreator.new(current_user, params) success, json = create_post(params)
post = post_creator.create unless success
if post_creator.errors.present? error_json = json
# If the post was spam, flag all the user's posts as spam
current_user.flag_linked_posts_as_spam if post_creator.spam?
error_json = MultiJson.dump(errors: post_creator.errors.full_messages)
raise Discourse::InvalidPost raise Discourse::InvalidPost
end
json
end
else else
post_serializer = PostSerializer.new(post, scope: guardian, root: false) success, payload = create_post(params)
post_serializer.topic_slug = post.topic.slug if post.topic.present? unless success
post_serializer.draft_sequence = DraftSequence.current(current_user, post.topic.draft_key) error_json = payload
MultiJson.dump(post_serializer) raise Discourse::InvalidPost
end end
end end
@ -74,6 +72,22 @@ class PostsController < ApplicationController
render json: error_json, status: 422 render json: error_json, status: 422
end end
def create_post(params)
post_creator = PostCreator.new(current_user, params)
post = post_creator.create
if post_creator.errors.present?
# If the post was spam, flag all the user's posts as spam
current_user.flag_linked_posts_as_spam if post_creator.spam?
[false, MultiJson.dump(errors: post_creator.errors.full_messages)]
else
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
post_serializer.topic_slug = post.topic.slug if post.topic.present?
post_serializer.draft_sequence = DraftSequence.current(current_user, post.topic.draft_key)
[true, MultiJson.dump(post_serializer)]
end
end
def update def update
params.require(:post) params.require(:post)

View File

@ -215,7 +215,7 @@ describe PostCreator do
context "disabled" do context "disabled" do
before do before do
SiteSetting.stubs(:unique_posts_mins).returns(0) SiteSetting.unique_posts_mins = 0
creator.create creator.create
end end
@ -229,22 +229,37 @@ describe PostCreator do
let(:new_post_creator) { PostCreator.new(user, basic_topic_params) } let(:new_post_creator) { PostCreator.new(user, basic_topic_params) }
before do before do
SiteSetting.stubs(:unique_posts_mins).returns(10) SiteSetting.unique_posts_mins = 10
creator.create end
it "fails for dupe post accross topic" do
first = create_post
second = create_post
dupe = "hello 123 test #{SecureRandom.hex}"
response_1 = create_post(raw: dupe, user: first.user, topic_id: first.topic_id)
response_2 = create_post(raw: dupe, user: first.user, topic_id: second.topic_id)
response_1.errors.count.should == 0
response_2.errors.count.should == 1
end end
it "returns blank for another post with the same content" do it "returns blank for another post with the same content" do
creator.create
new_post_creator.create new_post_creator.create
new_post_creator.errors.should be_present new_post_creator.errors.should be_present
end end
it "returns a post for admins" do it "returns a post for admins" do
creator.create
user.admin = true user.admin = true
new_post_creator.create new_post_creator.create
new_post_creator.errors.should be_blank new_post_creator.errors.should be_blank
end end
it "returns a post for moderators" do it "returns a post for moderators" do
creator.create
user.moderator = true user.moderator = true
new_post_creator.create new_post_creator.create
new_post_creator.errors.should be_blank new_post_creator.errors.should be_blank

View File

@ -367,6 +367,25 @@ describe PostsController do
include_examples 'action requires login', :post, :create include_examples 'action requires login', :post, :create
context 'api' do
it 'allows dupes through' do
raw = "this is a test post 123 #{SecureRandom.hash}"
title = "this is a title #{SecureRandom.hash}"
user = Fabricate(:user)
master_key = ApiKey.create_master_key.key
xhr :post, :create, {api_username: user.username, api_key: master_key, raw: raw, title: title, wpid: 1}
response.should be_success
original = response.body
xhr :post, :create, {api_username: user.username_lower, api_key: master_key, raw: raw, title: title, wpid: 2}
response.should be_success
response.body.should == original
end
end
describe 'when logged in' do describe 'when logged in' do
let!(:user) { log_in } let!(:user) { log_in }
@ -389,15 +408,14 @@ describe PostsController do
end end
it 'protects against dupes' do it 'protects against dupes' do
# TODO we really should be using a mock redis here raw = "this is a test post 123 #{SecureRandom.hash}"
xhr :post, :create, {raw: 'this is a test post 123', title: 'this is a test title 123', wpid: 1} title = "this is a title #{SecureRandom.hash}"
response.should be_success
original = response.body
xhr :post, :create, {raw: 'this is a test post 123', title: 'this is a test title 123', wpid: 2} xhr :post, :create, {raw: raw, title: title, wpid: 1}
response.should be_success response.should be_success
response.body.should == original xhr :post, :create, {raw: raw, title: title, wpid: 2}
response.should_not be_success
end end
context "errors" do context "errors" do