From 5d8398c8b8b51ee7363e7d45acc560f489783e34 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 2 Jun 2020 19:24:53 +0200 Subject: Add E2EE API (#13820) --- app/serializers/activitypub/activity_serializer.rb | 54 +++++-------------- app/serializers/activitypub/actor_serializer.rb | 9 +++- .../activitypub/collection_serializer.rb | 13 +++-- app/serializers/activitypub/device_serializer.rb | 52 ++++++++++++++++++ .../activitypub/encrypted_message_serializer.rb | 61 ++++++++++++++++++++++ .../activitypub/one_time_key_serializer.rb | 35 +++++++++++++ app/serializers/activitypub/outbox_serializer.rb | 11 +++- .../activitypub/undo_announce_serializer.rb | 6 ++- 8 files changed, 191 insertions(+), 50 deletions(-) create mode 100644 app/serializers/activitypub/device_serializer.rb create mode 100644 app/serializers/activitypub/encrypted_message_serializer.rb create mode 100644 app/serializers/activitypub/one_time_key_serializer.rb (limited to 'app/serializers/activitypub') diff --git a/app/serializers/activitypub/activity_serializer.rb b/app/serializers/activitypub/activity_serializer.rb index d0edad786..5bdf53f03 100644 --- a/app/serializers/activitypub/activity_serializer.rb +++ b/app/serializers/activitypub/activity_serializer.rb @@ -1,52 +1,22 @@ # frozen_string_literal: true class ActivityPub::ActivitySerializer < ActivityPub::Serializer - attributes :id, :type, :actor, :published, :to, :cc - - has_one :proper, key: :object, serializer: ActivityPub::NoteSerializer, if: :serialize_object? - - attribute :proper_uri, key: :object, unless: :serialize_object? - attribute :atom_uri, if: :announce? - - def id - ActivityPub::TagManager.instance.activity_uri_for(object) + def self.serializer_for(model, options) + case model.class.name + when 'Status' + ActivityPub::NoteSerializer + when 'DeliverToDeviceService::EncryptedMessage' + ActivityPub::EncryptedMessageSerializer + else + super + end end - def type - announce? ? 'Announce' : 'Create' - end + attributes :id, :type, :actor, :published, :to, :cc - def actor - ActivityPub::TagManager.instance.uri_for(object.account) - end + has_one :virtual_object, key: :object def published - object.created_at.iso8601 - end - - def to - ActivityPub::TagManager.instance.to(object) - end - - def cc - ActivityPub::TagManager.instance.cc(object) - end - - def proper_uri - ActivityPub::TagManager.instance.uri_for(object.proper) - end - - def atom_uri - OStatus::TagManager.instance.uri_for(object) - end - - def announce? - object.reblog? - end - - def serialize_object? - return true unless announce? - # Serialize private self-boosts of local toots - object.account == object.proper.account && object.proper.private_visibility? && object.local? + object.published.iso8601 end end diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index aa64936a7..627d4446b 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -7,7 +7,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer context_extensions :manually_approves_followers, :featured, :also_known_as, :moved_to, :property_value, :identity_proof, - :discoverable + :discoverable, :olm attributes :id, :type, :following, :followers, :inbox, :outbox, :featured, @@ -20,6 +20,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer has_many :virtual_tags, key: :tag has_many :virtual_attachments, key: :attachment + attribute :devices, unless: :instance_actor? attribute :moved_to, if: :moved? attribute :also_known_as, if: :also_known_as? @@ -38,7 +39,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer has_one :icon, serializer: ActivityPub::ImageSerializer, if: :avatar_exists? has_one :image, serializer: ActivityPub::ImageSerializer, if: :header_exists? - delegate :moved?, to: :object + delegate :moved?, :instance_actor?, to: :object def id object.instance_actor? ? instance_actor_url : account_url(object) @@ -68,6 +69,10 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer object.instance_actor? ? instance_actor_inbox_url : account_inbox_url(object) end + def devices + account_collection_url(object, :devices) + end + def outbox account_outbox_url(object) end diff --git a/app/serializers/activitypub/collection_serializer.rb b/app/serializers/activitypub/collection_serializer.rb index da1ba735f..00c7b786a 100644 --- a/app/serializers/activitypub/collection_serializer.rb +++ b/app/serializers/activitypub/collection_serializer.rb @@ -2,9 +2,16 @@ 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' - super + case model.class.name + when 'Status' + ActivityPub::NoteSerializer + when 'Device' + ActivityPub::DeviceSerializer + when 'ActivityPub::CollectionPresenter' + ActivityPub::CollectionSerializer + else + super + end end attribute :id, if: -> { object.id.present? } diff --git a/app/serializers/activitypub/device_serializer.rb b/app/serializers/activitypub/device_serializer.rb new file mode 100644 index 000000000..5f0fdc8af --- /dev/null +++ b/app/serializers/activitypub/device_serializer.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class ActivityPub::DeviceSerializer < ActivityPub::Serializer + context_extensions :olm + + include RoutingHelper + + class FingerprintKeySerializer < ActivityPub::Serializer + attributes :type, :public_key_base64 + + def type + 'Ed25519Key' + end + + def public_key_base64 + object.fingerprint_key + end + end + + class IdentityKeySerializer < ActivityPub::Serializer + attributes :type, :public_key_base64 + + def type + 'Curve25519Key' + end + + def public_key_base64 + object.identity_key + end + end + + attributes :device_id, :type, :name, :claim + + has_one :fingerprint_key, serializer: FingerprintKeySerializer + has_one :identity_key, serializer: IdentityKeySerializer + + def type + 'Device' + end + + def claim + account_claim_url(object.account, id: object.device_id) + end + + def fingerprint_key + object + end + + def identity_key + object + end +end diff --git a/app/serializers/activitypub/encrypted_message_serializer.rb b/app/serializers/activitypub/encrypted_message_serializer.rb new file mode 100644 index 000000000..3c525d23e --- /dev/null +++ b/app/serializers/activitypub/encrypted_message_serializer.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +class ActivityPub::EncryptedMessageSerializer < ActivityPub::Serializer + context :security + + context_extensions :olm + + class DeviceSerializer < ActivityPub::Serializer + attributes :type, :device_id + + def type + 'Device' + end + + def device_id + object + end + end + + class DigestSerializer < ActivityPub::Serializer + attributes :type, :digest_algorithm, :digest_value + + def type + 'Digest' + end + + def digest_algorithm + 'http://www.w3.org/2000/09/xmldsig#hmac-sha256' + end + + def digest_value + object + end + end + + attributes :type, :message_type, :cipher_text, :message_franking + + has_one :attributed_to, serializer: DeviceSerializer + has_one :to, serializer: DeviceSerializer + has_one :digest, serializer: DigestSerializer + + def type + 'EncryptedMessage' + end + + def attributed_to + object.source_device.device_id + end + + def to + object.target_device_id + end + + def message_type + object.type + end + + def cipher_text + object.body + end +end diff --git a/app/serializers/activitypub/one_time_key_serializer.rb b/app/serializers/activitypub/one_time_key_serializer.rb new file mode 100644 index 000000000..5932eb5b5 --- /dev/null +++ b/app/serializers/activitypub/one_time_key_serializer.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class ActivityPub::OneTimeKeySerializer < ActivityPub::Serializer + context :security + + context_extensions :olm + + class SignatureSerializer < ActivityPub::Serializer + attributes :type, :signature_value + + def type + 'Ed25519Signature' + end + + def signature_value + object.signature + end + end + + attributes :key_id, :type, :public_key_base64 + + has_one :signature, serializer: SignatureSerializer + + def type + 'Curve25519Key' + end + + def public_key_base64 + object.key + end + + def signature + object + end +end diff --git a/app/serializers/activitypub/outbox_serializer.rb b/app/serializers/activitypub/outbox_serializer.rb index 48fbad0fd..4f4f950a5 100644 --- a/app/serializers/activitypub/outbox_serializer.rb +++ b/app/serializers/activitypub/outbox_serializer.rb @@ -2,7 +2,14 @@ class ActivityPub::OutboxSerializer < ActivityPub::CollectionSerializer def self.serializer_for(model, options) - return ActivityPub::ActivitySerializer if model.is_a?(Status) - super + if model.class.name == 'ActivityPub::ActivityPresenter' + ActivityPub::ActivitySerializer + else + super + end + end + + def items + object.items.map { |status| ActivityPub::ActivityPresenter.from_status(status) } end end diff --git a/app/serializers/activitypub/undo_announce_serializer.rb b/app/serializers/activitypub/undo_announce_serializer.rb index 6758af679..a925efc18 100644 --- a/app/serializers/activitypub/undo_announce_serializer.rb +++ b/app/serializers/activitypub/undo_announce_serializer.rb @@ -3,7 +3,7 @@ class ActivityPub::UndoAnnounceSerializer < ActivityPub::Serializer attributes :id, :type, :actor, :to - has_one :object, serializer: ActivityPub::ActivitySerializer + has_one :virtual_object, key: :object, serializer: ActivityPub::ActivitySerializer def id [ActivityPub::TagManager.instance.uri_for(object.account), '#announces/', object.id, '/undo'].join @@ -20,4 +20,8 @@ class ActivityPub::UndoAnnounceSerializer < ActivityPub::Serializer def to [ActivityPub::TagManager::COLLECTIONS[:public]] end + + def virtual_object + ActivityPub::ActivityPresenter.from_status(object) + end end -- cgit