* Add: #591 リモート保留中アカウントからメンションが来た場合にuriを記録し、承認時にフェッチしに行く処理 * Rename fetch_remove_status_worker.rb to fetch_remote_status_worker.rb * Wip * Add lock code
This commit is contained in:
parent
b2acc7dbb8
commit
2ab9ea642a
22 changed files with 307 additions and 15 deletions
|
@ -50,6 +50,11 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
def create_status
|
||||
return reject_payload! if unsupported_object_type? || non_matching_uri_hosts?(@account.uri, object_uri) || tombstone_exists? || !related_to_local_activity?
|
||||
|
||||
if @account.suspended?
|
||||
process_pending_status if @account.remote_pending?
|
||||
return
|
||||
end
|
||||
|
||||
with_redis_lock("create:#{object_uri}") do
|
||||
return if delete_arrived_first?(object_uri) || poll_vote?
|
||||
|
||||
|
@ -405,6 +410,20 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, replied_to_status.id) unless replied_to_status.preloadable_poll.hide_totals?
|
||||
end
|
||||
|
||||
def process_pending_status
|
||||
with_redis_lock("pending_status:#{@object['id']}") do
|
||||
return if PendingStatus.exists?(uri: @object['id'])
|
||||
|
||||
fetch_account = as_array(@object['tag'])
|
||||
.filter_map { |tag| equals_or_includes?(tag['type'], 'Mention') && tag['href'] && ActivityPub::TagManager.instance.local_uri?(tag['href']) && ActivityPub::TagManager.instance.uri_to_resource(tag['href'], Account) }
|
||||
.first
|
||||
fetch_account ||= (audience_to + audience_cc).filter_map { |uri| ActivityPub::TagManager.instance.local_uri?(uri) && ActivityPub::TagManager.instance.uri_to_resource(uri, Account) }.first
|
||||
fetch_account ||= Account.representative
|
||||
|
||||
PendingStatus.create!(account: @account, uri: @object['id'], fetch_account: fetch_account)
|
||||
end
|
||||
end
|
||||
|
||||
def resolve_thread(status)
|
||||
return unless status.reply? && status.thread.nil? && Request.valid_url?(in_reply_to_uri)
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
|
|||
return
|
||||
end
|
||||
|
||||
if @account.suspended?
|
||||
PendingFollowRequest.create!(account: @account, target_account: target_account, uri: @json['id']) if @account.remote_pending?
|
||||
return
|
||||
end
|
||||
|
||||
if target_account.blocking?(@account) || target_account.domain_blocking?(@account.domain) || target_account.moved? || target_account.instance_actor? || block_new_follow?
|
||||
reject_follow_request!(target_account)
|
||||
return
|
||||
|
@ -33,13 +38,6 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
|
|||
return
|
||||
end
|
||||
|
||||
if @account.suspended? && @account.remote_pending?
|
||||
PendingFollowRequest.create!(account: @account, target_account: target_account, uri: @json['id'])
|
||||
return
|
||||
elsif @account.suspended?
|
||||
return
|
||||
end
|
||||
|
||||
follow_request = FollowRequest.create!(account: @account, target_account: target_account, uri: @json['id'])
|
||||
|
||||
if request_pending_follow?(@account, target_account)
|
||||
|
|
|
@ -298,14 +298,19 @@ class Account < ApplicationRecord
|
|||
end
|
||||
|
||||
def approve_remote!
|
||||
return unless remote_pending
|
||||
|
||||
update!(remote_pending: false)
|
||||
unsuspend!
|
||||
EnableFollowRequestsWorker.perform_async(id)
|
||||
ActivateRemoteAccountWorker.perform_async(id)
|
||||
end
|
||||
|
||||
def reject_remote!
|
||||
return unless remote_pending
|
||||
|
||||
update!(remote_pending: false, suspension_origin: :local)
|
||||
pending_follow_requests.destroy_all
|
||||
pending_statuses.destroy_all
|
||||
suspend!
|
||||
end
|
||||
|
||||
|
|
|
@ -50,6 +50,11 @@ module Account::Associations
|
|||
has_many :account_warnings, dependent: :destroy, inverse_of: :account
|
||||
has_many :strikes, class_name: 'AccountWarning', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account
|
||||
|
||||
# Remote pendings
|
||||
has_many :pending_follow_requests, dependent: :destroy
|
||||
has_many :pending_statuses, dependent: :destroy
|
||||
has_many :fetchable_pending_statuses, class_name: 'PendingStatus', foreign_key: :fetch_account_id, dependent: :destroy, inverse_of: :fetch_account
|
||||
|
||||
# Antennas (that the account is on, not owned by the account)
|
||||
has_many :antenna_accounts, inverse_of: :account, dependent: :destroy
|
||||
has_many :joined_antennas, class_name: 'Antenna', through: :antenna_accounts, source: :antenna
|
||||
|
|
|
@ -74,7 +74,6 @@ module Account::Interactions
|
|||
included do
|
||||
# Follow relations
|
||||
has_many :follow_requests, dependent: :destroy
|
||||
has_many :pending_follow_requests, dependent: :destroy
|
||||
|
||||
with_options class_name: 'Follow', dependent: :destroy do
|
||||
has_many :active_relationships, foreign_key: 'account_id', inverse_of: :account
|
||||
|
|
18
app/models/pending_status.rb
Normal file
18
app/models/pending_status.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: pending_statuses
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# fetch_account_id :bigint(8) not null
|
||||
# uri :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class PendingStatus < ApplicationRecord
|
||||
belongs_to :account
|
||||
belongs_to :fetch_account, class_name: 'Account'
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class EnableFollowRequestsService < BaseService
|
||||
class ActivateFollowRequestsService < BaseService
|
||||
include Payloadable
|
||||
include FollowHelper
|
||||
|
31
app/services/activate_remote_statuses_service.rb
Normal file
31
app/services/activate_remote_statuses_service.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivateRemoteStatusesService < BaseService
|
||||
include Payloadable
|
||||
include FollowHelper
|
||||
|
||||
def call(account)
|
||||
@account = account
|
||||
|
||||
PendingStatus.transaction do
|
||||
PendingStatus.where(account: account).find_each do |status_info|
|
||||
approve_status!(status_info)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def approve_status!(pending)
|
||||
account_id = pending.account_id
|
||||
fetch_account_id = pending.fetch_account_id
|
||||
fetch_account = pending.fetch_account
|
||||
uri = pending.uri
|
||||
pending.destroy!
|
||||
|
||||
return if fetch_account.suspended?
|
||||
return if ActivityPub::TagManager.instance.uri_to_resource(uri, Status).present?
|
||||
|
||||
ActivityPub::FetchRemoteStatusWorker.perform_async(uri, account_id, fetch_account_id)
|
||||
end
|
||||
end
|
|
@ -56,7 +56,7 @@ class ActivityPub::ProcessCollectionService < BaseService
|
|||
end
|
||||
|
||||
def activity_allowed_while_remote_pending?
|
||||
%w(Follow).include?(@json['type']) || activity_allowed_while_suspended?
|
||||
%w(Follow Create).include?(@json['type']) || activity_allowed_while_suspended?
|
||||
end
|
||||
|
||||
def process_items(items)
|
||||
|
|
|
@ -20,6 +20,7 @@ class DeleteAccountService < BaseService
|
|||
devices
|
||||
domain_blocks
|
||||
featured_tags
|
||||
fetchable_pending_statuses
|
||||
follow_requests
|
||||
list_accounts
|
||||
migrations
|
||||
|
@ -29,6 +30,7 @@ class DeleteAccountService < BaseService
|
|||
owned_lists
|
||||
passive_relationships
|
||||
pending_follow_requests
|
||||
pending_statuses
|
||||
report_notes
|
||||
scheduled_statuses
|
||||
scheduled_expiration_statuses
|
||||
|
@ -51,6 +53,7 @@ class DeleteAccountService < BaseService
|
|||
devices
|
||||
domain_blocks
|
||||
featured_tags
|
||||
fetchable_pending_statuses
|
||||
follow_requests
|
||||
list_accounts
|
||||
migrations
|
||||
|
@ -59,6 +62,7 @@ class DeleteAccountService < BaseService
|
|||
notifications
|
||||
owned_lists
|
||||
pending_follow_requests
|
||||
pending_statuses
|
||||
scheduled_statuses
|
||||
scheduled_expiration_statuses
|
||||
status_pins
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class EnableFollowRequestsWorker
|
||||
class ActivateRemoteAccountWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform(account_id)
|
||||
|
@ -8,6 +8,7 @@ class EnableFollowRequestsWorker
|
|||
return true if account.nil?
|
||||
return true if account.suspended?
|
||||
|
||||
EnableFollowRequestsService.new.call(account)
|
||||
ActivateFollowRequestsService.new.call(account)
|
||||
ActivateRemoteStatusesService.new.call(account)
|
||||
end
|
||||
end
|
17
app/workers/activitypub/fetch_remote_status_worker.rb
Normal file
17
app/workers/activitypub/fetch_remote_status_worker.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::FetchRemoteStatusWorker
|
||||
include Sidekiq::Worker
|
||||
include Redisable
|
||||
|
||||
sidekiq_options queue: 'pull', retry: 3
|
||||
|
||||
def perform(uri, author_account_id, on_behalf_of_account_id)
|
||||
author = Account.find(author_account_id)
|
||||
on_behalf_of = on_behalf_of_account_id.present? ? Account.find(on_behalf_of_account_id) : nil
|
||||
|
||||
ActivityPub::FetchRemoteStatusService.new.call(uri, on_behalf_of: on_behalf_of, expected_actor_uri: ActivityPub::TagManager.instance.uri_for(author), request_id: uri)
|
||||
rescue ActiveRecord::RecordNotFound, Mastodon::RaceConditionError
|
||||
true
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue