1
0
Fork 0
forked from gitea/nas

Change: #375 投稿を編集して拡張ドメインブロックの条件にひっかかる状態になった場合、対象サーバーには投稿削除のActivityを送信する (#495)

* Change: #375 投稿を編集して拡張ドメインブロックの条件にひっかかる状態になった場合、対象サーバーには投稿削除のActivityを送信する

* Fix test

* Add test
This commit is contained in:
KMY(雪あすか) 2024-01-24 09:03:24 +09:00 committed by GitHub
parent e4375143ca
commit fcd13a6474
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 146 additions and 12 deletions

View file

@ -31,6 +31,10 @@ class StatusReachFinder
)
end
def inboxes_diff_for_sending_domain_block
(reached_account_inboxes_for_sending_domain_block + followers_inboxes_for_sending_domain_block).uniq
end
def all_inboxes
(inboxes + inboxes_for_misskey + inboxes_for_friend).uniq
end
@ -58,6 +62,14 @@ class StatusReachFinder
end
end
def reached_account_inboxes_for_sending_domain_block
if @status.reblog? || @status.limited_visibility?
[]
else
Account.where(id: reached_account_ids, domain: banned_domains_of_status(@status)).inboxes
end
end
def reached_account_ids
# When the status is a reblog, there are no interactions with it
# directly, we assume all interactions are with the original one
@ -144,6 +156,10 @@ class StatusReachFinder
end
end
def followers_inboxes_for_sending_domain_block
@status.account.followers.where(domain: banned_domains_of_status(@status)).inboxes
end
def relay_inboxes
if @status.public_visibility?
Relay.enabled.pluck(:inbox_url)
@ -192,9 +208,15 @@ class StatusReachFinder
end
def banned_domains_of_status(status)
return [] unless status.sending_sensitive?
return @banned_domains_of_status if defined?(@banned_domains_of_status) && status.id == @status.id
blocks = DomainBlock.where(domain: nil)
blocks = blocks.or(DomainBlock.where(reject_send_sensitive: true)) if (status.with_media? && status.sensitive) || status.spoiler_text?
blocks.pluck(:domain).uniq
blocks = blocks.or(DomainBlock.where(reject_send_sensitive: true)) if status.sending_sensitive?
domains = blocks.pluck(:domain).uniq
@banned_domains_of_status = domains if status.id == @status.id
domains
end
def banned_domains_for_misskey

View file

@ -6,7 +6,7 @@ module Status::DomainBlockConcern
def sending_sensitive?
return false unless local?
(with_media? && sensitive) || spoiler_text?
sensitive
end
def sending_maybe_compromised_privacy?

View file

@ -68,11 +68,7 @@ class PostStatusService < BaseService
private
def preprocess_attributes!
@sensitive = (if @options[:sensitive].nil?
@media.any? ? @account.user&.setting_default_sensitive : false
else
@options[:sensitive]
end) || @options[:spoiler_text].present?
@sensitive = (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?
@text = @options.delete(:spoiler_text) if @text.blank? && @options[:spoiler_text].present?
@visibility = @options[:visibility]&.to_sym || @account.user&.setting_default_privacy&.to_sym
@visibility = :limited if %w(mutual circle reply).include?(@options[:visibility])

View file

@ -24,6 +24,7 @@ class UpdateStatusService < BaseService
@account_id = account_id
@media_attachments_changed = false
@poll_changed = false
@old_sensitive = sensitive?
clear_histories! if @options[:no_history]
@ -189,7 +190,7 @@ class UpdateStatusService < BaseService
def broadcast_updates!
DistributionWorker.perform_async(@status.id, { 'update' => true })
ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id)
ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id, { 'sensitive' => sensitive?, 'sensitive_changed' => @old_sensitive != sensitive? && sensitive? })
end
def queue_poll_notifications!
@ -227,4 +228,8 @@ class UpdateStatusService < BaseService
@status.edited_at = nil
@status.save!
end
def sensitive?
@status.sensitive
end
end

View file

@ -12,6 +12,7 @@ class ActivityPub::StatusUpdateDistributionWorker < ActivityPub::DistributionWor
distribute_limited!
else
distribute!
distribute_delete_activity!
end
rescue ActiveRecord::RecordNotFound
true
@ -19,6 +20,17 @@ class ActivityPub::StatusUpdateDistributionWorker < ActivityPub::DistributionWor
protected
def inboxes
return super if @status.limited_visibility?
return super unless sensitive?
super - inboxes_diff_for_sending_domain_block
end
def inboxes_diff_for_sending_domain_block
status_reach_finder.inboxes_diff_for_sending_domain_block
end
def inboxes_for_limited
@inboxes_for_limited ||= @status.mentioned_accounts.inboxes
end
@ -47,7 +59,30 @@ class ActivityPub::StatusUpdateDistributionWorker < ActivityPub::DistributionWor
build_activity(for_friend: true)
end
def delete_activity
@delete_activity ||= Oj.dump(serialize_payload(@status, ActivityPub::DeleteSerializer, signer: @account))
end
def distribute_delete_activity!
return unless sensitive_changed?
target_inboxes = inboxes_diff_for_sending_domain_block
return if target_inboxes.empty?
ActivityPub::DeliveryWorker.push_bulk(target_inboxes, limit: 1_000) do |inbox_url|
[delete_activity, @account.id, inbox_url, {}]
end
end
def always_sign
@status.limited_visibility?
end
def sensitive?
@options[:sensitive]
end
def sensitive_changed?
@options[:sensitive_changed]
end
end