From 11fe293e1b318a12b75f0c5d1bb208fdbb46417e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 27 Mar 2019 15:55:23 +0100 Subject: Remove unused ActivityPub `@context` values depending on response (#10378) Fix #8078 --- app/lib/activitypub/adapter.rb | 75 +++++++++++++++++++++++++-------------- app/lib/activitypub/serializer.rb | 30 ++++++++++++++++ 2 files changed, 78 insertions(+), 27 deletions(-) create mode 100644 app/lib/activitypub/serializer.rb (limited to 'app/lib') diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 99f4d9305..7e0b16c25 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 000000000..07bd8c494 --- /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 -- cgit