remote_follow.rb 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. # frozen_string_literal: true
  2. class RemoteFollow
  3. include ActiveModel::Validations
  4. include RoutingHelper
  5. attr_accessor :acct, :addressable_template
  6. validates :acct, presence: true, domain: { acct: true }
  7. def initialize(attrs = {})
  8. @acct = normalize_acct(attrs[:acct])
  9. end
  10. def valid?
  11. return false unless super
  12. fetch_template!
  13. errors.empty?
  14. end
  15. def subscribe_address_for(account)
  16. addressable_template.expand(uri: ActivityPub::TagManager.instance.uri_for(account)).to_s
  17. end
  18. def interact_address_for(status)
  19. addressable_template.expand(uri: ActivityPub::TagManager.instance.uri_for(status)).to_s
  20. end
  21. private
  22. def normalize_acct(value)
  23. return if value.blank?
  24. username, domain = value.strip.gsub(/\A@/, '').split('@')
  25. domain = begin
  26. if TagManager.instance.local_domain?(domain)
  27. nil
  28. else
  29. TagManager.instance.normalize_domain(domain)
  30. end
  31. end
  32. [username, domain].compact.join('@')
  33. rescue Addressable::URI::InvalidURIError
  34. value
  35. end
  36. def fetch_template!
  37. return missing_resource_error if acct.blank?
  38. _, domain = acct.split('@')
  39. if domain.nil?
  40. @addressable_template = Addressable::Template.new("#{authorize_interaction_url}?uri={uri}")
  41. elsif redirect_url_link.nil? || redirect_url_link.template.nil?
  42. missing_resource_error
  43. else
  44. @addressable_template = Addressable::Template.new(redirect_uri_template)
  45. end
  46. end
  47. def redirect_uri_template
  48. redirect_url_link.template
  49. end
  50. def redirect_url_link
  51. acct_resource&.link('http://ostatus.org/schema/1.0/subscribe')
  52. end
  53. def acct_resource
  54. @acct_resource ||= Goldfinger.finger("acct:#{acct}")
  55. rescue Goldfinger::Error, HTTP::ConnectionError
  56. nil
  57. end
  58. def missing_resource_error
  59. errors.add(:acct, I18n.t('remote_follow.missing_resource'))
  60. end
  61. end