You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.5 KiB

  1. # frozen_string_literal: true
  2. class ActivityPub::ProcessCollectionService < BaseService
  3. include JsonLdHelper
  4. def call(body, account, **options)
  5. @account = account
  6. @json = Oj.load(body, mode: :strict)
  7. @options = options
  8. return if !supported_context? || (different_actor? && verify_account!.nil?) || suspended_actor? || @account.local?
  9. case @json['type']
  10. when 'Collection', 'CollectionPage'
  11. process_items @json['items']
  12. when 'OrderedCollection', 'OrderedCollectionPage'
  13. process_items @json['orderedItems']
  14. else
  15. process_items [@json]
  16. end
  17. rescue Oj::ParseError
  18. nil
  19. end
  20. private
  21. def different_actor?
  22. @json['actor'].present? && value_or_id(@json['actor']) != @account.uri
  23. end
  24. def suspended_actor?
  25. @account.suspended? && !activity_allowed_while_suspended?
  26. end
  27. def activity_allowed_while_suspended?
  28. %w(Delete Reject Undo Update).include?(@json['type'])
  29. end
  30. def process_items(items)
  31. items.reverse_each.filter_map { |item| process_item(item) }
  32. end
  33. def supported_context?
  34. super(@json)
  35. end
  36. def process_item(item)
  37. activity = ActivityPub::Activity.factory(item, @account, **@options)
  38. activity&.perform
  39. end
  40. def verify_account!
  41. @options[:relayed_through_account] = @account
  42. @account = ActivityPub::LinkedDataSignature.new(@json).verify_account!
  43. rescue JSON::LD::JsonLdError => e
  44. Rails.logger.debug "Could not verify LD-Signature for #{value_or_id(@json['actor'])}: #{e.message}"
  45. nil
  46. end
  47. end