summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/lib/activitypub/adapter.rb75
-rw-r--r--app/lib/activitypub/serializer.rb30
-rw-r--r--app/serializers/activitypub/accept_follow_serializer.rb2
-rw-r--r--app/serializers/activitypub/activity_serializer.rb2
-rw-r--r--app/serializers/activitypub/actor_serializer.rb13
-rw-r--r--app/serializers/activitypub/add_serializer.rb2
-rw-r--r--app/serializers/activitypub/block_serializer.rb2
-rw-r--r--app/serializers/activitypub/collection_serializer.rb2
-rw-r--r--app/serializers/activitypub/delete_actor_serializer.rb2
-rw-r--r--app/serializers/activitypub/delete_serializer.rb6
-rw-r--r--app/serializers/activitypub/emoji_serializer.rb4
-rw-r--r--app/serializers/activitypub/flag_serializer.rb2
-rw-r--r--app/serializers/activitypub/follow_serializer.rb2
-rw-r--r--app/serializers/activitypub/image_serializer.rb4
-rw-r--r--app/serializers/activitypub/like_serializer.rb2
-rw-r--r--app/serializers/activitypub/note_serializer.rb15
-rw-r--r--app/serializers/activitypub/public_key_serializer.rb4
-rw-r--r--app/serializers/activitypub/reject_follow_serializer.rb2
-rw-r--r--app/serializers/activitypub/remove_serializer.rb2
-rw-r--r--app/serializers/activitypub/undo_announce_serializer.rb2
-rw-r--r--app/serializers/activitypub/undo_block_serializer.rb2
-rw-r--r--app/serializers/activitypub/undo_follow_serializer.rb2
-rw-r--r--app/serializers/activitypub/undo_like_serializer.rb2
-rw-r--r--app/serializers/activitypub/update_poll_serializer.rb2
-rw-r--r--app/serializers/activitypub/update_serializer.rb2
-rw-r--r--app/serializers/activitypub/vote_serializer.rb4
-rw-r--r--config/initializers/active_model_serializers.rb19
-rw-r--r--spec/lib/activitypub/adapter_spec.rb88
28 files changed, 235 insertions, 61 deletions
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb
index 99f4d930554..7e0b16c25dc 100644
--- a/app/lib/activitypub/adapter.rb
+++ b/app/lib/activitypub/adapter.rb
@@ -1,30 +1,23 @@
# frozen_string_literal: true
class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
- CONTEXT = {
- '@context': [
- 'https://www.w3.org/ns/activitystreams',
- 'https://w3id.org/security/v1',
-
- {
- 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
- 'sensitive' => 'as:sensitive',
- 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' },
- 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' },
- 'Hashtag' => 'as:Hashtag',
- 'ostatus' => 'http://ostatus.org#',
- 'atomUri' => 'ostatus:atomUri',
- 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri',
- 'conversation' => 'ostatus:conversation',
- 'toot' => 'http://joinmastodon.org/ns#',
- 'Emoji' => 'toot:Emoji',
- 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' },
- 'featured' => { '@id' => 'toot:featured', '@type' => '@id' },
- 'schema' => 'http://schema.org#',
- 'PropertyValue' => 'schema:PropertyValue',
- 'value' => 'schema:value',
- },
- ],
+ NAMED_CONTEXT_MAP = {
+ activitystreams: 'https://www.w3.org/ns/activitystreams',
+ security: 'https://w3id.org/security/v1',
+ }.freeze
+
+ CONTEXT_EXTENSION_MAP = {
+ manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' },
+ sensitive: { 'sensitive' => 'as:sensitive' },
+ hashtag: { 'Hashtag' => 'as:Hashtag' },
+ moved_to: { 'movedTo' => { '@id' => 'as:movedTo', '@type' => '@id' } },
+ also_known_as: { 'alsoKnownAs' => { '@id' => 'as:alsoKnownAs', '@type' => '@id' } },
+ emoji: { 'toot' => 'http://joinmastodon.org/ns#', 'Emoji' => 'toot:Emoji' },
+ featured: { 'toot' => 'http://joinmastodon.org/ns#', 'featured' => { '@id' => 'toot:featured', '@type' => '@id' } },
+ property_value: { 'schema' => 'http://schema.org#', 'PropertyValue' => 'schema:PropertyValue', 'value' => 'schema:value' },
+ atom_uri: { 'ostatus' => 'http://ostatus.org#', 'atomUri' => 'ostatus:atomUri' },
+ conversation: { 'ostatus' => 'http://ostatus.org#', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation' },
+ focal_point: { 'toot' => 'http://joinmastodon.org/ns#', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } },
}.freeze
def self.default_key_transform
@@ -36,8 +29,36 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
end
def serializable_hash(options = nil)
- options = serialization_options(options)
- serialized_hash = ActiveModelSerializers::Adapter::Attributes.new(serializer, instance_options).serializable_hash(options)
- CONTEXT.merge(self.class.transform_key_casing!(serialized_hash, instance_options))
+ options = serialization_options(options)
+ serialized_hash = serializer.serializable_hash(options)
+ serialized_hash = self.class.transform_key_casing!(serialized_hash, instance_options)
+
+ { '@context' => serialized_context }.merge(serialized_hash)
+ end
+
+ private
+
+ def serialized_context
+ context_array = []
+
+ serializer_options = serializer.send(:instance_options) || {}
+ named_contexts = [:activitystreams] + serializer._named_contexts.keys + serializer_options.fetch(:named_contexts, {}).keys
+ context_extensions = serializer._context_extensions.keys + serializer_options.fetch(:context_extensions, {}).keys
+
+ named_contexts.each do |key|
+ context_array << NAMED_CONTEXT_MAP[key]
+ end
+
+ extensions = context_extensions.each_with_object({}) do |key, h|
+ h.merge!(CONTEXT_EXTENSION_MAP[key])
+ end
+
+ context_array << extensions unless extensions.empty?
+
+ if context_array.size == 1
+ context_array.first
+ else
+ context_array
+ end
end
end
diff --git a/app/lib/activitypub/serializer.rb b/app/lib/activitypub/serializer.rb
new file mode 100644
index 00000000000..07bd8c49461
--- /dev/null
+++ b/app/lib/activitypub/serializer.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class ActivityPub::Serializer < ActiveModel::Serializer
+ with_options instance_writer: false, instance_reader: true do |serializer|
+ serializer.class_attribute :_named_contexts
+ serializer.class_attribute :_context_extensions
+
+ self._named_contexts ||= {}
+ self._context_extensions ||= {}
+ end
+
+ def self.inherited(base)
+ super
+
+ base._named_contexts = _named_contexts.dup
+ base._context_extensions = _context_extensions.dup
+ end
+
+ def self.context(*named_contexts)
+ named_contexts.each do |context|
+ _named_contexts[context] = true
+ end
+ end
+
+ def self.context_extensions(*extension_names)
+ extension_names.each do |extension_name|
+ _context_extensions[extension_name] = true
+ end
+ end
+end
diff --git a/app/serializers/activitypub/accept_follow_serializer.rb b/app/serializers/activitypub/accept_follow_serializer.rb
index 3e23591a527..1c1c6ab73bb 100644
--- a/app/serializers/activitypub/accept_follow_serializer.rb
+++ b/app/serializers/activitypub/accept_follow_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::AcceptFollowSerializer < ActiveModel::Serializer
+class ActivityPub::AcceptFollowSerializer < ActivityPub::Serializer
attributes :id, :type, :actor
has_one :object, serializer: ActivityPub::FollowSerializer
diff --git a/app/serializers/activitypub/activity_serializer.rb b/app/serializers/activitypub/activity_serializer.rb
index c001e28aae4..c06d5c87ca3 100644
--- a/app/serializers/activitypub/activity_serializer.rb
+++ b/app/serializers/activitypub/activity_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::ActivitySerializer < ActiveModel::Serializer
+class ActivityPub::ActivitySerializer < ActivityPub::Serializer
attributes :id, :type, :actor, :published, :to, :cc
has_one :proper, key: :object, serializer: ActivityPub::NoteSerializer, if: :serialize_object?
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
index 6746c178292..4b982b95511 100644
--- a/app/serializers/activitypub/actor_serializer.rb
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -1,8 +1,13 @@
# frozen_string_literal: true
-class ActivityPub::ActorSerializer < ActiveModel::Serializer
+class ActivityPub::ActorSerializer < ActivityPub::Serializer
include RoutingHelper
+ context :security
+
+ context_extensions :manually_approves_followers, :featured, :also_known_as,
+ :moved_to, :property_value, :hashtag, :emoji
+
attributes :id, :type, :following, :followers,
:inbox, :outbox, :featured,
:preferred_username, :name, :summary,
@@ -16,7 +21,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
attribute :moved_to, if: :moved?
attribute :also_known_as, if: :also_known_as?
- class EndpointsSerializer < ActiveModel::Serializer
+ class EndpointsSerializer < ActivityPub::Serializer
include RoutingHelper
attributes :shared_inbox
@@ -124,7 +129,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
class CustomEmojiSerializer < ActivityPub::EmojiSerializer
end
- class TagSerializer < ActiveModel::Serializer
+ class TagSerializer < ActivityPub::Serializer
include RoutingHelper
attributes :type, :href, :name
@@ -142,7 +147,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
end
end
- class Account::FieldSerializer < ActiveModel::Serializer
+ class Account::FieldSerializer < ActivityPub::Serializer
attributes :type, :name, :value
def type
diff --git a/app/serializers/activitypub/add_serializer.rb b/app/serializers/activitypub/add_serializer.rb
index c0906e8d036..6f5aab17f95 100644
--- a/app/serializers/activitypub/add_serializer.rb
+++ b/app/serializers/activitypub/add_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::AddSerializer < ActiveModel::Serializer
+class ActivityPub::AddSerializer < ActivityPub::Serializer
include RoutingHelper
attributes :type, :actor, :target
diff --git a/app/serializers/activitypub/block_serializer.rb b/app/serializers/activitypub/block_serializer.rb
index 624ce2fce81..e6c69329d8c 100644
--- a/app/serializers/activitypub/block_serializer.rb
+++ b/app/serializers/activitypub/block_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::BlockSerializer < ActiveModel::Serializer
+class ActivityPub::BlockSerializer < ActivityPub::Serializer
attributes :id, :type, :actor
attribute :virtual_object, key: :object
diff --git a/app/serializers/activitypub/collection_serializer.rb b/app/serializers/activitypub/collection_serializer.rb
index b03609957d1..da1ba735fc2 100644
--- a/app/serializers/activitypub/collection_serializer.rb
+++ b/app/serializers/activitypub/collection_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::CollectionSerializer < ActiveModel::Serializer
+class ActivityPub::CollectionSerializer < ActivityPub::Serializer
def self.serializer_for(model, options)
return ActivityPub::NoteSerializer if model.class.name == 'Status'
return ActivityPub::CollectionSerializer if model.class.name == 'ActivityPub::CollectionPresenter'
diff --git a/app/serializers/activitypub/delete_actor_serializer.rb b/app/serializers/activitypub/delete_actor_serializer.rb
index ddf59be9709..a6c5e2385eb 100644
--- a/app/serializers/activitypub/delete_actor_serializer.rb
+++ b/app/serializers/activitypub/delete_actor_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::DeleteActorSerializer < ActiveModel::Serializer
+class ActivityPub::DeleteActorSerializer < ActivityPub::Serializer
attributes :id, :type, :actor, :to
attribute :virtual_object, key: :object
diff --git a/app/serializers/activitypub/delete_serializer.rb b/app/serializers/activitypub/delete_serializer.rb
index 5012a8383ff..a7d5bd46985 100644
--- a/app/serializers/activitypub/delete_serializer.rb
+++ b/app/serializers/activitypub/delete_serializer.rb
@@ -1,7 +1,9 @@
# frozen_string_literal: true
-class ActivityPub::DeleteSerializer < ActiveModel::Serializer
- class TombstoneSerializer < ActiveModel::Serializer
+class ActivityPub::DeleteSerializer < ActivityPub::Serializer
+ class TombstoneSerializer < ActivityPub::Serializer
+ context_extensions :atom_uri
+
attributes :id, :type, :atom_uri
def id
diff --git a/app/serializers/activitypub/emoji_serializer.rb b/app/serializers/activitypub/emoji_serializer.rb
index 7b06b1e5db2..4dc38f3ea6e 100644
--- a/app/serializers/activitypub/emoji_serializer.rb
+++ b/app/serializers/activitypub/emoji_serializer.rb
@@ -1,8 +1,10 @@
# frozen_string_literal: true
-class ActivityPub::EmojiSerializer < ActiveModel::Serializer
+class ActivityPub::EmojiSerializer < ActivityPub::Serializer
include RoutingHelper
+ context_extensions :emoji
+
attributes :id, :type, :name, :updated
has_one :icon, serializer: ActivityPub::ImageSerializer
diff --git a/app/serializers/activitypub/flag_serializer.rb b/app/serializers/activitypub/flag_serializer.rb
index 1e7a46dd9ed..2f2a707d362 100644
--- a/app/serializers/activitypub/flag_serializer.rb
+++ b/app/serializers/activitypub/flag_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::FlagSerializer < ActiveModel::Serializer
+class ActivityPub::FlagSerializer < ActivityPub::Serializer
attributes :id, :type, :actor, :content
attribute :virtual_object, key: :object
diff --git a/app/serializers/activitypub/follow_serializer.rb b/app/serializers/activitypub/follow_serializer.rb
index bb204ee8f36..9228d7716e3 100644
--- a/app/serializers/activitypub/follow_serializer.rb
+++ b/app/serializers/activitypub/follow_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::FollowSerializer < ActiveModel::Serializer
+class ActivityPub::FollowSerializer < ActivityPub::Serializer
attributes :id, :type, :actor
attribute :virtual_object, key: :object
diff --git a/app/serializers/activitypub/image_serializer.rb b/app/serializers/activitypub/image_serializer.rb
index 3c08f77e831..1060f969149 100644
--- a/app/serializers/activitypub/image_serializer.rb
+++ b/app/serializers/activitypub/image_serializer.rb
@@ -1,8 +1,10 @@
# frozen_string_literal: true
-class ActivityPub::ImageSerializer < ActiveModel::Serializer
+class ActivityPub::ImageSerializer < ActivityPub::Serializer
include RoutingHelper
+ context_extensions :focal_point
+
attributes :type, :media_type, :url
attribute :focal_point, if: :focal_point?
diff --git a/app/serializers/activitypub/like_serializer.rb b/app/serializers/activitypub/like_serializer.rb
index c1a7ff6f637..0f170ddb4e8 100644
--- a/app/serializers/activitypub/like_serializer.rb
+++ b/app/serializers/activitypub/like_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::LikeSerializer < ActiveModel::Serializer
+class ActivityPub::LikeSerializer < ActivityPub::Serializer
attributes :id, :type, :actor
attribute :virtual_object, key: :object
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index 553f333d8ff..0666bea5a78 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -1,6 +1,9 @@
# frozen_string_literal: true
-class ActivityPub::NoteSerializer < ActiveModel::Serializer
+class ActivityPub::NoteSerializer < ActivityPub::Serializer
+ context_extensions :atom_uri, :conversation, :sensitive,
+ :hashtag, :emoji, :focal_point
+
attributes :id, :type, :summary,
:in_reply_to, :published, :url,
:attributed_to, :to, :cc, :sensitive,
@@ -147,7 +150,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
object.poll&.expired?
end
- class MediaAttachmentSerializer < ActiveModel::Serializer
+ class MediaAttachmentSerializer < ActivityPub::Serializer
include RoutingHelper
attributes :type, :media_type, :url, :name
@@ -178,7 +181,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
end
end
- class MentionSerializer < ActiveModel::Serializer
+ class MentionSerializer < ActivityPub::Serializer
attributes :type, :href, :name
def type
@@ -194,7 +197,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
end
end
- class TagSerializer < ActiveModel::Serializer
+ class TagSerializer < ActivityPub::Serializer
include RoutingHelper
attributes :type, :href, :name
@@ -215,8 +218,8 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
class CustomEmojiSerializer < ActivityPub::EmojiSerializer
end
- class OptionSerializer < ActiveModel::Serializer
- class RepliesSerializer < ActiveModel::Serializer
+ class OptionSerializer < ActivityPub::Serializer
+ class RepliesSerializer < ActivityPub::Serializer
attributes :type, :total_items
def type
diff --git a/app/serializers/activitypub/public_key_serializer.rb b/app/serializers/activitypub/public_key_serializer.rb
index 38e9e93baaa..62ed49e81d2 100644
--- a/app/serializers/activitypub/public_key_serializer.rb
+++ b/app/serializers/activitypub/public_key_serializer.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
-class ActivityPub::PublicKeySerializer < ActiveModel::Serializer
+class ActivityPub::PublicKeySerializer < ActivityPub::Serializer
+ context :security
+
attributes :id, :owner, :public_key_pem
def id
diff --git a/app/serializers/activitypub/reject_follow_serializer.rb b/app/serializers/activitypub/reject_follow_serializer.rb
index 7814f4f5759..4996c9a3c35 100644
--- a/app/serializers/activitypub/reject_follow_serializer.rb
+++ b/app/serializers/activitypub/reject_follow_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::RejectFollowSerializer < ActiveModel::Serializer
+class ActivityPub::RejectFollowSerializer < ActivityPub::Serializer
attributes :id, :type, :actor
has_one :object, serializer: ActivityPub::FollowSerializer
diff --git a/app/serializers/activitypub/remove_serializer.rb b/app/serializers/activitypub/remove_serializer.rb
index c2a5ae1b3a8..7fefda59da3 100644
--- a/app/serializers/activitypub/remove_serializer.rb
+++ b/app/serializers/activitypub/remove_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::RemoveSerializer < ActiveModel::Serializer
+class ActivityPub::RemoveSerializer < ActivityPub::Serializer
include RoutingHelper
attributes :type, :actor, :target
diff --git a/app/serializers/activitypub/undo_announce_serializer.rb b/app/serializers/activitypub/undo_announce_serializer.rb
index 4fc042727ad..6758af6792a 100644
--- a/app/serializers/activitypub/undo_announce_serializer.rb
+++ b/app/serializers/activitypub/undo_announce_serializer.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-class ActivityPub::UndoAnnounceSerializer < ActiveModel::Serializer
+class ActivityPub::UndoAnnounceSerializer < ActivityPub::Serializer
attributes :id, :type, :actor, :to
has_one :object, serializer: ActivityPub::ActivitySerializer
diff --git a/app/serializers/activitypub/undo_block_serializer.rb b/app/serializers/activitypub/undo_block_serializer.rb
index 2f43d8402a3..b4f04937771 100644
--- a/