diff options
author | multiple creatures <dev@multiple-creature.party> | 2019-08-08 09:59:14 -0500 |
---|---|---|
committer | multiple creatures <dev@multiple-creature.party> | 2019-08-08 12:46:17 -0500 |
commit | 4dfc40324b1f3b20550982621501e162d2ed3bed (patch) | |
tree | 1578cba8809b7db27dc82f4d439471194d5fad31 /app/services | |
parent | d019e55b7bc496d3c4d942fb4ffe65bb7e149249 (diff) |
add new `reject unknown` policy option to prevent spam & harassment from large/undermoderated servers
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/activitypub/fetch_remote_status_service.rb | 4 | ||||
-rw-r--r-- | app/services/block_domain_service.rb | 51 | ||||
-rw-r--r-- | app/services/favourite_service.rb | 2 | ||||
-rw-r--r-- | app/services/fetch_remote_status_service.rb | 5 | ||||
-rw-r--r-- | app/services/follow_service.rb | 2 | ||||
-rw-r--r-- | app/services/post_status_service.rb | 5 | ||||
-rw-r--r-- | app/services/reblog_service.rb | 2 | ||||
-rw-r--r-- | app/services/resolve_url_service.rb | 2 |
8 files changed, 59 insertions, 14 deletions
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb index 42280ad74..423c7bc9a 100644 --- a/app/services/activitypub/fetch_remote_status_service.rb +++ b/app/services/activitypub/fetch_remote_status_service.rb @@ -5,7 +5,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService include AutorejectHelper # Should be called when uri has already been checked for locality - def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil) + def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil, announced_by: nil, requested: false) return if autoreject?(uri) @json = if prefetched_body.nil? @@ -24,7 +24,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService return if actor.nil? || actor.suspended? - ActivityPub::Activity.factory(activity_json, actor).perform + ActivityPub::Activity.factory(activity_json, actor, announced_by: announced_by, requested: requested).perform end private diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index 908deacf4..5a6f4a6ce 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -5,8 +5,11 @@ class BlockDomainService < BaseService def call(domain_block) @domain_block = domain_block + @affected_status_ids = [] + remove_existing_block! process_domain_block! + invalidate_association_caches! end private @@ -16,8 +19,9 @@ class BlockDomainService < BaseService end def process_domain_block! - clear_media! if domain_block.reject_media? + clear_media! if domain_block.reject_media? || domain_block.suspend? force_accounts_sensitive! if domain_block.force_sensitive? + mark_unknown_accounts! if domain_block.reject_unknown? if domain_block.force_unlisted? force_accounts_unlisted! @@ -39,17 +43,22 @@ class BlockDomainService < BaseService def force_accounts_sensitive! ApplicationRecord.transaction do blocked_domain_accounts.in_batches.update_all(force_sensitive: true) - blocked_domain_accounts.reorder(nil).find_each do |account| + blocked_domain_accounts.find_each do |account| + @affected_status_ids |= account.statuses.where(sensitive: false).pluck(:id) account.statuses.where(sensitive: false).in_batches.update_all(sensitive: true) end end - invalidate_association_caches! unless @affected_status_ids.blank? + end + + def mark_unknown_accounts! + unknown_accounts.in_batches.update_all(known: false) end def force_accounts_unlisted! ApplicationRecord.transaction do blocked_domain_accounts.in_batches.update_all(force_unlisted: true) - blocked_domain_accounts.reorder(nil).find_each do |account| + blocked_domain_accounts.find_each do |account| + @affected_status_ids |= account.statuses.with_public_visibility.pluck(:id) account.statuses.with_public_visibility.in_batches.update_all(visibility: :unlisted) end end @@ -60,23 +69,21 @@ class BlockDomainService < BaseService end def clear_media! - @affected_status_ids = [] clear_account_images! clear_account_attachments! clear_emojos! - invalidate_association_caches! end def suspend_accounts! - blocked_domain_accounts.without_suspended.reorder(nil).find_each do |account| + blocked_domain_accounts.without_suspended.find_each do |account| SuspendAccountService.new.call(account, suspended_at: @domain_block.created_at) end end def clear_account_images! - blocked_domain_accounts.reorder(nil).find_each do |account| + blocked_domain_accounts.find_each do |account| account.avatar.destroy if account.avatar.exists? account.header.destroy if account.header.exists? account.save @@ -84,7 +91,7 @@ class BlockDomainService < BaseService end def clear_account_attachments! - media_from_blocked_domain.reorder(nil).find_each do |attachment| + media_from_blocked_domain.find_each do |attachment| @affected_status_ids << attachment.status_id if attachment.status_id.present? attachment.file.destroy if attachment.file.exists? @@ -102,7 +109,7 @@ class BlockDomainService < BaseService end def blocked_domain_accounts - Account.where(domain: blocked_domain) + Account.where(domain: blocked_domain).reorder(nil) end def media_from_blocked_domain @@ -112,4 +119,28 @@ class BlockDomainService < BaseService def emojis_from_blocked_domains CustomEmoji.where(domain: blocked_domain) end + + def unknown_accounts + Account.where(id: blocked_domain_accounts.pluck(:id) - known_account_ids).reorder(nil) + end + + def known_account_ids + local_accounts | packmates | boosted_authors | faved_authors + end + + def boosted_authors + Status.where(id: Status.local.reblogs.reorder(nil).select(:reblog_of_id)).reorder(nil).pluck(:account_id) + end + + def faved_authors + Status.where(id: Favourite.select(:status_id)).reorder(nil).pluck(:account_id) + end + + def local_accounts + Account.local.pluck(:id) + end + + def packmates + Account.local.flat_map { |account| account.following_ids | account.follower_ids } + end end diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb index ee3248877..ce13b92ed 100644 --- a/app/services/favourite_service.rb +++ b/app/services/favourite_service.rb @@ -16,6 +16,8 @@ class FavouriteService < BaseService favourite = Favourite.create!(account: account, status: status) + status.account.mark_known! unless status.account.known? + curate_status(status) create_notification(favourite) unless skip_notify bump_potential_friendship(account, status) diff --git a/app/services/fetch_remote_status_service.rb b/app/services/fetch_remote_status_service.rb index 2c6dbb58d..4fde2b395 100644 --- a/app/services/fetch_remote_status_service.rb +++ b/app/services/fetch_remote_status_service.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class FetchRemoteStatusService < BaseService - def call(url, prefetched_body = nil) + def call(url, prefetched_body = nil, announced_by: nil, requested: false) if prefetched_body.nil? resource_url, resource_options = FetchAtomService.new.call(url) else @@ -9,6 +9,9 @@ class FetchRemoteStatusService < BaseService resource_options = { prefetched_body: prefetched_body } end + resource_options[:announced_by] = announced_by unless announced_by.nil? + resource_options[:requested] = true if requested + return if resource_url.blank? ActivityPub::FetchRemoteStatusService.new.call(resource_url, **resource_options) end diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb index 3494dce99..776c4cb9b 100644 --- a/app/services/follow_service.rb +++ b/app/services/follow_service.rb @@ -14,6 +14,8 @@ class FollowService < BaseService raise ActiveRecord::RecordNotFound if target_account.nil? || target_account.id == source_account.id || target_account.suspended? raise Mastodon::NotPermittedError if target_account.blocking?(source_account) || source_account.blocking?(target_account) || target_account.moved? + target_account.mark_known! unless target_account.known? + if source_account.following?(target_account) # We're already following this account, but we'll call follow! again to # make sure the reblogs status is set correctly. diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index bd076eaf4..6377248e5 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -94,6 +94,10 @@ class PostStatusService < BaseService @in_reply_to.present? && @in_reply_to.reject_replies && @in_reply_to.account_id != @account.id end + def mark_recipient_known + @in_reply_to.account.mark_known! unless @in_reply_to.account.known? + end + def set_footer_from_i_am return if @footer.present? || @options[:no_footer] name = @account.user.vars['_they:are'] @@ -153,6 +157,7 @@ class PostStatusService < BaseService limit_visibility_if_silenced unless @in_reply_to.nil? + mark_recipient_known inherit_reply_rejection limit_visibility_to_reply unfilter_thread_on_reply diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb index 7d72357f9..1e7d4f3ca 100644 --- a/app/services/reblog_service.rb +++ b/app/services/reblog_service.rb @@ -17,6 +17,8 @@ class ReblogService < BaseService new_reblog = reblog.nil? if new_reblog + reblogged_status.account.mark_known! unless reblogged_status.account.known? + visibility = options[:visibility] || account.user&.setting_default_privacy visibility = reblogged_status.visibility if reblogged_status.hidden? reblog = account.statuses.create!(reblog: reblogged_status, text: '', visibility: visibility) diff --git a/app/services/resolve_url_service.rb b/app/services/resolve_url_service.rb index 89a31c9ed..0c265b0db 100644 --- a/app/services/resolve_url_service.rb +++ b/app/services/resolve_url_service.rb @@ -21,7 +21,7 @@ class ResolveURLService < BaseService if equals_or_includes_any?(type, %w(Application Group Organization Person Service)) FetchRemoteAccountService.new.call(atom_url, body) elsif equals_or_includes_any?(type, %w(Note Article Image Video Page Question)) - FetchRemoteStatusService.new.call(atom_url, body) + FetchRemoteStatusService.new.call(atom_url, body, requested: true) end end |