about summary refs log tree commit diff
path: root/app/models/user.rb
diff options
context:
space:
mode:
authormultiple creatures <dev@multiple-creature.party>2019-11-06 00:08:06 -0600
committermultiple creatures <dev@multiple-creature.party>2019-11-06 00:08:06 -0600
commit0db4b0b9d550b22f531cc427ddc2dcd68b0a9ae1 (patch)
treeb614ab137163b66c268fa101b3eb743937bc9b4b /app/models/user.rb
parentaf9b9777af9601bb2de857e6e4fea0b07d699108 (diff)
perform spam detection at registration time
Diffstat (limited to 'app/models/user.rb')
-rw-r--r--app/models/user.rb39
1 files changed, 37 insertions, 2 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index 11289a0a5..f72acd452 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -44,6 +44,7 @@
 class User < ApplicationRecord
   include Settings::Extend
   include UserRoles
+  include LogHelper
 
   # The home and list feeds will be stored in Redis for this amount
   # of time, and status fan-out to followers will include only people
@@ -54,6 +55,12 @@ class User < ApplicationRecord
   # to check their feed
   ACTIVE_DURATION = ENV.fetch('USER_ACTIVE_DAYS', 7).to_i.days.freeze
 
+  spam_triggers = ENV.fetch('REGISTRATION_SPAM_TRIGGERS', '').split('|').map { |phrase| Regexp.escape(phrase.strip) }
+  spam_triggers = spam_triggers.empty? ? /(?!)/ : /\b#{Regexp.union(spam_triggers)}\b/i
+
+  SPAM_TRIGGERS = spam_triggers.freeze
+
+
   devise :two_factor_authenticatable,
          otp_secret_encryption_key: Rails.configuration.x.otp_secret
 
@@ -198,7 +205,7 @@ class User < ApplicationRecord
     if new_user && approved?
       prepare_new_user!
     elsif new_user
-      RegistrationJanitorWorker.perform_async(id)
+      notify_staff_about_pending_account!
     end
   end
 
@@ -243,13 +250,36 @@ class User < ApplicationRecord
   end
 
   def notify_staff_about_pending_account!
-    LogWorker.perform_async("\xf0\x9f\x86\x95 New account <#{Account.find(account_id).username}> is awaiting admin approval.\n\nReview (moderators only): https://#{Rails.configuration.x.web_domain || Rails.configuration.x.local_domain}/admin/pending_accounts")
+    LogWorker.perform_async("\xf0\x9f\x86\x95 New account <#{self.account.username}> is awaiting admin approval.\n\nReview (moderators only): https://#{Rails.configuration.x.web_domain || Rails.configuration.x.local_domain}/admin/pending_accounts")
     User.staff.includes(:account).each do |u|
       next unless u.allows_pending_account_emails?
       AdminMailer.new_pending_account(u.account, self).deliver_later
     end
   end
 
+  def detect_spam!
+    janitor = janitor_account || Account.representative
+
+    intro = self.invite_request&.text
+    # normalize it
+    intro = intro.gsub(/[\u200b-\u200d\ufeff\u200e\u200f]/, '').strip.downcase unless intro.nil?
+
+    return false unless intro.blank? || intro.split.count < 5 || SPAM_TRIGGERS.match?(intro)
+
+    user_friendly_action_log(janitor, :reject_registration, self.account.username, "Registration was spam filtered.")
+    Form::AccountBatch.new(current_account: janitor, account_ids: account_id, action: 'reject').save
+
+    true
+  rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
+    false
+  end
+
+  def janitor_account
+    account_id = ENV.fetch('JANITOR_USER', '').to_i
+    return if account_id == 0
+    Account.find_by(id: account_id)
+  end
+
   def wants_larger_menus?
     @wants_larger_menus ||= (settings.larger_menus || false)
   end
@@ -459,6 +489,11 @@ class User < ApplicationRecord
     super
   end
 
+  def send_confirmation_instructions
+    return false if detect_spam!
+    super
+  end
+
   def show_all_media?
     setting_display_media == 'show_all'
   end