mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-28 22:15:06 +01:00
Merge pull request from GHSA-3fjr-858r-92rw
This commit is contained in:
parent
4a5f458ea0
commit
ed36f7beaa
@ -219,7 +219,7 @@ module SignatureVerification
|
|||||||
stoplight_wrap_request { ResolveAccountService.new.call(key_id.gsub(/\Aacct:/, '')) }
|
stoplight_wrap_request { ResolveAccountService.new.call(key_id.gsub(/\Aacct:/, '')) }
|
||||||
elsif !ActivityPub::TagManager.instance.local_uri?(key_id)
|
elsif !ActivityPub::TagManager.instance.local_uri?(key_id)
|
||||||
account = ActivityPub::TagManager.instance.uri_to_resource(key_id, Account)
|
account = ActivityPub::TagManager.instance.uri_to_resource(key_id, Account)
|
||||||
account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false) }
|
account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id) }
|
||||||
account
|
account
|
||||||
end
|
end
|
||||||
rescue Mastodon::HostValidationError
|
rescue Mastodon::HostValidationError
|
||||||
|
@ -143,8 +143,8 @@ module JsonLdHelper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_resource(uri, id, on_behalf_of = nil)
|
def fetch_resource(uri, id_is_known, on_behalf_of = nil)
|
||||||
unless id
|
unless id_is_known
|
||||||
json = fetch_resource_without_id_validation(uri, on_behalf_of)
|
json = fetch_resource_without_id_validation(uri, on_behalf_of)
|
||||||
|
|
||||||
return if !json.is_a?(Hash) || unsupported_uri_scheme?(json['id'])
|
return if !json.is_a?(Hash) || unsupported_uri_scheme?(json['id'])
|
||||||
|
@ -204,7 +204,8 @@ class ActivityPub::Activity
|
|||||||
def fetch_remote_original_status
|
def fetch_remote_original_status
|
||||||
if object_uri.start_with?('http')
|
if object_uri.start_with?('http')
|
||||||
return if ActivityPub::TagManager.instance.local_uri?(object_uri)
|
return if ActivityPub::TagManager.instance.local_uri?(object_uri)
|
||||||
ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true, on_behalf_of: @account.followers.local.first)
|
|
||||||
|
ActivityPub::FetchRemoteStatusService.new.call(object_uri, on_behalf_of: @account.followers.local.first)
|
||||||
elsif @object['url'].present?
|
elsif @object['url'].present?
|
||||||
::FetchRemoteStatusService.new.call(@object['url'])
|
::FetchRemoteStatusService.new.call(@object['url'])
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,7 @@ class ActivityPub::LinkedDataSignature
|
|||||||
return unless type == 'RsaSignature2017'
|
return unless type == 'RsaSignature2017'
|
||||||
|
|
||||||
creator = ActivityPub::TagManager.instance.uri_to_resource(creator_uri, Account)
|
creator = ActivityPub::TagManager.instance.uri_to_resource(creator_uri, Account)
|
||||||
creator ||= ActivityPub::FetchRemoteKeyService.new.call(creator_uri, id: false)
|
creator ||= ActivityPub::FetchRemoteKeyService.new.call(creator_uri)
|
||||||
|
|
||||||
return if creator.nil?
|
return if creator.nil?
|
||||||
|
|
||||||
|
@ -8,15 +8,15 @@ class ActivityPub::FetchRemoteAccountService < BaseService
|
|||||||
SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
|
SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
|
||||||
|
|
||||||
# Does a WebFinger roundtrip on each call, unless `only_key` is true
|
# Does a WebFinger roundtrip on each call, unless `only_key` is true
|
||||||
def call(uri, id: true, prefetched_body: nil, break_on_redirect: false, only_key: false)
|
def call(uri, prefetched_body: nil, break_on_redirect: false, only_key: false)
|
||||||
return if domain_not_allowed?(uri)
|
return if domain_not_allowed?(uri)
|
||||||
return ActivityPub::TagManager.instance.uri_to_resource(uri, Account) if ActivityPub::TagManager.instance.local_uri?(uri)
|
return ActivityPub::TagManager.instance.uri_to_resource(uri, Account) if ActivityPub::TagManager.instance.local_uri?(uri)
|
||||||
|
|
||||||
@json = begin
|
@json = begin
|
||||||
if prefetched_body.nil?
|
if prefetched_body.nil?
|
||||||
fetch_resource(uri, id)
|
fetch_resource(uri, true)
|
||||||
else
|
else
|
||||||
body_to_json(prefetched_body, compare_id: id ? uri : nil)
|
body_to_json(prefetched_body, compare_id: uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,23 +4,10 @@ class ActivityPub::FetchRemoteKeyService < BaseService
|
|||||||
include JsonLdHelper
|
include JsonLdHelper
|
||||||
|
|
||||||
# Returns account that owns the key
|
# Returns account that owns the key
|
||||||
def call(uri, id: true, prefetched_body: nil)
|
def call(uri)
|
||||||
return if uri.blank?
|
return if uri.blank?
|
||||||
|
|
||||||
if prefetched_body.nil?
|
@json = fetch_resource(uri, false)
|
||||||
if id
|
|
||||||
@json = fetch_resource_without_id_validation(uri)
|
|
||||||
if person?
|
|
||||||
@json = fetch_resource(@json['id'], true)
|
|
||||||
elsif uri != @json['id']
|
|
||||||
return
|
|
||||||
end
|
|
||||||
else
|
|
||||||
@json = fetch_resource(uri, id)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
@json = body_to_json(prefetched_body, compare_id: id ? uri : nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
return unless supported_context?(@json) && expected_type?
|
return unless supported_context?(@json) && expected_type?
|
||||||
return find_account(@json['id'], @json) if person?
|
return find_account(@json['id'], @json) if person?
|
||||||
|
@ -4,19 +4,19 @@ class ActivityPub::FetchRemoteStatusService < BaseService
|
|||||||
include JsonLdHelper
|
include JsonLdHelper
|
||||||
|
|
||||||
# Should be called when uri has already been checked for locality
|
# Should be called when uri has already been checked for locality
|
||||||
def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil)
|
def call(uri, prefetched_body: nil, on_behalf_of: nil)
|
||||||
@json = begin
|
@json = begin
|
||||||
if prefetched_body.nil?
|
if prefetched_body.nil?
|
||||||
fetch_resource(uri, id, on_behalf_of)
|
fetch_resource(uri, true, on_behalf_of)
|
||||||
else
|
else
|
||||||
body_to_json(prefetched_body, compare_id: id ? uri : nil)
|
body_to_json(prefetched_body, compare_id: uri)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return if !(supported_context? && expected_type?) || actor_id.nil? || !trustworthy_attribution?(@json['id'], actor_id)
|
return if !(supported_context? && expected_type?) || actor_id.nil? || !trustworthy_attribution?(@json['id'], actor_id)
|
||||||
|
|
||||||
actor = ActivityPub::TagManager.instance.uri_to_resource(actor_id, Account)
|
actor = ActivityPub::TagManager.instance.uri_to_resource(actor_id, Account)
|
||||||
actor = ActivityPub::FetchRemoteAccountService.new.call(actor_id, id: true) if actor.nil? || needs_update?(actor)
|
actor = ActivityPub::FetchRemoteAccountService.new.call(actor_id) if actor.nil? || needs_update?(actor)
|
||||||
|
|
||||||
return if actor.nil? || actor.suspended?
|
return if actor.nil? || actor.suspended?
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||||||
|
|
||||||
def moved_account
|
def moved_account
|
||||||
account = ActivityPub::TagManager.instance.uri_to_resource(@json['movedTo'], Account)
|
account = ActivityPub::TagManager.instance.uri_to_resource(@json['movedTo'], Account)
|
||||||
account ||= ActivityPub::FetchRemoteAccountService.new.call(@json['movedTo'], id: true, break_on_redirect: true)
|
account ||= ActivityPub::FetchRemoteAccountService.new.call(@json['movedTo'], break_on_redirect: true)
|
||||||
account
|
account
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,7 +47,15 @@ class FetchResourceService < BaseService
|
|||||||
body = response.body_with_limit
|
body = response.body_with_limit
|
||||||
json = body_to_json(body)
|
json = body_to_json(body)
|
||||||
|
|
||||||
[json['id'], { prefetched_body: body, id: true }] if supported_context?(json) && (equals_or_includes_any?(json['type'], ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES) || expected_type?(json))
|
return unless supported_context?(json) && (equals_or_includes_any?(json['type'], ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES) || expected_type?(json))
|
||||||
|
|
||||||
|
if json['id'] != @url
|
||||||
|
return if terminal
|
||||||
|
|
||||||
|
return process(json['id'], terminal: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
[@url, { prefetched_body: body }]
|
||||||
elsif !terminal
|
elsif !terminal
|
||||||
link_header = response['Link'] && parse_link_header(response)
|
link_header = response['Link'] && parse_link_header(response)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#call' do
|
describe '#call' do
|
||||||
let(:account) { subject.call('https://example.com/alice', id: true) }
|
let(:account) { subject.call('https://example.com/alice') }
|
||||||
|
|
||||||
shared_examples 'sets profile data' do
|
shared_examples 'sets profile data' do
|
||||||
it 'returns an account' do
|
it 'returns an account' do
|
||||||
|
@ -54,7 +54,7 @@ RSpec.describe FetchResourceService, type: :service do
|
|||||||
|
|
||||||
let(:json) do
|
let(:json) do
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 'http://example.com/foo',
|
||||||
'@context': ActivityPub::TagManager::CONTEXT,
|
'@context': ActivityPub::TagManager::CONTEXT,
|
||||||
type: 'Note',
|
type: 'Note',
|
||||||
}.to_json
|
}.to_json
|
||||||
@ -79,14 +79,14 @@ RSpec.describe FetchResourceService, type: :service do
|
|||||||
let(:content_type) { 'application/activity+json; charset=utf-8' }
|
let(:content_type) { 'application/activity+json; charset=utf-8' }
|
||||||
let(:body) { json }
|
let(:body) { json }
|
||||||
|
|
||||||
it { is_expected.to eq [1, { prefetched_body: body, id: true }] }
|
it { is_expected.to eq ['http://example.com/foo', { prefetched_body: body }] }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when content type is ld+json with profile' do
|
context 'when content type is ld+json with profile' do
|
||||||
let(:content_type) { 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' }
|
let(:content_type) { 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' }
|
||||||
let(:body) { json }
|
let(:body) { json }
|
||||||
|
|
||||||
it { is_expected.to eq [1, { prefetched_body: body, id: true }] }
|
it { is_expected.to eq ['http://example.com/foo', { prefetched_body: body }] }
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@ -97,14 +97,14 @@ RSpec.describe FetchResourceService, type: :service do
|
|||||||
context 'when link header is present' do
|
context 'when link header is present' do
|
||||||
let(:headers) { { 'Link' => '<http://example.com/foo>; rel="alternate"; type="application/activity+json"', } }
|
let(:headers) { { 'Link' => '<http://example.com/foo>; rel="alternate"; type="application/activity+json"', } }
|
||||||
|
|
||||||
it { is_expected.to eq [1, { prefetched_body: json, id: true }] }
|
it { is_expected.to eq ['http://example.com/foo', { prefetched_body: json }] }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when content type is text/html' do
|
context 'when content type is text/html' do
|
||||||
let(:content_type) { 'text/html' }
|
let(:content_type) { 'text/html' }
|
||||||
let(:body) { '<html><head><link rel="alternate" href="http://example.com/foo" type="application/activity+json"/></head></html>' }
|
let(:body) { '<html><head><link rel="alternate" href="http://example.com/foo" type="application/activity+json"/></head></html>' }
|
||||||
|
|
||||||
it { is_expected.to eq [1, { prefetched_body: json, id: true }] }
|
it { is_expected.to eq ['http://example.com/foo', { prefetched_body: json }] }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user