Skip to content

Commit 7e6d5ae

Browse files
authored
Filter incoming Announce activities by relation to local activity (mastodon#10041)
* Filter incoming Announce activities by relation to local activity Reject if announcer is not followed by local accounts, and is not from an enabled relay, and the object is not a local status Follow-up to mastodon#10005 * Fix tests
1 parent e44f020 commit 7e6d5ae

4 files changed

Lines changed: 25 additions & 13 deletions

File tree

app/lib/activitypub/activity.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,13 @@ def delete_later!(uri)
138138
def status_from_object
139139
# If the status is already known, return it
140140
status = status_from_uri(object_uri)
141+
141142
return status unless status.nil?
142143

143144
# If the boosted toot is embedded and it is a self-boost, handle it like a Create
144145
unless unsupported_object_type?
145146
actor_id = value_or_id(first_of_value(@object['attributedTo'])) || @account.uri
147+
146148
if actor_id == @account.uri
147149
return ActivityPub::Activity.factory({ 'type' => 'Create', 'actor' => actor_id, 'object' => @object }, @account).perform
148150
end
@@ -166,4 +168,16 @@ def lock_or_return(key, expire_after = 7.days.seconds)
166168
ensure
167169
redis.del(key)
168170
end
171+
172+
def fetch?
173+
!@options[:delivery]
174+
end
175+
176+
def followed_by_local_accounts?
177+
@account.passive_relationships.exists?
178+
end
179+
180+
def requested_through_relay?
181+
@options[:relayed_through_account] && Relay.find_by(inbox_url: @options[:relayed_through_account].inbox_url)&.enabled?
182+
end
169183
end

app/lib/activitypub/activity/announce.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
class ActivityPub::Activity::Announce < ActivityPub::Activity
44
def perform
55
original_status = status_from_object
6-
return if original_status.nil? || delete_arrived_first?(@json['id']) || !announceable?(original_status)
6+
7+
return if original_status.nil? || delete_arrived_first?(@json['id']) || !announceable?(original_status) || !related_to_local_activity?
78

89
status = Status.find_by(account: @account, reblog: original_status)
910

@@ -39,4 +40,12 @@ def visibility_from_audience
3940
def announceable?(status)
4041
status.account_id == @account.id || status.public_visibility? || status.unlisted_visibility?
4142
end
43+
44+
def related_to_local_activity?
45+
followed_by_local_accounts? || requested_through_relay? || reblog_of_local_status?
46+
end
47+
48+
def reblog_of_local_status?
49+
status_from_uri(object_uri)&.account&.local?
50+
end
4251
end

app/lib/activitypub/activity/create.rb

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -341,18 +341,6 @@ def related_to_local_activity?
341341
responds_to_followed_account? || addresses_local_accounts?
342342
end
343343

344-
def fetch?
345-
!@options[:delivery]
346-
end
347-
348-
def followed_by_local_accounts?
349-
@account.passive_relationships.exists?
350-
end
351-
352-
def requested_through_relay?
353-
@options[:relayed_through_account] && Relay.find_by(inbox_url: @options[:relayed_through_account].inbox_url)&.enabled?
354-
end
355-
356344
def responds_to_followed_account?
357345
!replied_to_status.nil? && (replied_to_status.account.local? || replied_to_status.account.passive_relationships.exists?)
358346
end

spec/lib/activitypub/activity/announce_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
subject { described_class.new(json, sender) }
1919

2020
before do
21+
Fabricate(:account).follow!(sender)
2122
sender.update(uri: ActivityPub::TagManager.instance.uri_for(sender))
2223
end
2324

0 commit comments

Comments
 (0)