about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin/accounts_controller.rb2
-rw-r--r--app/helpers/admin/filter_helper.rb2
-rw-r--r--app/lib/activitypub/activity/accept.rb2
-rw-r--r--app/lib/activitypub/activity/delete.rb2
-rw-r--r--app/lib/activitypub/activity/reject.rb2
-rw-r--r--app/lib/activitypub/activity/undo.rb2
-rw-r--r--app/models/account.rb26
-rw-r--r--app/models/account_filter.rb6
-rw-r--r--app/models/follow.rb1
-rw-r--r--app/models/follow_request.rb1
-rw-r--r--app/serializers/rest/account_serializer.rb6
-rw-r--r--app/services/verify_link_service.rb2
-rw-r--r--app/validators/follow_limit_validator.rb27
-rw-r--r--app/views/admin/accounts/index.html.haml4
-rw-r--r--app/workers/import_worker.rb4
15 files changed, 70 insertions, 19 deletions
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
index e7ca6b907..5d57fe361 100644
--- a/app/controllers/admin/accounts_controller.rb
+++ b/app/controllers/admin/accounts_controller.rb
@@ -95,7 +95,7 @@ module Admin
         :remote,
         :by_domain,
         :silenced,
-        :recent,
+        :alphabetic,
         :suspended,
         :username,
         :display_name,
diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb
index 359c43d0e..60e5142e3 100644
--- a/app/helpers/admin/filter_helper.rb
+++ b/app/helpers/admin/filter_helper.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module Admin::FilterHelper
-  ACCOUNT_FILTERS      = %i(local remote by_domain silenced suspended recent username display_name email ip staff).freeze
+  ACCOUNT_FILTERS      = %i(local remote by_domain silenced suspended alphabetic username display_name email ip staff).freeze
   REPORT_FILTERS       = %i(resolved account_id target_account_id).freeze
   INVITE_FILTER        = %i(available expired).freeze
   CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
diff --git a/app/lib/activitypub/activity/accept.rb b/app/lib/activitypub/activity/accept.rb
index 7e60b2c00..348ee0d1c 100644
--- a/app/lib/activitypub/activity/accept.rb
+++ b/app/lib/activitypub/activity/accept.rb
@@ -26,7 +26,7 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
   end
 
   def relay
-    @relay ||= Relay.find_by(follow_activity_id: object_uri)
+    @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
   end
 
   def relay_follow?
diff --git a/app/lib/activitypub/activity/delete.rb b/app/lib/activitypub/activity/delete.rb
index 3474d55d9..457047ac0 100644
--- a/app/lib/activitypub/activity/delete.rb
+++ b/app/lib/activitypub/activity/delete.rb
@@ -17,6 +17,8 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
   end
 
   def delete_note
+    return if object_uri.nil?
+
     @status   = Status.find_by(uri: object_uri, account: @account)
     @status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?
 
diff --git a/app/lib/activitypub/activity/reject.rb b/app/lib/activitypub/activity/reject.rb
index d81b157de..dba21fb9a 100644
--- a/app/lib/activitypub/activity/reject.rb
+++ b/app/lib/activitypub/activity/reject.rb
@@ -28,7 +28,7 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
   end
 
   def relay
-    @relay ||= Relay.find_by(follow_activity_id: object_uri)
+    @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
   end
 
   def relay_follow?
diff --git a/app/lib/activitypub/activity/undo.rb b/app/lib/activitypub/activity/undo.rb
index 64c2be7d9..599823c6e 100644
--- a/app/lib/activitypub/activity/undo.rb
+++ b/app/lib/activitypub/activity/undo.rb
@@ -19,6 +19,8 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
   private
 
   def undo_announce
+    return if object_uri.nil?
+
     status   = Status.find_by(uri: object_uri, account: @account)
     status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?
 
diff --git a/app/models/account.rb b/app/models/account.rb
index d0c4c1a6d..1ca27f636 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -315,8 +315,8 @@ class Account < ApplicationRecord
     def initialize(account, attributes)
       @account     = account
       @attributes  = attributes
-      @name        = attributes['name'].strip[0, 255]
-      @value       = attributes['value'].strip[0, 255]
+      @name        = attributes['name'].strip[0, string_limit]
+      @value       = attributes['value'].strip[0, string_limit]
       @verified_at = attributes['verified_at']&.to_datetime
       @errors      = {}
     end
@@ -325,8 +325,18 @@ class Account < ApplicationRecord
       verified_at.present?
     end
 
+    def value_for_verification
+      @value_for_verification ||= begin
+        if account.local?
+          value
+        else
+          ActionController::Base.helpers.strip_tags(value)
+        end
+      end
+    end
+
     def verifiable?
-      value.present? && value.start_with?('http://', 'https://')
+      value_for_verification.present? && value_for_verification.start_with?('http://', 'https://')
     end
 
     def mark_verified!
@@ -337,6 +347,16 @@ class Account < ApplicationRecord
     def to_h
       { name: @name, value: @value, verified_at: @verified_at }
     end
