Add E2EE API (#13820)
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user