Change: #538 NGワード「フォローしていないアカウントへのメンションで利用できないキーワード」を、参照投稿にも適用する (#544)

* Change: #538 NGワード「フォローしていないアカウントへのメンションで利用できないキーワード」を、参照投稿にも適用する

* Update create.rb

* Update create.rb

* Update create.rb

* Fix test
This commit is contained in:
KMY(雪あすか) 2024-02-16 18:19:14 +09:00 committed by GitHub
parent 5c543c602b
commit 76b5d4f2c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 265 additions and 41 deletions

View file

@ -3,8 +3,8 @@
class ActivityPub::FetchReferencesService < BaseService
include JsonLdHelper
def call(status, collection_or_uri)
@account = status.account
def call(account, collection_or_uri)
@account = account
collection_items(collection_or_uri)&.take(8)&.map { |item| value_or_id(item) }
end

View file

@ -165,12 +165,16 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
end
def validate_status_mentions!
raise AbortError if mention_to_stranger? && Admin::NgWord.stranger_mention_reject?("#{@status.spoiler_text}\n#{@status.text}", uri: @status.uri, target_type: :status)
raise AbortError if (mention_to_stranger? || reference_to_stranger?) && Admin::NgWord.stranger_mention_reject?("#{@status.spoiler_text}\n#{@status.text}", uri: @status.uri, target_type: :status)
end
def mention_to_stranger?
@status.mentions.map(&:account).to_a.any? { |mentioned_account| mentioned_account.id != @status.account.id && !mentioned_account.following?(@status.account) } ||
(@status.thread.present? && @status.thread.account.id != @status.account.id && !@status.thread.account.following?(@status.account))
@status.mentions.map(&:account).to_a.any? { |mentioned_account| mentioned_account.id != @status.account.id && mentioned_account.local? && !mentioned_account.following?(@status.account) } ||
(@status.thread.present? && @status.thread.account.id != @status.account.id && @status.thread.account.local? && !@status.thread.account.following?(@status.account))
end
def reference_to_stranger?
local_referred_accounts.any? { |account| !account.following?(@account) }
end
def update_immediate_attributes!
@ -271,12 +275,32 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
end
def update_references!
references = @json['references'].nil? ? [] : ActivityPub::FetchReferencesService.new.call(@status, @json['references'])
quote = @json['quote'] || @json['quoteUrl'] || @json['quoteURL'] || @json['_misskey_quote']
references = reference_uris
ProcessReferencesService.call_service_without_error(@status, [], references, [quote].compact)
end
def reference_uris
return @reference_uris if defined?(@reference_uris)
@reference_uris = @json['references'].nil? ? [] : (ActivityPub::FetchReferencesService.new.call(@status.account, @json['references']) || [])
@reference_uris += ProcessReferencesService.extract_uris(@json['content'] || '')
end
def quote
@json['quote'] || @json['quoteUrl'] || @json['quoteURL'] || @json['_misskey_quote']
end
def local_referred_accounts
return @local_referred_accounts if defined?(@local_referred_accounts)
local_referred_statuses = reference_uris.filter_map do |uri|
ActivityPub::TagManager.instance.local_uri?(uri) && ActivityPub::TagManager.instance.uri_to_resource(uri, Status)
end.compact
@local_referred_accounts = local_referred_statuses.map(&:account)
end
def expected_type?
equals_or_includes_any?(@json['type'], %w(Note Question))
end

View file

@ -212,7 +212,7 @@ class PostStatusService < BaseService
end
def validate_status_mentions!
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if mention_to_stranger? && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if (mention_to_stranger? || reference_to_stranger?) && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
end
def mention_to_stranger?
@ -220,6 +220,17 @@ class PostStatusService < BaseService
(@in_reply_to && @in_reply_to.account.id != @account.id && !@in_reply_to.account.following?(@account))
end
def reference_to_stranger?
referred_statuses.any? { |status| !status.account.following?(@account) }
end
def referred_statuses
statuses = ProcessReferencesService.extract_uris(@text).filter_map { |uri| ActivityPub::TagManager.instance.local_uri?(uri) && ActivityPub::TagManager.instance.uri_to_resource(uri, Status, url: true) }
statuses += Status.where(id: @reference_ids) if @reference_ids.present?
statuses
end
def validate_media!
if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
@media = []

View file

@ -45,6 +45,10 @@ class ProcessReferencesService < BaseService
reference_parameters.any? || (urls || []).any? || (quote_urls || []).any? || FormattingHelper.extract_status_plain_text(status).scan(REFURL_EXP).pluck(3).uniq.any?
end
def self.extract_uris(text)
text.scan(REFURL_EXP).pluck(3)
end
def self.perform_worker_async(status, reference_parameters, urls, quote_urls)
return unless need_process?(status, reference_parameters, urls, quote_urls)

View file

@ -86,7 +86,7 @@ class UpdateStatusService < BaseService
end
def validate_status_mentions!
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if mention_to_stranger? && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
raise Mastodon::ValidationError, I18n.t('statuses.contains_ng_words') if (mention_to_stranger? || reference_to_stranger?) && Setting.stranger_mention_from_local_ng && Admin::NgWord.stranger_mention_reject?("#{@options[:spoiler_text]}\n#{@options[:text]}")
end
def mention_to_stranger?
@ -94,6 +94,16 @@ class UpdateStatusService < BaseService
(@status.thread.present? && @status.thread.account.id != @status.account.id && !@status.thread.account.following?(@status.account))
end
def reference_to_stranger?
referred_statuses.any? { |status| !status.account.following?(@status.account) }
end
def referred_statuses
return [] unless @options[:text]
ProcessReferencesService.extract_uris(@options[:text]).filter_map { |uri| ActivityPub::TagManager.instance.local_uri?(uri) && ActivityPub::TagManager.instance.uri_to_resource(uri, Status, url: true) }
end
def validate_media!
return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)