+
+    private
+
+    def string_limit
+      if account.local?
+        255
+      else
+        2047
+      end
+    end
   end
 
   class << self
diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb
index dc7a03039..84364bf1b 100644
--- a/app/models/account_filter.rb
+++ b/app/models/account_filter.rb
@@ -8,7 +8,7 @@ class AccountFilter
   end
 
   def results
-    scope = Account.alphabetic
+    scope = Account.recent
 
     params.each do |key, value|
       scope.merge!(scope_for(key, value)) if value.present?
@@ -29,8 +29,8 @@ class AccountFilter
       Account.where(domain: value)
     when 'silenced'
       Account.silenced
-    when 'recent'
-      Account.recent
+    when 'alphabetic'
+      Account.reorder(nil).alphabetic
     when 'suspended'
       Account.suspended
     when 'username'
diff --git a/app/models/follow.rb b/app/models/follow.rb
index 714f4e898..7ad56eb78 100644
--- a/app/models/follow.rb
+++ b/app/models/follow.rb
@@ -25,6 +25,7 @@ class Follow < ApplicationRecord
   has_one :notification, as: :activity, dependent: :destroy
 
   validates :account_id, uniqueness: { scope: :target_account_id }
+  validates_with FollowLimitValidator, on: :create
 
   scope :recent, -> { reorder(id: :desc) }
 
diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb
index 9c4875564..c5451a050 100644
--- a/app/models/follow_request.rb
+++ b/app/models/follow_request.rb
@@ -22,6 +22,7 @@ class FollowRequest < ApplicationRecord
   has_one :notification, as: :activity, dependent: :destroy
 
   validates :account_id, uniqueness: { scope: :target_account_id }
+  validates_with FollowLimitValidator, on: :create
 
   def authorize!
     account.follow!(target_account, reblogs: show_reblogs, uri: uri)
diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb
index d84b48afb..12adc971c 100644
--- a/app/serializers/rest/account_serializer.rb
+++ b/app/serializers/rest/account_serializer.rb
@@ -11,11 +11,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
   has_many :emojis, serializer: REST::CustomEmojiSerializer
 
   class FieldSerializer < ActiveModel::Serializer
-    attributes :name, :value
-
-    attribute :verified_at, if: :verifiable?
-
-    delegate :verifiable?, to: :object
+    attributes :name, :value, :verified_at
 
     def value
       Formatter.instance.format_field(object.account, object.value)
diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb
index 7d53bc255..3453b54c5 100644
--- a/app/services/verify_link_service.rb
+++ b/app/services/verify_link_service.rb
@@ -3,7 +3,7 @@
 class VerifyLinkService < BaseService
   def call(field)
     @link_back = ActivityPub::TagManager.instance.url_for(field.account)
-    @url       = field.value
+    @url       = field.value_for_verification
 
     perform_request!
 
diff --git a/app/validators/follow_limit_validator.rb b/app/validators/follow_limit_validator.rb
new file mode 100644
index 000000000..eb083ed85
--- /dev/null
+++ b/app/validators/follow_limit_validator.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class FollowLimitValidator < ActiveModel::Validator
+  LIMIT = ENV.fetch('MAX_FOLLOWS_THRESHOLD', 7_500).to_i
+  RATIO = ENV.fetch('MAX_FOLLOWS_RATIO', 1.1).to_f
+
+  def validate(follow)
+    return if follow.account.nil? || !follow.account.local?
+    follow.errors.add(:base, I18n.t('users.follow_limit_reached', limit: self.class.limit_for_account(follow.account))) if limit_reached?(follow.account)
+  end
+
+  class << self
+    def limit_for_account(account)
+      if account.following_count < LIMIT
+        LIMIT
+      else
+        account.followers_count * RATIO
+      end
+    end
+  end
+
+  private
+
+  def limit_reached?(account)
+    account.following_count >= self.class.limit_for_account(account)
+  end
+end
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index 6aa39a80a..4bee73adc 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -38,8 +38,8 @@
   .filter-subset
     %strong= t('admin.accounts.order.title')
     %ul
-      %li= filter_link_to t('admin.accounts.order.alphabetic'), recent: nil
-      %li= filter_link_to t('admin.accounts.order.most_recent'), recent: '1'
+      %li= filter_link_to t('admin.accounts.order.most_recent'), alphabetic: nil
+      %li= filter_link_to t('admin.accounts.order.alphabetic'), alphabetic: '1'
 
 = form_tag admin_accounts_url, method: 'GET', class: 'simple_form' do
   .fields-group
diff --git a/app/workers/import_worker.rb b/app/workers/import_worker.rb
index d7c126f75..aeb221cf6 100644
--- a/app/workers/import_worker.rb
+++ b/app/workers/import_worker.rb
@@ -37,6 +37,8 @@ class ImportWorker
   end
 
   def import_rows
-    CSV.new(import_contents).reject(&:blank?)
+    rows = CSV.new(import_contents).reject(&:blank?)
+    rows = rows.take(FollowLimitValidator.limit_for_account(@import.account)) if @import.type == 'following'
+    rows
   end
 end