Define missing JSON-LD properties (#4767)

Using _: property names is discouraged, as in the future,
canonicalization may throw an error when encountering that instead
of discarding it silently like it does now.

We are defining some ActivityStreams properties which we expect
to land in ActivityStreams eventually, to ensure that future versions
of Mastodon will remain compatible with this even once that happens.
Those would be `locked`, `sensitive` and `Hashtag`

We are defining a custom context inline for some properties which we
do not expect to land in any other context. `atomUri`, `inReplyToAtomUri`
and `conversation` are part of the custom defined OStatus context.
main
Eugen Rochko 2017-09-02 14:01:23 +02:00 committed by GitHub
parent 1b1e025b41
commit 1b5806b744
8 changed files with 41 additions and 17 deletions

View File

@ -26,7 +26,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
def find_existing_status def find_existing_status
status = status_from_uri(object_uri) status = status_from_uri(object_uri)
status ||= Status.find_by(uri: @object['_:atomUri']) if @object['_:atomUri'].present? status ||= Status.find_by(uri: @object['atomUri']) if @object['atomUri'].present?
status status
end end
@ -43,7 +43,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
sensitive: @object['sensitive'] || false, sensitive: @object['sensitive'] || false,
visibility: visibility_from_audience, visibility: visibility_from_audience,
thread: replied_to_status, thread: replied_to_status,
conversation: conversation_from_uri(@object['_:conversation']), conversation: conversation_from_uri(@object['conversation']),
} }
end end
@ -125,7 +125,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
@replied_to_status = nil @replied_to_status = nil
else else
@replied_to_status = status_from_uri(in_reply_to_uri) @replied_to_status = status_from_uri(in_reply_to_uri)
@replied_to_status ||= status_from_uri(@object['_:inReplyToAtomUri']) if @object['_:inReplyToAtomUri'].present? @replied_to_status ||= status_from_uri(@object['inReplyToAtomUri']) if @object['inReplyToAtomUri'].present?
@replied_to_status @replied_to_status
end end
end end

View File

@ -17,7 +17,7 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
def delete_note def delete_note
status = Status.find_by(uri: object_uri, account: @account) status = Status.find_by(uri: object_uri, account: @account)
status ||= Status.find_by(uri: @object['_:atomUri'], account: @account) if @object.is_a?(Hash) && @object['_:atomUri'].present? status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?
delete_later!(object_uri) delete_later!(object_uri)

View File

@ -1,6 +1,24 @@
# frozen_string_literal: true # frozen_string_literal: true
class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
CONTEXT = {
'@context': [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1',
{
'locked' => 'as:locked',
'sensitive' => 'as:sensitive',
'Hashtag' => 'as:Hashtag',
'ostatus' => 'http://ostatus.org#',
'atomUri' => 'ostatus:atomUri',
'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri',
'conversation' => 'ostatus:conversation',
},
],
}.freeze
def self.default_key_transform def self.default_key_transform
:camel_lower :camel_lower
end end
@ -11,7 +29,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
def serializable_hash(options = nil) def serializable_hash(options = nil)
options = serialization_options(options) options = serialization_options(options)
serialized_hash = { '@context': [ActivityPub::TagManager::CONTEXT, 'https://w3id.org/security/v1'] }.merge(ActiveModelSerializers::Adapter::Attributes.new(serializer, instance_options).serializable_hash(options)) serialized_hash = CONTEXT.merge(ActiveModelSerializers::Adapter::Attributes.new(serializer, instance_options).serializable_hash(options))
self.class.transform_key_casing!(serialized_hash, instance_options) self.class.transform_key_casing!(serialized_hash, instance_options)
end end
end end

View File

@ -6,12 +6,10 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer
attributes :id, :type, :following, :followers, attributes :id, :type, :following, :followers,
:inbox, :outbox, :shared_inbox, :inbox, :outbox, :shared_inbox,
:preferred_username, :name, :summary, :preferred_username, :name, :summary,
:url :url, :locked
has_one :public_key, serializer: ActivityPub::PublicKeySerializer has_one :public_key, serializer: ActivityPub::PublicKeySerializer
attribute :locked, key: '_:locked'
class ImageSerializer < ActiveModel::Serializer class ImageSerializer < ActiveModel::Serializer
include RoutingHelper include RoutingHelper

View File

@ -2,8 +2,7 @@
class ActivityPub::DeleteSerializer < ActiveModel::Serializer class ActivityPub::DeleteSerializer < ActiveModel::Serializer
class TombstoneSerializer < ActiveModel::Serializer class TombstoneSerializer < ActiveModel::Serializer
attributes :id, :type attributes :id, :type, :atom_uri
attribute :atom_uri, key: '_:atomUri'
def id def id
ActivityPub::TagManager.instance.uri_for(object) ActivityPub::TagManager.instance.uri_for(object)

View File

@ -3,14 +3,13 @@
class ActivityPub::NoteSerializer < ActiveModel::Serializer class ActivityPub::NoteSerializer < ActiveModel::Serializer
attributes :id, :type, :summary, :content, attributes :id, :type, :summary, :content,
:in_reply_to, :published, :url, :in_reply_to, :published, :url,
:attributed_to, :to, :cc, :sensitive :attributed_to, :to, :cc, :sensitive,
:atom_uri, :in_reply_to_atom_uri,
:conversation
has_many :media_attachments, key: :attachment has_many :media_attachments, key: :attachment
has_many :virtual_tags, key: :tag has_many :virtual_tags, key: :tag
attribute :atom_uri, key: '_:atomUri', if: :local?
attribute :in_reply_to_atom_uri, key: '_:inReplyToAtomUri'
def id def id
ActivityPub::TagManager.instance.uri_for(object) ActivityPub::TagManager.instance.uri_for(object)
end end
@ -62,6 +61,8 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
end end
def atom_uri def atom_uri
return unless object.local?
::TagManager.instance.uri_for(object) ::TagManager.instance.uri_for(object)
end end
@ -71,6 +72,14 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
::TagManager.instance.uri_for(object.thread) ::TagManager.instance.uri_for(object.thread)
end end
def conversation
if object.conversation.uri?
object.conversation.uri
else
TagManager.instance.unique_tag(object.conversation.created_at, object.conversation.id, 'Conversation')
end
end
def local? def local?
object.account.local? object.account.local?
end end

View File

@ -25,8 +25,8 @@ class ActivityPub::FetchRemoteStatusService < BaseService
def activity_json def activity_json
if %w(Note Article).include? @json['type'] if %w(Note Article).include? @json['type']
{ {
'type' => 'Create', 'type' => 'Create',
'actor' => first_of_value(@json['attributedTo']), 'actor' => first_of_value(@json['attributedTo']),
'object' => @json, 'object' => @json,
} }
else else

View File

@ -50,7 +50,7 @@ class ActivityPub::ProcessAccountService < BaseService
@account.avatar_remote_url = image_url('icon') @account.avatar_remote_url = image_url('icon')
@account.header_remote_url = image_url('image') @account.header_remote_url = image_url('image')
@account.public_key = public_key || '' @account.public_key = public_key || ''
@account.locked = @json['_:locked'] || false @account.locked = @json['locked'] || false
@account.save! @account.save!
end end