1
0

remote_follow.rb 1.8 KB

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