From 256e85e32608f012209fd1d52486174995b77905 Mon Sep 17 00:00:00 2001 From: Fire Demon Date: Fri, 7 Aug 2020 00:20:41 -0500 Subject: [Feature, Federation] Add support for arbitarty account and server metadata fields --- app/lib/activitypub/adapter.rb | 2 ++ app/models/account_metadata.rb | 22 ++++++++++++++++ app/serializers/activitypub/actor_serializer.rb | 11 +++++++- app/serializers/activitypub/note_serializer.rb | 7 ++++- lib/mastodon/version.rb | 35 +++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 5b78b8a7b..b02059430 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -14,6 +14,8 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base show_unlisted: { 'mp' => 'http://the.monsterpit.net/ns#', 'showUnlisted' => 'mp:showUnlisted' }, private: { 'mp' => 'http://the.monsterpit.net/ns#', 'private' => 'mp:private' }, require_auth: { 'mp' => 'http://the.monsterpit.net/ns#', 'requireAuth' => 'mp:requireAuth' }, + metadata: { 'mp' => 'https://the.monsterpit.net/ns#', 'metadata' => { '@id' => 'mp:metadata', '@type' => '@id' } }, + server_metadata: { 'mp' => 'https://the.monsterpit.net/ns#', 'serverMetadata' => { '@id' => 'mp:serverMetadata', '@type' => '@id' } }, manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' }, sensitive: { 'sensitive' => 'as:sensitive' }, hashtag: { 'Hashtag' => 'as:Hashtag' }, diff --git a/app/models/account_metadata.rb b/app/models/account_metadata.rb index 1085d7f14..bb0f7676e 100644 --- a/app/models/account_metadata.rb +++ b/app/models/account_metadata.rb @@ -18,6 +18,28 @@ class AccountMetadata < ApplicationRecord self[:fields].presence || {} end + def fields_json + fields.select { |name, _| name.start_with?('custom:') } + .map do |name, value| + { + '@context': { + schema: 'http://schema.org/', + name: 'schema:name', + value: 'schema:value', + }, + type: 'PropertyValue', + name: name, + value: value.is_a?(Array) ? value.join("\r\n") : value, + } + end + end + + def cached_fields_json + Rails.cache.fetch("custom_metadata:#{account_id}", expires_in: 1.hour) do + fields_json + end + end + class << self def create_or_update(fields) create(fields).presence || update(fields) diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index 8e5e5b4bb..d9d47808e 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -24,8 +24,9 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer attribute :moved_to, if: :moved? attribute :also_known_as, if: :also_known_as? - context_extensions :require_dereference, :show_replies, :private, :require_auth + context_extensions :require_dereference, :show_replies, :private, :require_auth, :metadata, :server_metadata attributes :require_dereference, :show_replies, :show_unlisted, :private, :require_auth + attributes :metadata, :server_metadata class EndpointsSerializer < ActivityPub::Serializer include RoutingHelper @@ -136,6 +137,14 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer object.fields + object.identity_proofs.active end + def metadata + object.metadata.cached_fields_json + end + + def server_metadata + Mastodon::Version.server_metadata_json + end + def moved_to ActivityPub::TagManager.instance.uri_for(object.moved_to_account) end diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index 86dc64590..3d99e29c4 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -3,7 +3,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer context_extensions :atom_uri, :conversation, :sensitive, :voters_count, :direct_message - context_extensions :edited + context_extensions :edited, :server_metadata attributes :id, :type, :summary, :in_reply_to, :published, :url, @@ -18,6 +18,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer attribute :content_map, if: :language? attribute :direct_message, if: :non_public? + attribute :server_metadata has_many :media_attachments, key: :attachment has_many :virtual_tags, key: :tag @@ -195,6 +196,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer object.title.present? end + def server_metadata + Mastodon::Version.server_metadata_json + end + class MediaAttachmentSerializer < ActivityPub::Serializer context_extensions :blurhash, :focal_point diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 1a8aabe8c..0cad7a273 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -56,5 +56,40 @@ module Mastodon def user_agent @user_agent ||= "#{HTTP::Request::USER_AGENT} (Mastodon/#{Version}; +http#{Rails.configuration.x.use_https ? 's' : ''}://#{Rails.configuration.x.web_domain}/)" end + + def server_metadata_json + @server_metadata_json ||= [ + { + '@context': { 'schema': 'http://schema.org/', name: 'schema:name', value: 'schema:value' }, + type: 'PropertyValue', + name: 'version', + value: to_s, + }, + { + '@context': { 'schema': 'http://schema.org/', name: 'schema:name', value: 'schema:value' }, + type: 'PropertyValue', + name: 'monsterpit:extensions', + value: '2020.08.06.1', + }, + { + '@context': { 'schema': 'http://schema.org/', name: 'schema:name', value: 'schema:value' }, + type: 'PropertyValue', + name: 'comment:0', + value: "big tails can't fail", + }, + { + '@context': { 'schema': 'http://schema.org/', name: 'schema:name', value: 'schema:value' }, + type: 'PropertyValue', + name: 'comment:1', + value: 'trans rights!', + }, + { + '@context': { 'schema': 'http://schema.org/', name: 'schema:name', value: 'schema:value' }, + type: 'PropertyValue', + name: 'comment:2', + value: 'gently the kobolds', + }, + ] + end end end -- cgit