Merge tag 'v3.2.1' into instance_only_statuses
This commit is contained in:
@ -168,11 +168,13 @@ class ActivityPub::Activity
|
||||
end
|
||||
|
||||
def signed_fetch_account
|
||||
return Account.find(@options[:delivered_to_account_id]) if @options[:delivered_to_account_id].present?
|
||||
|
||||
first_mentioned_local_account || first_local_follower
|
||||
end
|
||||
|
||||
def first_mentioned_local_account
|
||||
audience = (as_array(@json['to']) + as_array(@json['cc'])).uniq
|
||||
audience = (as_array(@json['to']) + as_array(@json['cc'])).map { |x| value_or_id(x) }.uniq
|
||||
local_usernames = audience.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }
|
||||
.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
|
||||
|
||||
|
||||
@ -34,12 +34,20 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
|
||||
|
||||
private
|
||||
|
||||
def audience_to
|
||||
as_array(@json['to']).map { |x| value_or_id(x) }
|
||||
end
|
||||
|
||||
def audience_cc
|
||||
as_array(@json['cc']).map { |x| value_or_id(x) }
|
||||
end
|
||||
|
||||
def visibility_from_audience
|
||||
if equals_or_includes?(@json['to'], ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
if audience_to.include?(ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
:public
|
||||
elsif equals_or_includes?(@json['cc'], ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
elsif audience_cc.include?(ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
:unlisted
|
||||
elsif equals_or_includes?(@json['to'], @account.followers_url)
|
||||
elsif audience_to.include?(@account.followers_url)
|
||||
:private
|
||||
else
|
||||
:direct
|
||||
|
||||
@ -65,11 +65,11 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||
end
|
||||
|
||||
def audience_to
|
||||
@object['to'] || @json['to']
|
||||
as_array(@object['to'] || @json['to']).map { |x| value_or_id(x) }
|
||||
end
|
||||
|
||||
def audience_cc
|
||||
@object['cc'] || @json['cc']
|
||||
as_array(@object['cc'] || @json['cc']).map { |x| value_or_id(x) }
|
||||
end
|
||||
|
||||
def process_status
|
||||
@ -122,7 +122,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||
end
|
||||
|
||||
def process_audience
|
||||
(as_array(audience_to) + as_array(audience_cc)).uniq.each do |audience|
|
||||
(audience_to + audience_cc).uniq.each do |audience|
|
||||
next if audience == ActivityPub::TagManager::COLLECTIONS[:public]
|
||||
|
||||
# Unlike with tags, there is no point in resolving accounts we don't already
|
||||
@ -352,11 +352,11 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||
end
|
||||
|
||||
def visibility_from_audience
|
||||
if equals_or_includes?(audience_to, ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
if audience_to.include?(ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
:public
|
||||
elsif equals_or_includes?(audience_cc, ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
elsif audience_cc.include?(ActivityPub::TagManager::COLLECTIONS[:public])
|
||||
:unlisted
|
||||
elsif equals_or_includes?(audience_to, @account.followers_url)
|
||||
elsif audience_to.include?(@account.followers_url)
|
||||
:private
|
||||
else
|
||||
:direct
|
||||
@ -365,7 +365,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||
|
||||
def audience_includes?(account)
|
||||
uri = ActivityPub::TagManager.instance.uri_for(account)
|
||||
equals_or_includes?(audience_to, uri) || equals_or_includes?(audience_cc, uri)
|
||||
audience_to.include?(uri) || audience_cc.include?(uri)
|
||||
end
|
||||
|
||||
def replied_to_status
|
||||
@ -477,7 +477,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||
def addresses_local_accounts?
|
||||
return true if @options[:delivered_to_account_id]
|
||||
|
||||
local_usernames = (as_array(audience_to) + as_array(audience_cc)).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
|
||||
local_usernames = (audience_to + audience_cc).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
|
||||
|
||||
return false if local_usernames.empty?
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
|
||||
def perform
|
||||
return reject_follow_for_relay if relay_follow?
|
||||
return follow_request_from_object.reject! unless follow_request_from_object.nil?
|
||||
return UnfollowService.new.call(follow_from_object.target_account, @account) unless follow_from_object.nil?
|
||||
return UnfollowService.new.call(follow_from_object.account, @account) unless follow_from_object.nil?
|
||||
|
||||
case @object['type']
|
||||
when 'Follow'
|
||||
|
||||
93
app/lib/webfinger.rb
Normal file
93
app/lib/webfinger.rb
Normal file
@ -0,0 +1,93 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Webfinger
|
||||
class Error < StandardError; end
|
||||
|
||||
class Response
|
||||
def initialize(body)
|
||||
@json = Oj.load(body, mode: :strict)
|
||||
end
|
||||
|
||||
def subject
|
||||
@json['subject']
|
||||
end
|
||||
|
||||
def link(rel, attribute)
|
||||
links.dig(rel, attribute)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def links
|
||||
@links ||= @json['links'].map { |link| [link['rel'], link] }.to_h
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(uri)
|
||||
_, @domain = uri.split('@')
|
||||
|
||||
raise ArgumentError, 'Webfinger requested for local account' if @domain.nil?
|
||||
|
||||
@uri = uri
|
||||
end
|
||||
|
||||
def perform
|
||||
Response.new(body_from_webfinger)
|
||||
rescue Oj::ParseError
|
||||
raise Webfinger::Error, "Invalid JSON in response for #{@uri}"
|
||||
rescue Addressable::URI::InvalidURIError
|
||||
raise Webfinger::Error, "Invalid URI for #{@uri}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def body_from_webfinger(url = standard_url, use_fallback = true)
|
||||
webfinger_request(url).perform do |res|
|
||||
if res.code == 200
|
||||
res.body_with_limit
|
||||
elsif res.code == 404 && use_fallback
|
||||
body_from_host_meta
|
||||
else
|
||||
raise Webfinger::Error, "Request for #{@uri} returned HTTP #{res.code}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def body_from_host_meta
|
||||
host_meta_request.perform do |res|
|
||||
if res.code == 200
|
||||
body_from_webfinger(url_from_template(res.body_with_limit), false)
|
||||
else
|
||||
raise Webfinger::Error, "Request for #{@uri} returned HTTP #{res.code}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def url_from_template(str)
|
||||
link = Nokogiri::XML(str).at_xpath('//xmlns:Link[@rel="lrdd"]')
|
||||
|
||||
if link.present?
|
||||
link['template'].gsub('{uri}', @uri)
|
||||
else
|
||||
raise Webfinger::Error, "Request for #{@uri} returned host-meta without link to Webfinger"
|
||||
end
|
||||
rescue Nokogiri::XML::XPath::SyntaxError
|
||||
raise Webfinger::Error, "Invalid XML encountered in host-meta for #{@uri}"
|
||||
end
|
||||
|
||||
def host_meta_request
|
||||
Request.new(:get, host_meta_url).add_headers('Accept' => 'application/xrd+xml, application/xml, text/xml')
|
||||
end
|
||||
|
||||
def webfinger_request(url)
|
||||
Request.new(:get, url).add_headers('Accept' => 'application/jrd+json, application/json')
|
||||
end
|
||||
|
||||
def standard_url
|
||||
"https://#{@domain}/.well-known/webfinger?resource=#{@uri}"
|
||||
end
|
||||
|
||||
def host_meta_url
|
||||
"https://#{@domain}/.well-known/host-meta"
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user