uploads: add limit to prevent users from submitting too many uploads at once.
Add a limit so that users can't upload more if they already have more than 250 images queued for upload. For example, if you upload a Pixiv post that has 200 images, then you'll have 200 queued images for upload. This will go down as the images are processed. If you exceed the limit, then trying to create new uploads will return an error. This is to prevent single users from overwhelming the site by uploading too many images at once, thereby preventing other users from uploading because the job queue is backed up and can't process new uploads by other users until existing uploads are finished.
This commit is contained in:
@@ -6,6 +6,9 @@ class Upload < ApplicationRecord
|
||||
|
||||
MAX_FILES_PER_UPLOAD = 100
|
||||
|
||||
# The maximum number of 'pending' or 'processing' media assets a single user can have at once.
|
||||
MAX_QUEUED_ASSETS = 250
|
||||
|
||||
attr_accessor :files
|
||||
|
||||
belongs_to :uploader, class_name: "User"
|
||||
@@ -19,6 +22,7 @@ class Upload < ApplicationRecord
|
||||
validates :source, format: { with: %r{\Ahttps?://}i, message: "is not a valid URL" }, if: -> { source.present? }
|
||||
validates :referer_url, format: { with: %r{\Ahttps?://}i, message: "is not a valid URL" }, if: -> { referer_url.present? }
|
||||
validate :validate_file_and_source, on: :create
|
||||
validate :uploader_is_not_limited, on: :create
|
||||
|
||||
after_create :async_process_upload!
|
||||
|
||||
@@ -64,6 +68,14 @@ class Upload < ApplicationRecord
|
||||
errors.add(:base, "No file or source given")
|
||||
end
|
||||
end
|
||||
|
||||
def uploader_is_not_limited
|
||||
queued_asset_count = uploader.upload_media_assets.unfinished.count
|
||||
|
||||
if queued_asset_count > MAX_QUEUED_ASSETS
|
||||
errors.add(:base, "You have too many images queued for upload (queued: #{queued_asset_count}; limit: #{MAX_QUEUED_ASSETS}). Try again later.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
concerning :SourceMethods do
|
||||
|
||||
@@ -23,6 +23,9 @@ class UploadMediaAsset < ApplicationRecord
|
||||
failed: 300,
|
||||
}
|
||||
|
||||
scope :unfinished, -> { where(status: %w[pending processing]) }
|
||||
scope :finished, -> { where(status: %w[active failed]) }
|
||||
|
||||
def self.visible(user)
|
||||
if user.is_admin?
|
||||
all
|
||||
|
||||
@@ -109,6 +109,7 @@ class User < ApplicationRecord
|
||||
validate :validate_custom_css, if: :custom_style_changed?
|
||||
before_validation :normalize_blacklisted_tags
|
||||
before_create :promote_to_owner_if_first_user
|
||||
|
||||
has_many :artist_versions, foreign_key: :updater_id
|
||||
has_many :artist_commentary_versions, foreign_key: :updater_id
|
||||
has_many :comments, foreign_key: :creator_id
|
||||
@@ -131,7 +132,6 @@ class User < ApplicationRecord
|
||||
has_many :purchased_upgrades, class_name: "UserUpgrade", foreign_key: :purchaser_id, dependent: :destroy
|
||||
has_many :user_events, dependent: :destroy
|
||||
has_one :active_ban, -> { active }, class_name: "Ban"
|
||||
|
||||
has_one :email_address, dependent: :destroy
|
||||
has_many :api_keys, dependent: :destroy
|
||||
has_many :note_versions, :foreign_key => "updater_id"
|
||||
@@ -145,6 +145,8 @@ class User < ApplicationRecord
|
||||
has_many :ip_bans, foreign_key: :creator_id
|
||||
has_many :tag_aliases, foreign_key: :creator_id
|
||||
has_many :tag_implications, foreign_key: :creator_id
|
||||
has_many :uploads, foreign_key: :uploader_id, dependent: :destroy
|
||||
has_many :upload_media_assets, through: :uploads, dependent: :destroy
|
||||
belongs_to :inviter, class_name: "User", optional: true
|
||||
|
||||
accepts_nested_attributes_for :email_address, reject_if: :all_blank, allow_destroy: true
|
||||
|
||||
Reference in New Issue
Block a user