Commit 5149c613 authored by Developer's avatar Developer

Added StatusSimilarityService to check against spamming same statuses over and over

• Added:
- StatusSimilarityService to check against spamming same statuses over and over
- StatusSimilarityService check to PostStatusService and EditStatusService
parent a955c51e
......@@ -25,6 +25,7 @@ class EditStatusService < BaseService
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
validate_similarity!
validate_links!
validate_media!
preprocess_attributes!
......@@ -92,6 +93,10 @@ class EditStatusService < BaseService
raise GabSocial::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && hasVideoOrGif
end
def validate_similarity!
raise GabSocial::NotPermittedError if StatusSimilarityService.new.call?(@text, @account.id)
end
def validate_links!
raise GabSocial::LinkBlockedError if LinkBlock.block?(@text)
end
......
......@@ -34,6 +34,7 @@ class PostStatusService < BaseService
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
validate_similarity!
validate_links!
validate_media!
validate_group!
......@@ -159,6 +160,10 @@ class PostStatusService < BaseService
raise GabSocial::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && hasVideoOrGif
end
def validate_similarity!
raise GabSocial::NotPermittedError if StatusSimilarityService.new.call?(@text, @account.id)
end
def validate_links!
raise GabSocial::NotPermittedError if LinkBlock.block?(@text)
end
......
# frozen_string_literal: true
require 'similar_text'
class StatusSimilarityService < BaseService
def call?(status_text = "", account_id = nil)
@status_text = status_text
@account_id = account_id
# Not alike if no status_text or no account
# : todo : come up with solution for same image spamming
return false if @status_text.length == 0 || @account_id.nil?
alike?
end
private
def alike?
last_status_text = nil
key = "last_status_from_account:#{@account_id}"
Redis.current.with do |conn|
last_status_text = conn.get(key) || ""
conn.setex(key, 300, @status_text)
end
if last_status_text.nil? || last_status_text.empty? || last_status_text.length == 0
  • Rails provides a blank? method (and present?, which is just !blank?) on all classes. It’s got some specialized logic depending on the class of the receiver. For strings, it makes sure that it’s not empty (empty? is a C function that does length == 0), and also that it’s not whitespace only.

    https://rubyapi.org/2.6/o/string#method-i-empty-3F

    https://github.com/rails/rails/blob/main/activesupport/lib/active_support/core_ext/object/blank.rb

Please register or sign in to reply
return false
end
likeness = last_status_text.similar(@status_text)
likeness > 85
end
end
  • Should do similar with comments, but be sure to strip out tags before comparing similarity (but somehow not flag people saying “yes!” or other common legitimate relies). It seems like the bots actually use the UI, because they always include the correct tags in the beginning of their replies.

    B631D4FE-E2FF-45F7-84DF-9F11FCBAAF03

Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment