diff options
author | Starfall <us@starfall.systems> | 2020-07-23 16:25:58 -0500 |
---|---|---|
committer | Starfall <us@starfall.systems> | 2020-07-23 16:25:58 -0500 |
commit | 2b41ed0fd69a7f7a0e17d6f0c6a421805c5e3127 (patch) | |
tree | a3ab43415b061112bc614205a3bb96bb9718bbd0 /app/lib/activitypub/activity | |
parent | e3d96a9bc62f57d60dc21906b4b803e346b0a738 (diff) | |
parent | 16416e940fd803af92377eee9a1756ef27eed199 (diff) |
Merge branch 'glitch' into main
Diffstat (limited to 'app/lib/activitypub/activity')
-rw-r--r-- | app/lib/activitypub/activity/announce.rb | 39 | ||||
-rw-r--r-- | app/lib/activitypub/activity/block.rb | 7 | ||||
-rw-r--r-- | app/lib/activitypub/activity/create.rb | 2 | ||||
-rw-r--r-- | app/lib/activitypub/activity/undo.rb | 51 | ||||
-rw-r--r-- | app/lib/activitypub/activity/update.rb | 2 |
5 files changed, 86 insertions, 15 deletions
diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb index 34c646668..9e108985a 100644 --- a/app/lib/activitypub/activity/announce.rb +++ b/app/lib/activitypub/activity/announce.rb @@ -4,25 +4,32 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity def perform return reject_payload! if delete_arrived_first?(@json['id']) || !related_to_local_activity? - original_status = status_from_object + RedisLock.acquire(lock_options) do |lock| + if lock.acquired? + original_status = status_from_object - return reject_payload! if original_status.nil? || !announceable?(original_status) + return reject_payload! if original_status.nil? || !announceable?(original_status) - status = Status.find_by(account: @account, reblog: original_status) + @status = Status.find_by(account: @account, reblog: original_status) - return status unless status.nil? + return @status unless @status.nil? - status = Status.create!( - account: @account, - reblog: original_status, - uri: @json['id'], - created_at: @json['published'], - override_timestamps: @options[:override_timestamps], - visibility: visibility_from_audience - ) + @status = Status.create!( + account: @account, + reblog: original_status, + uri: @json['id'], + created_at: @json['published'], + override_timestamps: @options[:override_timestamps], + visibility: visibility_from_audience + ) - distribute(status) - status + distribute(@status) + else + raise Mastodon::RaceConditionError + end + end + + @status end private @@ -54,4 +61,8 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity def reblog_of_local_status? status_from_uri(object_uri)&.account&.local? end + + def lock_options + { redis: Redis.current, key: "announce:#{@object['id']}" } + end end diff --git a/app/lib/activitypub/activity/block.rb b/app/lib/activitypub/activity/block.rb index a17a2d50a..90477bf33 100644 --- a/app/lib/activitypub/activity/block.rb +++ b/app/lib/activitypub/activity/block.rb @@ -4,7 +4,12 @@ class ActivityPub::Activity::Block < ActivityPub::Activity def perform target_account = account_from_uri(object_uri) - return if target_account.nil? || !target_account.local? || @account.blocking?(target_account) + return if target_account.nil? || !target_account.local? + + if @account.blocking?(target_account) + @account.block_relationships.find_by(target_account: target_account).update(uri: @json['id']) if @json['id'].present? + return + end UnfollowService.new.call(target_account, @account) if target_account.following?(@account) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index e81452e3c..08dd98e94 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -2,6 +2,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def perform + dereference_object! + case @object['type'] when 'EncryptedMessage' create_encrypted_message diff --git a/app/lib/activitypub/activity/undo.rb b/app/lib/activitypub/activity/undo.rb index 599823c6e..9eff1b71c 100644 --- a/app/lib/activitypub/activity/undo.rb +++ b/app/lib/activitypub/activity/undo.rb @@ -13,11 +13,62 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity undo_like when 'Block' undo_block + when nil + handle_reference end end private + def handle_reference + # Some implementations do not inline the object, and as we don't have a + # global index, we have to guess what object it is. + return if object_uri.nil? + + try_undo_announce || try_undo_accept || try_undo_follow || try_undo_like || try_undo_block || delete_later!(object_uri) + end + + def try_undo_announce + status = Status.where.not(reblog_of_id: nil).find_by(uri: object_uri, account: @account) + if status.present? + RemoveStatusService.new.call(status) + true + else + false + end + end + + def try_undo_accept + # We can't currently handle `Undo Accept` as we don't record `Accept`'s uri + false + end + + def try_undo_follow + follow = @account.follow_requests.find_by(uri: object_uri) || @account.active_relationships.find_by(uri: object_uri) + + if follow.present? + follow.destroy + true + else + false + end + end + + def try_undo_like + # There is an index on accounts, but an account may have *many* favs, so this may be too costly + false + end + + def try_undo_block + block = @account.block_relationships.find_by(uri: object_uri) + if block.present? + UnblockService.new.call(@account, block.target_account) + true + else + false + end + end + def undo_announce return if object_uri.nil? diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb index 70035325b..018e2df54 100644 --- a/app/lib/activitypub/activity/update.rb +++ b/app/lib/activitypub/activity/update.rb @@ -4,6 +4,8 @@ class ActivityPub::Activity::Update < ActivityPub::Activity SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze def perform + dereference_object! + if equals_or_includes_any?(@object['type'], SUPPORTED_TYPES) update_account elsif equals_or_includes_any?(@object['type'], %w(Question)) |