Merge pull request #3427 from evazion/feat-autoban-spammers
Fix #3408: More automated measures against spammers
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
require 'digest/sha1'
|
||||
|
||||
class Dmail < ApplicationRecord
|
||||
# if a person sends spam to more than 10 users within a 24 hour window, automatically ban them for 3 days.
|
||||
AUTOBAN_THRESHOLD = 10
|
||||
AUTOBAN_WINDOW = 24.hours
|
||||
AUTOBAN_DURATION = 3
|
||||
|
||||
include Rakismet::Model
|
||||
|
||||
with_options on: :create do
|
||||
@@ -23,6 +28,23 @@ class Dmail < ApplicationRecord
|
||||
rakismet_attrs author: :from_name, author_email: :from_email, content: :title_and_body, user_ip: :creator_ip_addr_str
|
||||
|
||||
concerning :SpamMethods do
|
||||
class_methods do
|
||||
def is_spammer?(user)
|
||||
return false if user.is_gold?
|
||||
|
||||
spammed_users = sent_by(user).where(is_spam: true).where("created_at > ?", AUTOBAN_WINDOW.ago).distinct.count(:to_id)
|
||||
spammed_users >= AUTOBAN_THRESHOLD
|
||||
end
|
||||
|
||||
def ban_spammer(spammer)
|
||||
spammer.bans.create! do |ban|
|
||||
ban.banner = User.system
|
||||
ban.reason = "Spambot."
|
||||
ban.duration = AUTOBAN_DURATION
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def title_and_body
|
||||
"#{title}\n\n#{body}"
|
||||
end
|
||||
@@ -31,9 +53,9 @@ class Dmail < ApplicationRecord
|
||||
creator_ip_addr.to_s
|
||||
end
|
||||
|
||||
def spam?(sender = CurrentUser.user)
|
||||
def spam?
|
||||
return false if Danbooru.config.rakismet_key.blank?
|
||||
return false if sender.is_gold?
|
||||
return false if from.is_gold?
|
||||
super()
|
||||
end
|
||||
end
|
||||
@@ -58,7 +80,6 @@ class Dmail < ApplicationRecord
|
||||
def initialize_attributes
|
||||
self.from_id ||= CurrentUser.id
|
||||
self.creator_ip_addr ||= CurrentUser.ip_addr
|
||||
self.is_spam = spam?(CurrentUser.user)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -73,6 +94,7 @@ class Dmail < ApplicationRecord
|
||||
# recipient's copy
|
||||
copy = Dmail.new(params)
|
||||
copy.owner_id = copy.to_id
|
||||
copy.is_spam = copy.spam?
|
||||
copy.save unless copy.to_id == copy.from_id
|
||||
|
||||
# sender's copy
|
||||
@@ -80,13 +102,15 @@ class Dmail < ApplicationRecord
|
||||
copy.owner_id = copy.from_id
|
||||
copy.is_read = true
|
||||
copy.save
|
||||
|
||||
Dmail.ban_spammer(copy.from) if Dmail.is_spammer?(copy.from)
|
||||
end
|
||||
|
||||
copy
|
||||
end
|
||||
|
||||
def create_automated(params)
|
||||
dmail = Dmail.new(from: Danbooru.config.system_user, **params)
|
||||
dmail = Dmail.new(from: User.system, **params)
|
||||
dmail.owner = dmail.to
|
||||
dmail.save
|
||||
dmail
|
||||
@@ -119,6 +143,10 @@ class Dmail < ApplicationRecord
|
||||
end
|
||||
|
||||
module SearchMethods
|
||||
def sent_by(user)
|
||||
where("dmails.from_id = ? AND dmails.owner_id != ?", user.id, user.id)
|
||||
end
|
||||
|
||||
def active
|
||||
where("is_deleted = ?", false)
|
||||
end
|
||||
@@ -234,7 +262,7 @@ class Dmail < ApplicationRecord
|
||||
end
|
||||
|
||||
def is_automated?
|
||||
from == Danbooru.config.system_user
|
||||
from == User.system
|
||||
end
|
||||
|
||||
def filtered?
|
||||
|
||||
@@ -316,7 +316,7 @@ class User < ApplicationRecord
|
||||
|
||||
module ClassMethods
|
||||
def system
|
||||
Danbooru.config.system_user
|
||||
User.find_by!(name: Danbooru.config.system_user)
|
||||
end
|
||||
|
||||
def level_hash
|
||||
@@ -366,7 +366,7 @@ class User < ApplicationRecord
|
||||
def promote_to_admin_if_first_user
|
||||
return if Rails.env.test?
|
||||
|
||||
if User.count == 0
|
||||
if User.admins.count == 0
|
||||
self.level = Levels::ADMIN
|
||||
self.can_approve_posts = true
|
||||
self.can_upload_free = true
|
||||
|
||||
Reference in New Issue
Block a user