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/lib/activitypub/activity/create.rb | 50 ++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'app/lib/activitypub/activity/create.rb') diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 572b8087e..3509a6c40 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -2,6 +2,45 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def perform + case @object['type'] + when 'EncryptedMessage' + create_encrypted_message + else + create_status + end + end + + private + + def create_encrypted_message + return reject_payload! if invalid_origin?(@object['id']) || @options[:delivered_to_account_id].blank? + + target_account = Account.find(@options[:delivered_to_account_id]) + target_device = target_account.devices.find_by(device_id: @object.dig('to', 'deviceId')) + + return if target_device.nil? + + target_device.encrypted_messages.create!( + from_account: @account, + from_device_id: @object.dig('attributedTo', 'deviceId'), + type: @object['messageType'], + body: @object['cipherText'], + digest: @object.dig('digest', 'digestValue'), + message_franking: message_franking.to_token + ) + end + + def message_franking + MessageFranking.new( + hmac: @object.dig('digest', 'digestValue'), + original_franking: @object['messageFranking'], + source_account_id: @account.id, + target_account_id: @options[:delivered_to_account_id], + timestamp: Time.now.utc + ) + end + + def create_status return reject_payload! if unsupported_object_type? || invalid_origin?(@object['id']) || Tombstone.exists?(uri: @object['id']) || !related_to_local_activity? RedisLock.acquire(lock_options) do |lock| @@ -23,8 +62,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity @status end - private - def audience_to @object['to'] || @json['to'] end @@ -262,6 +299,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def poll_vote! poll = replied_to_status.preloadable_poll already_voted = true + RedisLock.acquire(poll_lock_options) do |lock| if lock.acquired? already_voted = poll.votes.where(account: @account).exists? @@ -270,20 +308,24 @@ class ActivityPub::Activity::Create < ActivityPub::Activity raise Mastodon::RaceConditionError end end + increment_voters_count! unless already_voted ActivityPub::DistributePollUpdateWorker.perform_in(3.minutes, replied_to_status.id) unless replied_to_status.preloadable_poll.hide_totals? end def resolve_thread(status) return unless status.reply? && status.thread.nil? && Request.valid_url?(in_reply_to_uri) + ThreadResolveWorker.perform_async(status.id, in_reply_to_uri) end def fetch_replies(status) collection = @object['replies'] return if collection.nil? + replies = ActivityPub::FetchRepliesService.new.call(status, collection, false) return unless replies.nil? + uri = value_or_id(collection) ActivityPub::FetchRepliesWorker.perform_async(status.id, uri) unless uri.nil? end @@ -291,6 +333,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def conversation_from_uri(uri) return nil if uri.nil? return Conversation.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) if OStatus::TagManager.instance.local_id?(uri) + begin Conversation.find_or_create_by!(uri: uri) rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique @@ -404,6 +447,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def skip_download? return @skip_download if defined?(@skip_download) + @skip_download ||= DomainBlock.reject_media?(@account.domain) end @@ -436,11 +480,13 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def forward_for_reply return unless @json['signature'].present? && reply_to_local? + ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), replied_to_status.account_id, [@account.preferred_inbox_url]) end def increment_voters_count! poll = replied_to_status.preloadable_poll + unless poll.voters_count.nil? poll.voters_count = poll.voters_count + 1 poll.save -- cgit