diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2017-08-21 22:57:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-21 22:57:34 +0200 |
commit | 72bb3e03fdf4d8c886d41f3459000b336a3a362b (patch) | |
tree | ef5e3f97195bf55d04b49ac6cdf04b6394d8f686 /app/services/activitypub | |
parent | f391a4673adc6d79bb3a46b493d599a4bf6d558f (diff) |
Support more variations of ActivityPub keyId in signature (#4630)
- Tries to avoid performing HTTP request if the keyId is an actor URI - Likewise if the URI is a fragment URI on top of actor URI - Resolves public key, returns owner if the owner links back to the key
Diffstat (limited to 'app/services/activitypub')
-rw-r--r-- | app/services/activitypub/fetch_remote_key_service.rb | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/app/services/activitypub/fetch_remote_key_service.rb b/app/services/activitypub/fetch_remote_key_service.rb new file mode 100644 index 000000000..ebd64071e --- /dev/null +++ b/app/services/activitypub/fetch_remote_key_service.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +class ActivityPub::FetchRemoteKeyService < BaseService + include JsonLdHelper + + # Returns account that owns the key + def call(uri, prefetched_json = nil) + @json = body_to_json(prefetched_json) || fetch_resource(uri) + + return unless supported_context?(@json) && expected_type? + return find_account(uri, @json) if person? + + @owner = fetch_resource(owner_uri) + + return unless supported_context?(@owner) && confirmed_owner? + + find_account(owner_uri, @owner) + end + + private + + def find_account(uri, prefetched_json) + account = ActivityPub::TagManager.instance.uri_to_resource(uri, Account) + account ||= ActivityPub::FetchRemoteAccountService.new.call(uri, prefetched_json) + account + end + + def expected_type? + person? || public_key? + end + + def person? + @json['type'] == 'Person' + end + + def public_key? + @json['publicKeyPem'].present? && @json['owner'].present? + end + + def owner_uri + @owner_uri ||= value_or_id(@json['owner']) + end + + def confirmed_owner? + @owner['type'] == 'Person' && value_or_id(@owner['publicKey']) == @json['id'] + end +end |