about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-08-07 00:20:41 -0500
committerFire Demon <firedemon@creature.cafe>2020-08-30 05:45:17 -0500
commit256e85e32608f012209fd1d52486174995b77905 (patch)
tree37cef8207a19ae8c364243bac597a4c45df97e72
parent93b17730518898d7de5ce1a3c6cc4df40f30c79d (diff)
[Feature, Federation] Add support for arbitarty account and server metadata fields
-rw-r--r--app/lib/activitypub/adapter.rb2
-rw-r--r--app/models/account_metadata.rb22
-rw-r--r--app/serializers/activitypub/actor_serializer.rb11
-rw-r--r--app/serializers/activitypub/note_serializer.rb7
-rw-r--r--lib/mastodon/version.rb35
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