FIX: FlagSockpuppets should not flag a post if a post of that user was already rejected by staff (#9328)

FIX: FlagSockpuppets should not flag a post if a post of that user was already rejected by staff (#9328)

  • FIX: FlagSockpuppets should not flag a post if a post of that user was already rejected by staff

  • Update spec/services/flag_sockpuppets_spec.rb

Co-Authored-By: Robin Ward robin.ward@gmail.com

Co-authored-by: Robin Ward robin.ward@gmail.com

diff --git a/app/services/spam_rule/flag_sockpuppets.rb b/app/services/spam_rule/flag_sockpuppets.rb
index 26c53ff..1bc930b 100644
--- a/app/services/spam_rule/flag_sockpuppets.rb
+++ b/app/services/spam_rule/flag_sockpuppets.rb
@@ -19,8 +19,6 @@ class SpamRule::FlagSockpuppets
 
   def reply_is_from_sockpuppet?
     return false if @post.try(:post_number) == 1
-
-    first_post = @post.topic.posts.by_post_number.first
     return false if first_post.user.nil?
 
     !first_post.user.staff? &&
@@ -41,11 +39,22 @@ class SpamRule::FlagSockpuppets
       locale: SiteSetting.default_locale
     )
 
-    PostActionCreator.create(Discourse.system_user, @post, :spam, message: message)
+    flag_post(@post, message)
 
-    if (first_post = @post.topic.posts.by_post_number.first).try(:user).try(:new_user?)
-      PostActionCreator.create(Discourse.system_user, first_post, :spam, message: message)
-    end
+    flag_post(first_post, message) if first_post&.user&.new_user?
+  end
+
+  private
+
+  def flag_post(post, message)
+    can_trust_user = ReviewableFlaggedPost.where(status: Reviewable.statuses[:rejected], target_created_by: post.user).exists?
+    return if can_trust_user
+
+    PostActionCreator.create(Discourse.system_user, post, :spam, message: message)
+  end
+
+  def first_post
+    @first_post ||= @post.topic.posts.by_post_number.first
   end
 
 end
diff --git a/spec/services/flag_sockpuppets_spec.rb b/spec/services/flag_sockpuppets_spec.rb
index 985d8fc..cebb398 100644
--- a/spec/services/flag_sockpuppets_spec.rb
+++ b/spec/services/flag_sockpuppets_spec.rb
@@ -150,5 +150,28 @@ describe SpamRule::FlagSockpuppets do
       expect(PostAction.where(user: system, post: post2, post_action_type_id: spam).exists?).to eq(true)
       expect(PostAction.where(user: system, post: post1, post_action_type_id: spam).exists?).to eq(false)
     end
+
+    it "doesn't flag the first post if it was already rejected by staff before" do
+      flagged_post = Fabricate(
+        :reviewable_flagged_post,
+        target: post1, status: Reviewable.statuses[:rejected], target_created_by: post1.user
+      )
+
+      described_class.new(post2).perform
+
+      expect(flagged_post.reload.status).to eq(Reviewable.statuses[:rejected])
+    end
+
+    it "doesn't flag the post if another post of the same user was rejected by staff before" do
+      another_post = Fabricate(:post, user: user1)
+      flagged_post = Fabricate(
+        :reviewable_flagged_post,
+        target: another_post, status: Reviewable.statuses[:rejected], target_created_by: another_post.user
+      )
+
+      described_class.new(post2).perform
+
+      expect(ReviewableFlaggedPost.where(target_created_by: user1).count).to eq(1)
+    end
   end
 end

GitHub sha: b2f30aa0

This commit appears in #9328 which was approved by eviltrout. It was merged by romanrizzi.