From 9edefc779f8e5a5bdedd5a27f6fd815105dd3e92 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 7 Feb 2023 01:14:44 +0100 Subject: Fix `UserCleanupScheduler` crash when an unconfirmed account has a moderation note (#23318) * Fix `UserCleanupScheduler` crash when an unconfirmed account has a moderation note * Add tests --- app/workers/scheduler/user_cleanup_scheduler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/workers') diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb index 63f9ed78c..45cfbc62e 100644 --- a/app/workers/scheduler/user_cleanup_scheduler.rb +++ b/app/workers/scheduler/user_cleanup_scheduler.rb @@ -15,7 +15,7 @@ class Scheduler::UserCleanupScheduler def clean_unconfirmed_accounts! User.where('confirmed_at is NULL AND confirmation_sent_at <= ?', 2.days.ago).reorder(nil).find_in_batches do |batch| # We have to do it separately because of missing database constraints - AccountModerationNote.where(account_id: batch.map(&:account_id)).delete_all + AccountModerationNote.where(target_account_id: batch.map(&:account_id)).delete_all Account.where(id: batch.map(&:account_id)).delete_all User.where(id: batch.map(&:id)).delete_all end -- cgit From ed570050c62115cfbcca8cfcd0de891b729f3e5c Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Mon, 6 Feb 2023 21:44:36 -0500 Subject: Autofix Rails/EagerEvaluationLogMessage (#23429) * Autofix Rails/EagerEvaluationLogMessage * Update spec for debug block syntax --- app/lib/activitypub/activity/create.rb | 2 +- app/lib/link_details_extractor.rb | 2 +- app/models/concerns/remotable.rb | 4 ++-- app/services/activitypub/fetch_featured_collection_service.rb | 2 +- app/services/activitypub/fetch_remote_account_service.rb | 2 +- app/services/activitypub/fetch_remote_actor_service.rb | 2 +- app/services/activitypub/fetch_remote_key_service.rb | 2 +- app/services/activitypub/process_collection_service.rb | 4 ++-- app/services/activitypub/process_status_update_service.rb | 2 +- app/services/fetch_link_card_service.rb | 2 +- app/services/fetch_resource_service.rb | 2 +- app/services/keys/claim_service.rb | 2 +- app/services/keys/query_service.rb | 2 +- app/services/resolve_account_service.rb | 2 +- app/services/verify_link_service.rb | 2 +- app/workers/activitypub/processing_worker.rb | 2 +- spec/models/concerns/remotable_spec.rb | 4 +++- 17 files changed, 21 insertions(+), 19 deletions(-) (limited to 'app/workers') diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index b15e66ca2..cfad62a6b 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -285,7 +285,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity media_attachments rescue Addressable::URI::InvalidURIError => e - Rails.logger.debug "Invalid URL in attachment: #{e}" + Rails.logger.debug { "Invalid URL in attachment: #{e}" } media_attachments end diff --git a/app/lib/link_details_extractor.rb b/app/lib/link_details_extractor.rb index b0c4e4f42..2e0672abe 100644 --- a/app/lib/link_details_extractor.rb +++ b/app/lib/link_details_extractor.rb @@ -248,7 +248,7 @@ class LinkDetailsExtractor structured_data rescue Oj::ParseError, EncodingError - Rails.logger.debug("Invalid JSON-LD in #{@original_url}") + Rails.logger.debug { "Invalid JSON-LD in #{@original_url}" } next end.first end diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index ffe8a7565..cb8f46e68 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -27,11 +27,11 @@ module Remotable public_send("#{attachment_name}=", ResponseWithLimit.new(response, limit)) end rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e - Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" + Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" } public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present? raise e unless suppress_errors rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError, Mastodon::StreamValidationError => e - Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" + Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" } public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present? end diff --git a/app/services/activitypub/fetch_featured_collection_service.rb b/app/services/activitypub/fetch_featured_collection_service.rb index a746ef4d6..1208820df 100644 --- a/app/services/activitypub/fetch_featured_collection_service.rb +++ b/app/services/activitypub/fetch_featured_collection_service.rb @@ -53,7 +53,7 @@ class ActivityPub::FetchFeaturedCollectionService < BaseService status.id rescue ActiveRecord::RecordInvalid => e - Rails.logger.debug "Invalid pinned status #{uri}: #{e.message}" + Rails.logger.debug { "Invalid pinned status #{uri}: #{e.message}" } nil end diff --git a/app/services/activitypub/fetch_remote_account_service.rb b/app/services/activitypub/fetch_remote_account_service.rb index 7aba8269e..567dd8a14 100644 --- a/app/services/activitypub/fetch_remote_account_service.rb +++ b/app/services/activitypub/fetch_remote_account_service.rb @@ -6,7 +6,7 @@ class ActivityPub::FetchRemoteAccountService < ActivityPub::FetchRemoteActorServ actor = super return actor if actor.nil? || actor.is_a?(Account) - Rails.logger.debug "Fetching account #{uri} failed: Expected Account, got #{actor.class.name}" + Rails.logger.debug { "Fetching account #{uri} failed: Expected Account, got #{actor.class.name}" } raise Error, "Expected Account, got #{actor.class.name}" unless suppress_errors end end diff --git a/app/services/activitypub/fetch_remote_actor_service.rb b/app/services/activitypub/fetch_remote_actor_service.rb index 4f60ea5e8..8908d21e2 100644 --- a/app/services/activitypub/fetch_remote_actor_service.rb +++ b/app/services/activitypub/fetch_remote_actor_service.rb @@ -38,7 +38,7 @@ class ActivityPub::FetchRemoteActorService < BaseService ActivityPub::ProcessAccountService.new.call(@username, @domain, @json, only_key: only_key, verified_webfinger: !only_key, request_id: request_id) rescue Error => e - Rails.logger.debug "Fetching actor #{uri} failed: #{e.message}" + Rails.logger.debug { "Fetching actor #{uri} failed: #{e.message}" } raise unless suppress_errors end diff --git a/app/services/activitypub/fetch_remote_key_service.rb b/app/services/activitypub/fetch_remote_key_service.rb index 32e82b47a..8eb97c1e6 100644 --- a/app/services/activitypub/fetch_remote_key_service.rb +++ b/app/services/activitypub/fetch_remote_key_service.rb @@ -38,7 +38,7 @@ class ActivityPub::FetchRemoteKeyService < BaseService find_actor(owner_uri, @owner, suppress_errors) rescue Error => e - Rails.logger.debug "Fetching key #{uri} failed: #{e.message}" + Rails.logger.debug { "Fetching key #{uri} failed: #{e.message}" } raise unless suppress_errors end diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index 8218b8a12..52f48bd49 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -11,7 +11,7 @@ class ActivityPub::ProcessCollectionService < BaseService begin @json = compact(@json) if @json['signature'].is_a?(Hash) rescue JSON::LD::JsonLdError => e - Rails.logger.debug "Error when compacting JSON-LD document for #{value_or_id(@json['actor'])}: #{e.message}" + Rails.logger.debug { "Error when compacting JSON-LD document for #{value_or_id(@json['actor'])}: #{e.message}" } @json = original_json.without('signature') end @@ -72,7 +72,7 @@ class ActivityPub::ProcessCollectionService < BaseService @account = nil unless @account.is_a?(Account) @account rescue JSON::LD::JsonLdError, RDF::WriterError => e - Rails.logger.debug "Could not verify LD-Signature for #{value_or_id(@json['actor'])}: #{e.message}" + Rails.logger.debug { "Could not verify LD-Signature for #{value_or_id(@json['actor'])}: #{e.message}" } nil end end diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index 11b38ab92..1dc393e28 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -94,7 +94,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService @next_media_attachments << media_attachment rescue Addressable::URI::InvalidURIError => e - Rails.logger.debug "Invalid URL in attachment: #{e}" + Rails.logger.debug { "Invalid URL in attachment: #{e}" } end end diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index e5b5b730e..4d55aa5e2 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -30,7 +30,7 @@ class FetchLinkCardService < BaseService attach_card if @card&.persisted? rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e - Rails.logger.debug "Error fetching link #{@original_url}: #{e}" + Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" } nil end diff --git a/app/services/fetch_resource_service.rb b/app/services/fetch_resource_service.rb index 73204e55d..4470fca01 100644 --- a/app/services/fetch_resource_service.rb +++ b/app/services/fetch_resource_service.rb @@ -12,7 +12,7 @@ class FetchResourceService < BaseService process(url) rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e - Rails.logger.debug "Error fetching resource #{@url}: #{e}" + Rails.logger.debug { "Error fetching resource #{@url}: #{e}" } nil end diff --git a/app/services/keys/claim_service.rb b/app/services/keys/claim_service.rb index ae9e24a24..0451c3cb1 100644 --- a/app/services/keys/claim_service.rb +++ b/app/services/keys/claim_service.rb @@ -58,7 +58,7 @@ class Keys::ClaimService < BaseService @result = Result.new(@target_account, @device_id, key_id: json['id'], key: json['publicKeyBase64'], signature: json.dig('signature', 'signatureValue')) rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e - Rails.logger.debug "Claiming one-time key for #{@target_account.acct}:#{@device_id} failed: #{e}" + Rails.logger.debug { "Claiming one-time key for #{@target_account.acct}:#{@device_id} failed: #{e}" } nil end diff --git a/app/services/keys/query_service.rb b/app/services/keys/query_service.rb index ac3388bdc..404854c9f 100644 --- a/app/services/keys/query_service.rb +++ b/app/services/keys/query_service.rb @@ -73,7 +73,7 @@ class Keys::QueryService < BaseService Device.new(device_id: device['id'], name: device['name'], identity_key: device.dig('identityKey', 'publicKeyBase64'), fingerprint_key: device.dig('fingerprintKey', 'publicKeyBase64'), claim_url: device['claim']) end rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e - Rails.logger.debug "Querying devices for #{@account.acct} failed: #{e}" + Rails.logger.debug { "Querying devices for #{@account.acct} failed: #{e}" } nil end end diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb index d8b81a7b9..1ba372cd6 100644 --- a/app/services/resolve_account_service.rb +++ b/app/services/resolve_account_service.rb @@ -54,7 +54,7 @@ class ResolveAccountService < BaseService fetch_account! rescue Webfinger::Error => e - Rails.logger.debug "Webfinger query for #{@uri} failed: #{e}" + Rails.logger.debug { "Webfinger query for #{@uri} failed: #{e}" } raise unless @options[:suppress_errors] end diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb index 9708cdd73..f83a664d4 100644 --- a/app/services/verify_link_service.rb +++ b/app/services/verify_link_service.rb @@ -11,7 +11,7 @@ class VerifyLinkService < BaseService field.mark_verified! rescue OpenSSL::SSL::SSLError, HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, IPAddr::AddressFamilyError => e - Rails.logger.debug "Error fetching link #{@url}: #{e}" + Rails.logger.debug { "Error fetching link #{@url}: #{e}" } nil end diff --git a/app/workers/activitypub/processing_worker.rb b/app/workers/activitypub/processing_worker.rb index 5e36fab51..1bb94b7f2 100644 --- a/app/workers/activitypub/processing_worker.rb +++ b/app/workers/activitypub/processing_worker.rb @@ -15,6 +15,6 @@ class ActivityPub::ProcessingWorker ActivityPub::ProcessCollectionService.new.call(body, actor, override_timestamps: true, delivered_to_account_id: delivered_to_account_id, delivery: true) rescue ActiveRecord::RecordInvalid => e - Rails.logger.debug "Error processing incoming ActivityPub object: #{e}" + Rails.logger.debug { "Error processing incoming ActivityPub object: #{e}" } end end diff --git a/spec/models/concerns/remotable_spec.rb b/spec/models/concerns/remotable_spec.rb index 9cc849ded..ca2d65d2d 100644 --- a/spec/models/concerns/remotable_spec.rb +++ b/spec/models/concerns/remotable_spec.rb @@ -194,7 +194,9 @@ RSpec.describe Remotable do let(:error_class) { error_class } it 'calls Rails.logger.debug' do - expect(Rails.logger).to receive(:debug).with(/^Error fetching remote #{hoge}: /) + expect(Rails.logger).to receive(:debug) do |&block| + expect(block.call).to match(/^Error fetching remote #{hoge}: /) + end foo.hoge_remote_url = url end end -- cgit From cec005068f25c6487331a8437e69f29d5bef3d60 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 7 Feb 2023 18:58:18 -0500 Subject: Apply Rubocop Performance/RedundantBlockCall (#23440) --- app/models/trends/history.rb | 2 +- app/workers/import/relationship_worker.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app/workers') diff --git a/app/models/trends/history.rb b/app/models/trends/history.rb index 74723e35c..03d62103f 100644 --- a/app/models/trends/history.rb +++ b/app/models/trends/history.rb @@ -88,7 +88,7 @@ class Trends::History def each(&block) if block_given? - (0...7).map { |i| block.call(get(i.days.ago)) } + (0...7).map { |i| yield(get(i.days.ago)) } else to_enum(:each) end diff --git a/app/workers/import/relationship_worker.rb b/app/workers/import/relationship_worker.rb index 6791b15c3..c2728c196 100644 --- a/app/workers/import/relationship_worker.rb +++ b/app/workers/import/relationship_worker.rb @@ -49,7 +49,7 @@ class Import::RelationshipWorker .with_error_handler { |error, handle| error.is_a?(HTTP::Error) || error.is_a?(OpenSSL::SSL::SSLError) ? handle.call(error) : raise(error) } .run else - block.call + yield end end end -- cgit From 0c9eac80d887cdf7f1efa582b21006248d2f83eb Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 10 Feb 2023 22:16:37 +0100 Subject: Fix unbounded recursion in post discovery (#23506) * Add a limit to how many posts can get fetched as a result of a single request * Add tests * Always pass `request_id` when processing `Announce` activities --------- Co-authored-by: nametoolong --- app/lib/activitypub/activity.rb | 7 +- app/lib/activitypub/activity/create.rb | 6 +- .../activitypub/fetch_remote_status_service.rb | 13 ++- app/services/activitypub/fetch_replies_service.rb | 4 +- app/services/fetch_remote_status_service.rb | 4 +- app/services/resolve_url_service.rb | 2 +- app/workers/activitypub/fetch_replies_worker.rb | 4 +- app/workers/fetch_reply_worker.rb | 4 +- app/workers/thread_resolve_worker.rb | 4 +- spec/lib/activitypub/activity/add_spec.rb | 4 +- .../fetch_remote_status_service_spec.rb | 94 ++++++++++++++++++++++ spec/services/fetch_remote_status_service_spec.rb | 2 +- 12 files changed, 126 insertions(+), 22 deletions(-) (limited to 'app/workers') diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index f4c67cccd..900428e92 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -106,7 +106,8 @@ class ActivityPub::Activity actor_id = value_or_id(first_of_value(@object['attributedTo'])) if actor_id == @account.uri - return ActivityPub::Activity.factory({ 'type' => 'Create', 'actor' => actor_id, 'object' => @object }, @account).perform + virtual_object = { 'type' => 'Create', 'actor' => actor_id, 'object' => @object } + return ActivityPub::Activity.factory(virtual_object, @account, request_id: @options[:request_id]).perform end end @@ -152,9 +153,9 @@ class ActivityPub::Activity def fetch_remote_original_status if object_uri.start_with?('http') return if ActivityPub::TagManager.instance.local_uri?(object_uri) - ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true, on_behalf_of: @account.followers.local.first) + ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true, on_behalf_of: @account.followers.local.first, request_id: @options[:request_id]) elsif @object['url'].present? - ::FetchRemoteStatusService.new.call(@object['url']) + ::FetchRemoteStatusService.new.call(@object['url'], request_id: @options[:request_id]) end end diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index cfad62a6b..487b65223 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -327,18 +327,18 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def resolve_thread(status) return unless status.reply? && status.thread.nil? && Request.valid_url?(in_reply_to_uri) - ThreadResolveWorker.perform_async(status.id, in_reply_to_uri) + ThreadResolveWorker.perform_async(status.id, in_reply_to_uri, { 'request_id' => @options[:request_id]}) end def fetch_replies(status) collection = @object['replies'] return if collection.nil? - replies = ActivityPub::FetchRepliesService.new.call(status, collection, false) + replies = ActivityPub::FetchRepliesService.new.call(status, collection, allow_synchronous_requests: false, request_id: @options[:request_id]) return unless replies.nil? uri = value_or_id(collection) - ActivityPub::FetchRepliesWorker.perform_async(status.id, uri) unless uri.nil? + ActivityPub::FetchRepliesWorker.perform_async(status.id, uri, { 'request_id' => @options[:request_id]}) unless uri.nil? end def conversation_from_uri(uri) diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb index 21b9242f8..936737bf6 100644 --- a/app/services/activitypub/fetch_remote_status_service.rb +++ b/app/services/activitypub/fetch_remote_status_service.rb @@ -2,10 +2,13 @@ class ActivityPub::FetchRemoteStatusService < BaseService include JsonLdHelper + include Redisable + + DISCOVERIES_PER_REQUEST = 1000 # Should be called when uri has already been checked for locality def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil, expected_actor_uri: nil, request_id: nil) - @request_id = request_id + @request_id = request_id || "#{Time.now.utc.to_i}-status-#{uri}" @json = begin if prefetched_body.nil? fetch_resource(uri, id, on_behalf_of) @@ -42,7 +45,13 @@ class ActivityPub::FetchRemoteStatusService < BaseService # activity as an update rather than create activity_json['type'] = 'Update' if equals_or_includes_any?(activity_json['type'], %w(Create)) && Status.where(uri: object_uri, account_id: actor.id).exists? - ActivityPub::Activity.factory(activity_json, actor, request_id: request_id).perform + with_redis do |redis| + discoveries = redis.incr("status_discovery_per_request:#{@request_id}") + redis.expire("status_discovery_per_request:#{@request_id}", 5.minutes.seconds) + return nil if discoveries > DISCOVERIES_PER_REQUEST + end + + ActivityPub::Activity.factory(activity_json, actor, request_id: @request_id).perform end private diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb index 8cb309e52..18a27e851 100644 --- a/app/services/activitypub/fetch_replies_service.rb +++ b/app/services/activitypub/fetch_replies_service.rb @@ -3,14 +3,14 @@ class ActivityPub::FetchRepliesService < BaseService include JsonLdHelper - def call(parent_status, collection_or_uri, allow_synchronous_requests = true) + def call(parent_status, collection_or_uri, allow_synchronous_requests: true, request_id: nil) @account = parent_status.account @allow_synchronous_requests = allow_synchronous_requests @items = collection_items(collection_or_uri) return if @items.nil? - FetchReplyWorker.push_bulk(filtered_replies) + FetchReplyWorker.push_bulk(filtered_replies) { |reply_uri| [reply_uri, { 'request_id' => request_id}] } @items end diff --git a/app/services/fetch_remote_status_service.rb b/app/services/fetch_remote_status_service.rb index eafde4d4a..08c2d24ba 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, request_id: nil) if prefetched_body.nil? resource_url, resource_options = FetchResourceService.new.call(url) else @@ -9,6 +9,6 @@ class FetchRemoteStatusService < BaseService resource_options = { prefetched_body: prefetched_body } end - ActivityPub::FetchRemoteStatusService.new.call(resource_url, **resource_options) unless resource_url.nil? + ActivityPub::FetchRemoteStatusService.new.call(resource_url, **resource_options.merge(request_id: request_id)) unless resource_url.nil? end end diff --git a/app/services/resolve_url_service.rb b/app/services/resolve_url_service.rb index 52f35daf3..d8e795f3b 100644 --- a/app/services/resolve_url_service.rb +++ b/app/services/resolve_url_service.rb @@ -25,7 +25,7 @@ class ResolveURLService < BaseService if equals_or_includes_any?(type, ActivityPub::FetchRemoteActorService::SUPPORTED_TYPES) ActivityPub::FetchRemoteActorService.new.call(resource_url, prefetched_body: body) elsif equals_or_includes_any?(type, ActivityPub::Activity::Create::SUPPORTED_TYPES + ActivityPub::Activity::Create::CONVERTED_TYPES) - status = FetchRemoteStatusService.new.call(resource_url, body) + status = FetchRemoteStatusService.new.call(resource_url, prefetched_body: body) authorize_with @on_behalf_of, status, :show? unless status.nil? status end diff --git a/app/workers/activitypub/fetch_replies_worker.rb b/app/workers/activitypub/fetch_replies_worker.rb index 54d98f228..d72bad745 100644 --- a/app/workers/activitypub/fetch_replies_worker.rb +++ b/app/workers/activitypub/fetch_replies_worker.rb @@ -6,8 +6,8 @@ class ActivityPub::FetchRepliesWorker sidekiq_options queue: 'pull', retry: 3 - def perform(parent_status_id, replies_uri) - ActivityPub::FetchRepliesService.new.call(Status.find(parent_status_id), replies_uri) + def perform(parent_status_id, replies_uri, options = {}) + ActivityPub::FetchRepliesService.new.call(Status.find(parent_status_id), replies_uri, **options.deep_symbolize_keys) rescue ActiveRecord::RecordNotFound true end diff --git a/app/workers/fetch_reply_worker.rb b/app/workers/fetch_reply_worker.rb index f7aa25e81..68a7414be 100644 --- a/app/workers/fetch_reply_worker.rb +++ b/app/workers/fetch_reply_worker.rb @@ -6,7 +6,7 @@ class FetchReplyWorker sidekiq_options queue: 'pull', retry: 3 - def perform(child_url) - FetchRemoteStatusService.new.call(child_url) + def perform(child_url, options = {}) + FetchRemoteStatusService.new.call(child_url, **options.deep_symbolize_keys) end end diff --git a/app/workers/thread_resolve_worker.rb b/app/workers/thread_resolve_worker.rb index 1b77dfdd9..3206c45f6 100644 --- a/app/workers/thread_resolve_worker.rb +++ b/app/workers/thread_resolve_worker.rb @@ -6,9 +6,9 @@ class ThreadResolveWorker sidekiq_options queue: 'pull', retry: 3 - def perform(child_status_id, parent_url) + def perform(child_status_id, parent_url, options = {}) child_status = Status.find(child_status_id) - parent_status = FetchRemoteStatusService.new.call(parent_url) + parent_status = FetchRemoteStatusService.new.call(parent_url, **options.deep_symbolize_keys) return if parent_status.nil? diff --git a/spec/lib/activitypub/activity/add_spec.rb b/spec/lib/activitypub/activity/add_spec.rb index e6408b610..0b08e2924 100644 --- a/spec/lib/activitypub/activity/add_spec.rb +++ b/spec/lib/activitypub/activity/add_spec.rb @@ -48,7 +48,7 @@ RSpec.describe ActivityPub::Activity::Add do end it 'fetches the status and pins it' do - allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil| + allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil, request_id: nil| expect(uri).to eq 'https://example.com/unknown' expect(id).to eq true expect(on_behalf_of&.following?(sender)).to eq true @@ -62,7 +62,7 @@ RSpec.describe ActivityPub::Activity::Add do context 'when there is no local follower' do it 'tries to fetch the status' do - allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil| + allow(service_stub).to receive(:call) do |uri, id: true, on_behalf_of: nil, request_id: nil| expect(uri).to eq 'https://example.com/unknown' expect(id).to eq true expect(on_behalf_of).to eq nil diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index 7359ca0b4..a81dcad81 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -223,4 +223,98 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do end end end + + context 'statuses referencing other statuses' do + before do + stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 5 + end + + context 'using inReplyTo' do + let(:object) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/1", + type: 'Note', + content: 'Lorem ipsum', + inReplyTo: 'https://foo.bar/@foo/2', + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + } + end + + before do + 8.times do |i| + status_json = { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/#{i}", + type: 'Note', + content: 'Lorem ipsum', + inReplyTo: "https://foo.bar/@foo/#{i + 1}", + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + to: 'as:Public', + }.with_indifferent_access + stub_request(:get, "https://foo.bar/@foo/#{i}").to_return(status: 200, body: status_json.to_json, headers: { 'Content-Type': 'application/activity+json' }) + end + end + + it 'creates at least some statuses' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_least(2) + end + + it 'creates no more account than the limit allows' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_most(5) + end + end + + context 'using replies' do + let(:object) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/1", + type: 'Note', + content: 'Lorem ipsum', + replies: { + type: 'Collection', + id: 'https://foo.bar/@foo/1/replies', + first: { + type: 'CollectionPage', + partOf: 'https://foo.bar/@foo/1/replies', + items: ['https://foo.bar/@foo/2'], + }, + }, + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + } + end + + before do + 8.times do |i| + status_json = { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/#{i}", + type: 'Note', + content: 'Lorem ipsum', + replies: { + type: 'Collection', + id: "https://foo.bar/@foo/#{i}/replies", + first: { + type: 'CollectionPage', + partOf: "https://foo.bar/@foo/#{i}/replies", + items: ["https://foo.bar/@foo/#{i+1}"], + }, + }, + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + to: 'as:Public', + }.with_indifferent_access + stub_request(:get, "https://foo.bar/@foo/#{i}").to_return(status: 200, body: status_json.to_json, headers: { 'Content-Type': 'application/activity+json' }) + end + end + + it 'creates at least some statuses' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_least(2) + end + + it 'creates no more account than the limit allows' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_most(5) + end + end + end end diff --git a/spec/services/fetch_remote_status_service_spec.rb b/spec/services/fetch_remote_status_service_spec.rb index fe5f1aed1..4f6ad6496 100644 --- a/spec/services/fetch_remote_status_service_spec.rb +++ b/spec/services/fetch_remote_status_service_spec.rb @@ -15,7 +15,7 @@ RSpec.describe FetchRemoteStatusService, type: :service do end context 'protocol is :activitypub' do - subject { described_class.new.call(note[:id], prefetched_body) } + subject { described_class.new.call(note[:id], prefetched_body: prefetched_body) } let(:prefetched_body) { Oj.dump(note) } before do -- cgit