闭社主体 forked from https://github.com/tootsuite/mastodon
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.

95 lines
2.1 KiB

  1. # frozen_string_literal: true
  2. class ResolveURLService < BaseService
  3. include JsonLdHelper
  4. include Authorization
  5. attr_reader :url
  6. def call(url, on_behalf_of: nil)
  7. @url = url
  8. @on_behalf_of = on_behalf_of
  9. return process_local_url if local_url?
  10. process_url unless fetched_atom_feed.nil?
  11. end
  12. private
  13. def process_url
  14. if equals_or_includes_any?(type, %w(Application Group Organization Person Service))
  15. FetchRemoteAccountService.new.call(atom_url, body, protocol)
  16. elsif equals_or_includes_any?(type, %w(Note Article Image Video Page))
  17. FetchRemoteStatusService.new.call(atom_url, body, protocol)
  18. end
  19. end
  20. def fetched_atom_feed
  21. @_fetched_atom_feed ||= FetchAtomService.new.call(url)
  22. end
  23. def atom_url
  24. fetched_atom_feed.first
  25. end
  26. def body
  27. fetched_atom_feed.second[:prefetched_body]
  28. end
  29. def protocol
  30. fetched_atom_feed.third
  31. end
  32. def type
  33. return json_data['type'] if protocol == :activitypub
  34. case xml_root
  35. when 'feed'
  36. 'Person'
  37. when 'entry'
  38. 'Note'
  39. end
  40. end
  41. def json_data
  42. @_json_data ||= body_to_json(body)
  43. end
  44. def xml_root
  45. xml_data.root.name
  46. end
  47. def xml_data
  48. @_xml_data ||= Nokogiri::XML(body, nil, 'utf-8')
  49. end
  50. def local_url?
  51. TagManager.instance.local_url?(@url)
  52. end
  53. def process_local_url
  54. recognized_params = Rails.application.routes.recognize_path(@url)
  55. return unless recognized_params[:action] == 'show'
  56. if recognized_params[:controller] == 'stream_entries'
  57. status = StreamEntry.find_by(id: recognized_params[:id])&.status
  58. check_local_status(status)
  59. elsif recognized_params[:controller] == 'statuses'
  60. status = Status.find_by(id: recognized_params[:id])
  61. check_local_status(status)
  62. elsif recognized_params[:controller] == 'accounts'
  63. Account.find_local(recognized_params[:username])
  64. end
  65. end
  66. def check_local_status(status)
  67. return if status.nil?
  68. authorize_with @on_behalf_of, status, :show?
  69. status
  70. rescue Mastodon::NotPermittedError
  71. # Do not disclose the existence of status the user is not authorized to see
  72. nil
  73. end
  74. end