From cfe8a3218addfd7e0cc82c6f0054572f3d8aa296 Mon Sep 17 00:00:00 2001 From: Fire Demon Date: Wed, 18 Nov 2020 21:03:32 -0600 Subject: Break up AP envelope addressing by domain --- app/controllers/activitypub/outboxes_controller.rb | 2 +- app/controllers/statuses_controller.rb | 6 +++--- app/controllers/tags_controller.rb | 2 +- app/lib/activitypub/tag_manager.rb | 12 ++++++------ app/presenters/activitypub/activity_presenter.rb | 6 +++--- app/serializers/activitypub/note_serializer.rb | 4 ++-- app/serializers/activitypub/outbox_serializer.rb | 2 +- app/serializers/activitypub/undo_announce_serializer.rb | 2 +- app/serializers/activitypub/update_poll_serializer.rb | 4 ++-- app/services/backup_service.rb | 2 +- app/services/process_mentions_service.rb | 2 +- app/services/reblog_service.rb | 2 +- app/services/remove_status_service.rb | 15 +++++++++------ app/workers/activitypub/distribution_worker.rb | 9 +++++---- app/workers/activitypub/reply_distribution_worker.rb | 7 ++++--- 15 files changed, 41 insertions(+), 36 deletions(-) diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb index 7c914298b..1a879c379 100644 --- a/app/controllers/activitypub/outboxes_controller.rb +++ b/app/controllers/activitypub/outboxes_controller.rb @@ -15,7 +15,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController def show expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode? && !(current_account.present? && page_requested?)) - render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', target_domain: current_account&.domain + render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', domain: current_account&.domain end private diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 6f8e74414..596ce9b84 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -39,18 +39,18 @@ class StatusesController < ApplicationController format.json do expires_in 3.minutes, public: @status.distributable? && public_fetch_mode? - render_with_cache json: @status, content_type: 'application/activity+json', serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter, target_domain: current_account&.domain + render_with_cache json: @status, content_type: 'application/activity+json', serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter, domain: current_account&.domain end end end def activity expires_in 3.minutes, public: @status.distributable? && public_fetch_mode? - render_with_cache json: ActivityPub::ActivityPresenter.from_status(@status), + render_with_cache json: ActivityPub::ActivityPresenter.from_status(@status, current_account&.domain), content_type: 'application/activity+json', serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter, - target_domain: current_account&.domain + domain: current_account&.domain end def embed diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index d8b6019f5..1f703085f 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -32,7 +32,7 @@ class TagsController < ApplicationController format.json do expires_in 3.minutes, public: public_fetch_mode? - render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', target_domain: current_account&.domain + render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', domain: current_account&.domain end end end diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index fb1c9d7b2..383f182d2 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -64,8 +64,8 @@ class ActivityPub::TagManager # Public statuses go out to primarily the public collection # Unlisted and private statuses go out primarily to the followers collection # Others go out only to the people they mention - def to(status, target_domain: nil) - visibility = status.visibility_for_domain(target_domain) + def to(status, domain) + visibility = status.visibility_for_domain(domain) case visibility when 'public', 'unlisted' [status.tags.present? ? COLLECTIONS[:public] : account_followers_url(status.account)] @@ -74,7 +74,7 @@ class ActivityPub::TagManager account_ids |= status.account.follower_ids if visibility == 'private' accounts = status.account.silenced? ? status.account.followers.where(id: account_ids) : Account.where(id: account_ids) - accounts = accounts.where(domain: target_domain) if target_domain.present? + accounts = accounts.where(domain: domain) if domain.present? accounts.each_with_object([]) do |account, result| result << uri_for(account) @@ -88,11 +88,11 @@ class ActivityPub::TagManager # Unlisted statuses go to the public as well # Both of those and private statuses also go to the people mentioned in them # Direct ones don't have a secondary audience - def cc(status, target_domain: nil) + def cc(status, domain) cc = [] cc << uri_for(status.reblog.account) if status.reblog? - visibility = status.visibility_for_domain(target_domain) + visibility = status.visibility_for_domain(domain) case visibility when 'public', 'unlisted' @@ -108,7 +108,7 @@ class ActivityPub::TagManager if account_ids.present? accounts = status.account.silenced? ? status.account.followers.where(id: account_ids) : Account.where(id: account_ids) - accounts = accounts.where(domain: target_domain) if target_domain.present? + accounts = accounts.where(domain: domain) if domain.present? cc.concat(accounts.each_with_object([]) do |account, result| result << uri_for(account) diff --git a/app/presenters/activitypub/activity_presenter.rb b/app/presenters/activitypub/activity_presenter.rb index 7a19cc96a..88aed1e4e 100644 --- a/app/presenters/activitypub/activity_presenter.rb +++ b/app/presenters/activitypub/activity_presenter.rb @@ -4,15 +4,15 @@ class ActivityPub::ActivityPresenter < ActiveModelSerializers::Model attributes :id, :type, :actor, :published, :to, :cc, :virtual_object class << self - def from_status(status, update: false, embed: true) + def from_status(status, domain, update: false, embed: true) new.tap do |presenter| default_activity = update && status.edited.positive? ? 'Update' : 'Create' presenter.id = ActivityPub::TagManager.instance.activity_uri_for(status) presenter.type = (status.reblog? && status.spoiler_text.blank? ? 'Announce' : default_activity) presenter.actor = ActivityPub::TagManager.instance.uri_for(status.account) presenter.published = status.created_at - presenter.to = ActivityPub::TagManager.instance.to(status) - presenter.cc = ActivityPub::TagManager.instance.cc(status) + presenter.to = ActivityPub::TagManager.instance.to(status, domain) + presenter.cc = ActivityPub::TagManager.instance.cc(status, domain) unless embed || !status.account.require_dereference presenter.virtual_object = ActivityPub::TagManager.instance.uri_for(status.proper) diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index 0d3fe715d..29fec7e03 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -126,11 +126,11 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer end def to - ActivityPub::TagManager.instance.to(object, target_domain: instance_options[:target_domain]) + ActivityPub::TagManager.instance.to(object, instance_options[:domain]) end def cc - ActivityPub::TagManager.instance.cc(object, target_domain: instance_options[:target_domain]) + ActivityPub::TagManager.instance.cc(object, instance_options[:domain]) end def sensitive diff --git a/app/serializers/activitypub/outbox_serializer.rb b/app/serializers/activitypub/outbox_serializer.rb index 2692a1c42..d1708cc36 100644 --- a/app/serializers/activitypub/outbox_serializer.rb +++ b/app/serializers/activitypub/outbox_serializer.rb @@ -10,6 +10,6 @@ class ActivityPub::OutboxSerializer < ActivityPub::CollectionSerializer end def items - object.items.map { |status| ActivityPub::ActivityPresenter.from_status(status, embed: false) } + object.items.map { |status| ActivityPub::ActivityPresenter.from_status(status, instance_options[:domain], embed: false) } end end diff --git a/app/serializers/activitypub/undo_announce_serializer.rb b/app/serializers/activitypub/undo_announce_serializer.rb index a464517ca..d48fcff73 100644 --- a/app/serializers/activitypub/undo_announce_serializer.rb +++ b/app/serializers/activitypub/undo_announce_serializer.rb @@ -22,6 +22,6 @@ class ActivityPub::UndoAnnounceSerializer < ActivityPub::Serializer end def virtual_object - ActivityPub::ActivityPresenter.from_status(object, embed: false) + ActivityPub::ActivityPresenter.from_status(object, instance_options[:domain], embed: false) end end diff --git a/app/serializers/activitypub/update_poll_serializer.rb b/app/serializers/activitypub/update_poll_serializer.rb index 1d47b9764..a3ac028ec 100644 --- a/app/serializers/activitypub/update_poll_serializer.rb +++ b/app/serializers/activitypub/update_poll_serializer.rb @@ -18,10 +18,10 @@ class ActivityPub::UpdatePollSerializer < ActivityPub::Serializer end def to - ActivityPub::TagManager.instance.to(object) + ActivityPub::TagManager.instance.to(object, instance_options[:domain]) end def cc - ActivityPub::TagManager.instance.cc(object) + ActivityPub::TagManager.instance.cc(object, instance_options[:domain]) end end diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb index 749c84736..b83c08a98 100644 --- a/app/services/backup_service.rb +++ b/app/services/backup_service.rb @@ -22,7 +22,7 @@ class BackupService < BaseService account.statuses.with_includes.reorder(nil).find_in_batches do |statuses| statuses.each do |status| - item = serialize_payload(ActivityPub::ActivityPresenter.from_status(status), ActivityPub::ActivitySerializer, signer: @account, allow_local_only: true) + item = serialize_payload(ActivityPub::ActivityPresenter.from_status(status, nil), ActivityPub::ActivitySerializer, signer: @account, allow_local_only: true) item.delete(:'@context') unless item[:type] == 'Announce' || item[:object][:attachment].blank? diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index 56cfbdccd..51c368264 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -37,7 +37,7 @@ class ProcessMentionsService < BaseService end def activitypub_json(domain) - @activitypub_json[domain] ||= Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(@status, embed: false), ActivityPub::ActivitySerializer, signer: @status.account, target_domain: domain)) + @activitypub_json[domain] ||= Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(@status, domain, embed: false), ActivityPub::ActivitySerializer, signer: @status.account, domain: domain)) end def check_for_spam(status) diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb index 3188bbb69..93b0c160b 100644 --- a/app/services/reblog_service.rb +++ b/app/services/reblog_service.rb @@ -61,7 +61,7 @@ class ReblogService < BaseService end def build_json(reblog) - Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(reblog, embed: false), ActivityPub::ActivitySerializer, signer: reblog.account, target_domain: reblog.account.domain)) + Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(reblog, reblog.account.domain, embed: false), ActivityPub::ActivitySerializer, signer: reblog.account, domain: reblog.account.domain)) end def curate!(status) diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index 8025f235b..beb415f94 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -19,6 +19,8 @@ class RemoveStatusService < BaseService @reblogs = status.reblogs.includes(:account).to_a @options = options + @signed_activity_json = {} + RedisLock.acquire(lock_options) do |lock| if lock.acquired? remove_from_self if status.account.local? && !@options[:unpublish] @@ -95,18 +97,18 @@ class RemoveStatusService < BaseService # ActivityPub ActivityPub::DeliveryWorker.push_bulk(target_accounts.select(&:activitypub?).uniq(&:preferred_inbox_url)) do |target_account| - [signed_activity_json, @account.id, target_account.preferred_inbox_url] + [signed_activity_json(inbox_url), @account.id, target_account.preferred_inbox_url] end end def remove_from_remote_followers # ActivityPub ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url| - [signed_activity_json, @account.id, inbox_url] + [signed_activity_json(inbox_url), @account.id, inbox_url] end ActivityPub::DeliveryWorker.push_bulk(@account.following.inboxes) do |inbox_url| - [signed_activity_json, @account.id, inbox_url] + [signed_activity_json(inbox_url), @account.id, inbox_url] end relay! if relayable? @@ -118,12 +120,13 @@ class RemoveStatusService < BaseService def relay! ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url| - [signed_activity_json(Addressable::URI.parse(inbox_url).host), @account.id, inbox_url] + [signed_activity_json(inbox_url), @account.id, inbox_url] end end - def signed_activity_json - @signed_activity_json ||= Oj.dump(serialize_payload(@status, @status.reblog? && @status.spoiler_text.blank? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer, signer: @account)) + def signed_activity_json(inbox_url) + domain = Addressable::URI.parse(inbox_url).normalized_host + @signed_activity_json[domain] ||= Oj.dump(serialize_payload(@status, @status.reblog? && @status.spoiler_text.blank? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer, signer: @account, domain: domain)) end def remove_reblogs diff --git a/app/workers/activitypub/distribution_worker.rb b/app/workers/activitypub/distribution_worker.rb index 1602c3e24..948393c12 100644 --- a/app/workers/activitypub/distribution_worker.rb +++ b/app/workers/activitypub/distribution_worker.rb @@ -15,7 +15,7 @@ class ActivityPub::DistributionWorker return if skip_distribution? ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url| - [payload(Addressable::URI.parse(inbox_url).host), @account.id, inbox_url, { synchronize_followers: !@status.distributable? }] + [payload(inbox_url), @account.id, inbox_url, { synchronize_followers: !@status.distributable? }] end relay! if relayable? @@ -46,13 +46,14 @@ class ActivityPub::DistributionWorker end end - def payload(domain) - @payload[domain] ||= Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(@status, update: true, embed: false), ActivityPub::ActivitySerializer, signer: @account, target_domain: domain)) + def payload(inbox_url) + domain = Addressable::URI.parse(inbox_url).normalized_host + @payload[domain] ||= Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(@status, domain, update: true, embed: false), ActivityPub::ActivitySerializer, signer: @account, domain: domain)) end def relay! ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url| - [payload(Addressable::URI.parse(inbox_url).host), @account.id, inbox_url] + [payload(inbox_url), @account.id, inbox_url] end end end diff --git a/app/workers/activitypub/reply_distribution_worker.rb b/app/workers/activitypub/reply_distribution_worker.rb index f9044cbf3..6b807e8bc 100644 --- a/app/workers/activitypub/reply_distribution_worker.rb +++ b/app/workers/activitypub/reply_distribution_worker.rb @@ -18,7 +18,7 @@ class ActivityPub::ReplyDistributionWorker return unless @account.present? && @status.distributable? ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url| - [payload(Addressable::URI.parse(inbox_url).host), @status.account_id, inbox_url] + [payload(inbox_url), @status.account_id, inbox_url] end rescue ActiveRecord::RecordNotFound true @@ -30,7 +30,8 @@ class ActivityPub::ReplyDistributionWorker @inboxes ||= (@options[:all_servers] || @account.id == -99 ? Account.remote.without_suspended.inboxes : @account.followers.inboxes) end - def payload(domain) - @payload[domain] ||= Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(@status, update: true, embed: false), ActivityPub::ActivitySerializer, signer: @status.account, target_domain: domain)) + def payload(inbox_url) + domain = Addressable::URI.parse(inbox_url).normalized_host + @payload[domain] ||= Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(@status, domain, update: true, embed: false), ActivityPub::ActivitySerializer, signer: @status.account, domain: domain)) end end -- cgit